mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-07 10:12:38 +00:00
Compare commits
3 Commits
devin/1778
...
lorenze/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e77d1c0d6e | ||
|
|
c8716e7062 | ||
|
|
e48cf3604e |
@@ -187,6 +187,8 @@ HEADERS_TO_FILTER = {
|
||||
"anthropic-ratelimit-tokens-remaining": "ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX",
|
||||
"anthropic-ratelimit-tokens-reset": "ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX",
|
||||
"x-amz-date": "X-AMZ-DATE-XXX",
|
||||
"x-amz-security-token": "X-AMZ-SECURITY-TOKEN-XXX",
|
||||
"x-crewai-organization-id": "X-CREWAI-ORGANIZATION-ID-XXX",
|
||||
"amz-sdk-invocation-id": "AMZ-SDK-INVOCATION-ID-XXX",
|
||||
"accept-encoding": "ACCEPT-ENCODING-XXX",
|
||||
"x-amzn-requestid": "X-AMZN-REQUESTID-XXX",
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from pydantic import BaseModel, Field, PrivateAttr
|
||||
from pydantic import BaseModel as PydanticBaseModel, Field, PrivateAttr
|
||||
|
||||
from crewai.agents.parser import AgentFinish
|
||||
from crewai.memory.utils import sanitize_scope_name
|
||||
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
|
||||
from crewai.task import Task
|
||||
|
||||
|
||||
class BaseAgentExecutor(BaseModel):
|
||||
class BaseAgentExecutor(PydanticBaseModel):
|
||||
model_config = {"arbitrary_types_allowed": True}
|
||||
|
||||
executor_type: str = "base"
|
||||
@@ -28,6 +28,26 @@ class BaseAgentExecutor(BaseModel):
|
||||
messages: list[LLMMessage] = Field(default_factory=list)
|
||||
_resuming: bool = PrivateAttr(default=False)
|
||||
|
||||
def _loop_response_model(self) -> type[PydanticBaseModel] | None:
|
||||
"""Return the response_model to forward to the LLM during a tool loop.
|
||||
|
||||
When the executor has tools, returns ``None``. Sending a strict
|
||||
structured-output schema alongside ``tools=`` makes many providers
|
||||
(notably OpenAI's Responses API with ``text.format`` json_schema)
|
||||
constrain the first response to the schema, so the model emits
|
||||
placeholder JSON instead of calling tools. Schema conversion is
|
||||
applied as post-processing in ``Task._export_output()`` (Crew path)
|
||||
or via ``Converter`` in ``Agent._build_output_from_result()``
|
||||
(standalone kickoff path).
|
||||
|
||||
Subclasses must define ``original_tools`` and ``response_model``
|
||||
attributes; this base implementation reads them via ``getattr`` so
|
||||
the helper works for any executor that exposes those names.
|
||||
"""
|
||||
if getattr(self, "original_tools", None):
|
||||
return None
|
||||
return getattr(self, "response_model", None)
|
||||
|
||||
def _save_to_memory(self, output: AgentFinish) -> None:
|
||||
"""Save task result to unified memory (memory or crew._memory)."""
|
||||
if self.agent is None:
|
||||
|
||||
@@ -334,6 +334,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
loop_response_model = self._loop_response_model()
|
||||
answer = get_llm_response(
|
||||
llm=cast("BaseLLM", self.llm),
|
||||
messages=self.messages,
|
||||
@@ -341,11 +342,11 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=loop_response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
if self.response_model is not None:
|
||||
if loop_response_model is not None:
|
||||
try:
|
||||
if isinstance(answer, BaseModel):
|
||||
output_json = answer.model_dump_json()
|
||||
@@ -355,7 +356,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
text=output_json,
|
||||
)
|
||||
else:
|
||||
self.response_model.model_validate_json(answer)
|
||||
loop_response_model.model_validate_json(answer)
|
||||
formatted_answer = AgentFinish(
|
||||
thought="",
|
||||
output=answer,
|
||||
@@ -486,7 +487,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=self._loop_response_model(),
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
@@ -1142,6 +1143,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
loop_response_model = self._loop_response_model()
|
||||
answer = await aget_llm_response(
|
||||
llm=cast("BaseLLM", self.llm),
|
||||
messages=self.messages,
|
||||
@@ -1149,12 +1151,12 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=loop_response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
if self.response_model is not None:
|
||||
if loop_response_model is not None:
|
||||
try:
|
||||
if isinstance(answer, BaseModel):
|
||||
output_json = answer.model_dump_json()
|
||||
@@ -1164,7 +1166,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
text=output_json,
|
||||
)
|
||||
else:
|
||||
self.response_model.model_validate_json(answer)
|
||||
loop_response_model.model_validate_json(answer)
|
||||
formatted_answer = AgentFinish(
|
||||
thought="",
|
||||
output=answer,
|
||||
@@ -1295,7 +1297,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=self._loop_response_model(),
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
@@ -1229,7 +1229,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor): # type: ignor
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=self._loop_response_model(),
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
@@ -1317,7 +1317,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor): # type: ignor
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=self._loop_response_model(),
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
@@ -2044,3 +2044,103 @@ class TestVisionImageFormatContract:
|
||||
assert hasattr(AnthropicCompletion, "_convert_image_blocks"), (
|
||||
"Anthropic provider must have _convert_image_blocks for auto-conversion"
|
||||
)
|
||||
|
||||
|
||||
class TestLoopResponseModelGuard:
|
||||
"""Regression: response_model must not be sent to the LLM during a tool loop.
|
||||
|
||||
Bug: when output_pydantic + tools are both set, OpenAI's Responses API
|
||||
(and several other providers) constrain the first response to the
|
||||
structured-output schema, so the model emits placeholder JSON instead of
|
||||
calling tools. Schema conversion is post-processed, so the LLM call must
|
||||
omit response_model whenever tools are present.
|
||||
"""
|
||||
|
||||
def _make_pydantic_model(self):
|
||||
from pydantic import BaseModel as _BaseModel
|
||||
|
||||
class _Out(_BaseModel):
|
||||
answer: str
|
||||
|
||||
return _Out
|
||||
|
||||
def _crew_executor(self, *, with_tools: bool, response_model):
|
||||
from crewai.agents.crew_agent_executor import CrewAgentExecutor
|
||||
|
||||
tool = Mock()
|
||||
tool.name = "search"
|
||||
tool.description = "search"
|
||||
|
||||
executor = CrewAgentExecutor.model_construct(
|
||||
response_model=response_model,
|
||||
original_tools=[tool] if with_tools else [],
|
||||
)
|
||||
return executor
|
||||
|
||||
def test_crew_helper_strips_when_tools_present(self):
|
||||
Model = self._make_pydantic_model()
|
||||
ex = self._crew_executor(with_tools=True, response_model=Model)
|
||||
assert ex._loop_response_model() is None
|
||||
|
||||
def test_crew_helper_preserves_when_no_tools(self):
|
||||
Model = self._make_pydantic_model()
|
||||
ex = self._crew_executor(with_tools=False, response_model=Model)
|
||||
assert ex._loop_response_model() is Model
|
||||
|
||||
def test_crew_helper_returns_none_when_no_response_model(self):
|
||||
ex = self._crew_executor(with_tools=False, response_model=None)
|
||||
assert ex._loop_response_model() is None
|
||||
|
||||
def test_experimental_helper_strips_when_tools_present(self):
|
||||
Model = self._make_pydantic_model()
|
||||
llm = Mock()
|
||||
llm.supports_stop_words.return_value = False
|
||||
tool = Mock()
|
||||
tool.name = "search"
|
||||
ex = _build_executor(llm=llm, response_model=Model, original_tools=[tool])
|
||||
assert ex._loop_response_model() is None
|
||||
|
||||
def test_experimental_helper_preserves_when_no_tools(self):
|
||||
Model = self._make_pydantic_model()
|
||||
llm = Mock()
|
||||
llm.supports_stop_words.return_value = False
|
||||
ex = _build_executor(llm=llm, response_model=Model, original_tools=[])
|
||||
assert ex._loop_response_model() is Model
|
||||
|
||||
def test_loop_call_sites_route_through_helper(self):
|
||||
"""Source-level guard: every in-loop LLM call must use the helper.
|
||||
|
||||
This catches regressions where someone reintroduces
|
||||
`response_model=self.response_model` inside a tool loop.
|
||||
"""
|
||||
import inspect
|
||||
from crewai.agents import crew_agent_executor as _crew_mod
|
||||
from crewai.experimental import agent_executor as _exp_mod
|
||||
|
||||
for mod, names in (
|
||||
(
|
||||
_crew_mod,
|
||||
(
|
||||
"_invoke_loop_react",
|
||||
"_invoke_loop_native_tools",
|
||||
"_ainvoke_loop_react",
|
||||
"_ainvoke_loop_native_tools",
|
||||
),
|
||||
),
|
||||
(
|
||||
_exp_mod,
|
||||
("call_llm_and_parse", "call_llm_native_tools"),
|
||||
),
|
||||
):
|
||||
cls = (
|
||||
_crew_mod.CrewAgentExecutor
|
||||
if mod is _crew_mod
|
||||
else _exp_mod.AgentExecutor
|
||||
)
|
||||
for name in names:
|
||||
src = inspect.getsource(getattr(cls, name))
|
||||
assert "response_model=self.response_model" not in src, (
|
||||
f"{cls.__name__}.{name} forwards self.response_model directly. "
|
||||
"Use self._loop_response_model() instead — see "
|
||||
"TestLoopResponseModelGuard for the bug it prevents."
|
||||
)
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: '{"max_tokens":4096,"messages":[{"role":"user","content":"\nCurrent Task:
|
||||
Calculate 15 + 27 using your add_numbers tool. Report the result."}],"model":"claude-3-5-haiku-20241022","stop_sequences":["\nObservation:"],"stream":false,"system":"You
|
||||
Calculate 15 + 27 using your add_numbers tool. Report the result."}],"model":"claude-sonnet-4-6","stop_sequences":["\nObservation:"],"stream":false,"system":"You
|
||||
are Calculator. You are a calculator assistant that uses tools to compute results.\nYour
|
||||
personal goal is: Perform calculations using available tools","tool_choice":{"type":"tool","name":"structured_output"},"tools":[{"name":"structured_output","description":"Output
|
||||
the structured response","input_schema":{"type":"object","description":"Structured
|
||||
output for calculation results.","title":"CalculationResult","properties":{"operation":{"type":"string","description":"The
|
||||
mathematical operation performed","title":"Operation"},"result":{"type":"integer","description":"The
|
||||
result of the calculation","title":"Result"},"explanation":{"type":"string","description":"Brief
|
||||
explanation of the calculation","title":"Explanation"}},"additionalProperties":false,"required":["operation","result","explanation"]}}]}'
|
||||
personal goal is: Perform calculations using available tools","tools":[{"name":"add_numbers","description":"Add
|
||||
two numbers together and return the sum.","input_schema":{"properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"],"type":"object","additionalProperties":false},"strict":true}]}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -21,7 +17,7 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1050'
|
||||
- '638'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
@@ -37,7 +33,7 @@ interactions:
|
||||
x-stainless-os:
|
||||
- X-STAINLESS-OS-XXX
|
||||
x-stainless-package-version:
|
||||
- 0.73.0
|
||||
- 0.96.0
|
||||
x-stainless-retry-count:
|
||||
- '0'
|
||||
x-stainless-runtime:
|
||||
@@ -50,8 +46,8 @@ interactions:
|
||||
uri: https://api.anthropic.com/v1/messages
|
||||
response:
|
||||
body:
|
||||
string: '{"model":"claude-3-5-haiku-20241022","id":"msg_01MsoNSVoPuoMYGCcJLvfXS6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01TtAsqddWjE7C4GYmCKavdg","name":"structured_output","input":{"operation":"Addition","result":42,"explanation":"Added
|
||||
15 and 27 together"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":573,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":75,"service_tier":"standard","inference_geo":"not_available"}}'
|
||||
string: '{"model":"claude-sonnet-4-6","id":"msg_016CHZY3K6G73PFc4iAJVC5C","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll
|
||||
calculate 15 + 27 right away using the `add_numbers` tool!"},{"type":"tool_use","id":"toolu_011UPTzkFNsgYshddoTX2A8X","name":"add_numbers","input":{"a":15,"b":27},"caller":{"type":"direct"}}],"stop_reason":"tool_use","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":633,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":92,"service_tier":"standard","inference_geo":"global"}}'
|
||||
headers:
|
||||
CF-RAY:
|
||||
- CF-RAY-XXX
|
||||
@@ -62,7 +58,7 @@ interactions:
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 12 Feb 2026 22:11:20 GMT
|
||||
- Fri, 24 Apr 2026 20:48:28 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
@@ -84,11 +80,119 @@ interactions:
|
||||
anthropic-ratelimit-output-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-requests-limit:
|
||||
- '4000'
|
||||
- '20000'
|
||||
anthropic-ratelimit-requests-remaining:
|
||||
- '3999'
|
||||
- '19999'
|
||||
anthropic-ratelimit-requests-reset:
|
||||
- '2026-02-12T22:11:18Z'
|
||||
- '2026-04-24T20:48:25Z'
|
||||
anthropic-ratelimit-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX
|
||||
cf-cache-status:
|
||||
- DYNAMIC
|
||||
request-id:
|
||||
- REQUEST-ID-XXX
|
||||
set-cookie:
|
||||
- SET-COOKIE-XXX
|
||||
strict-transport-security:
|
||||
- STS-XXX
|
||||
x-envoy-upstream-service-time:
|
||||
- '2056'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"max_tokens":4096,"messages":[{"role":"user","content":"\nCurrent Task:
|
||||
Calculate 15 + 27 using your add_numbers tool. Report the result."},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_011UPTzkFNsgYshddoTX2A8X","name":"add_numbers","input":{"a":15,"b":27}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_011UPTzkFNsgYshddoTX2A8X","content":"42"}]}],"model":"claude-sonnet-4-6","stop_sequences":["\nObservation:"],"stream":false,"system":"You
|
||||
are Calculator. You are a calculator assistant that uses tools to compute results.\nYour
|
||||
personal goal is: Perform calculations using available tools","tools":[{"name":"add_numbers","description":"Add
|
||||
two numbers together and return the sum.","input_schema":{"properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"],"type":"object","additionalProperties":false},"strict":true}]}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
accept:
|
||||
- application/json
|
||||
accept-encoding:
|
||||
- ACCEPT-ENCODING-XXX
|
||||
anthropic-version:
|
||||
- '2023-06-01'
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '887'
|
||||
content-type:
|
||||
- application/json
|
||||
cookie:
|
||||
- COOKIE-XXX
|
||||
host:
|
||||
- api.anthropic.com
|
||||
x-api-key:
|
||||
- X-API-KEY-XXX
|
||||
x-stainless-arch:
|
||||
- X-STAINLESS-ARCH-XXX
|
||||
x-stainless-async:
|
||||
- 'false'
|
||||
x-stainless-lang:
|
||||
- python
|
||||
x-stainless-os:
|
||||
- X-STAINLESS-OS-XXX
|
||||
x-stainless-package-version:
|
||||
- 0.96.0
|
||||
x-stainless-retry-count:
|
||||
- '0'
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.13.3
|
||||
x-stainless-timeout:
|
||||
- NOT_GIVEN
|
||||
method: POST
|
||||
uri: https://api.anthropic.com/v1/messages
|
||||
response:
|
||||
body:
|
||||
string: "{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01V13FHBygrTHV6pnhocqvd9\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[{\"type\":\"text\",\"text\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F389\\n\\nUsing the `add_numbers` tool,
|
||||
I computed the sum of 15 and 27, and the result is **42**.\"}],\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":717,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":51,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}"
|
||||
headers:
|
||||
CF-RAY:
|
||||
- CF-RAY-XXX
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Security-Policy:
|
||||
- CSP-FILTERED
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 24 Apr 2026 20:48:32 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
X-Robots-Tag:
|
||||
- none
|
||||
anthropic-organization-id:
|
||||
- ANTHROPIC-ORGANIZATION-ID-XXX
|
||||
anthropic-ratelimit-input-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-input-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-input-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-output-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-output-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-output-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-requests-limit:
|
||||
- '20000'
|
||||
anthropic-ratelimit-requests-remaining:
|
||||
- '19999'
|
||||
anthropic-ratelimit-requests-reset:
|
||||
- '2026-04-24T20:48:28Z'
|
||||
anthropic-ratelimit-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-tokens-remaining:
|
||||
@@ -102,7 +206,139 @@ interactions:
|
||||
strict-transport-security:
|
||||
- STS-XXX
|
||||
x-envoy-upstream-service-time:
|
||||
- '1234'
|
||||
- '4700'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: "{\"max_tokens\":4096,\"messages\":[{\"role\":\"user\",\"content\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F389\\n\\nUsing the `add_numbers` tool, I
|
||||
computed the sum of 15 and 27, and the result is **42**.\"}],\"model\":\"claude-sonnet-4-6\",\"stop_sequences\":[\"\\nObservation:\"],\"stream\":false,\"system\":\"Format
|
||||
your final answer according to the following OpenAPI schema: {\\n \\\"type\\\":
|
||||
\\\"json_schema\\\",\\n \\\"json_schema\\\": {\\n \\\"name\\\": \\\"CalculationResult\\\",\\n
|
||||
\ \\\"strict\\\": true,\\n \\\"schema\\\": {\\n \\\"description\\\":
|
||||
\\\"Structured output for calculation results.\\\",\\n \\\"properties\\\":
|
||||
{\\n \\\"operation\\\": {\\n \\\"description\\\": \\\"The mathematical
|
||||
operation performed\\\",\\n \\\"title\\\": \\\"Operation\\\",\\n \\\"type\\\":
|
||||
\\\"string\\\"\\n },\\n \\\"result\\\": {\\n \\\"description\\\":
|
||||
\\\"The result of the calculation\\\",\\n \\\"title\\\": \\\"Result\\\",\\n
|
||||
\ \\\"type\\\": \\\"integer\\\"\\n },\\n \\\"explanation\\\":
|
||||
{\\n \\\"description\\\": \\\"Brief explanation of the calculation\\\",\\n
|
||||
\ \\\"title\\\": \\\"Explanation\\\",\\n \\\"type\\\": \\\"string\\\"\\n
|
||||
\ }\\n },\\n \\\"required\\\": [\\n \\\"operation\\\",\\n
|
||||
\ \\\"result\\\",\\n \\\"explanation\\\"\\n ],\\n \\\"title\\\":
|
||||
\\\"CalculationResult\\\",\\n \\\"type\\\": \\\"object\\\",\\n \\\"additionalProperties\\\":
|
||||
false\\n }\\n }\\n}\\n\\nIMPORTANT: Preserve the original content exactly
|
||||
as-is. Do NOT rewrite, paraphrase, or modify the meaning of the content. Only
|
||||
structure it to match the schema format.\\n\\nDo not include the OpenAPI schema
|
||||
in the final output. Ensure the final output does not include any code block
|
||||
markers like ```json or ```python.\",\"tool_choice\":{\"type\":\"tool\",\"name\":\"structured_output\"},\"tools\":[{\"name\":\"structured_output\",\"description\":\"Output
|
||||
the structured response\",\"input_schema\":{\"type\":\"object\",\"description\":\"Structured
|
||||
output for calculation results.\",\"title\":\"CalculationResult\",\"properties\":{\"operation\":{\"type\":\"string\",\"description\":\"The
|
||||
mathematical operation performed\",\"title\":\"Operation\"},\"result\":{\"type\":\"integer\",\"description\":\"The
|
||||
result of the calculation\",\"title\":\"Result\"},\"explanation\":{\"type\":\"string\",\"description\":\"Brief
|
||||
explanation of the calculation\",\"title\":\"Explanation\"}},\"additionalProperties\":false,\"required\":[\"operation\",\"result\",\"explanation\"]}}]}"
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
accept:
|
||||
- application/json
|
||||
accept-encoding:
|
||||
- ACCEPT-ENCODING-XXX
|
||||
anthropic-version:
|
||||
- '2023-06-01'
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2313'
|
||||
content-type:
|
||||
- application/json
|
||||
cookie:
|
||||
- COOKIE-XXX
|
||||
host:
|
||||
- api.anthropic.com
|
||||
x-api-key:
|
||||
- X-API-KEY-XXX
|
||||
x-stainless-arch:
|
||||
- X-STAINLESS-ARCH-XXX
|
||||
x-stainless-async:
|
||||
- 'false'
|
||||
x-stainless-lang:
|
||||
- python
|
||||
x-stainless-os:
|
||||
- X-STAINLESS-OS-XXX
|
||||
x-stainless-package-version:
|
||||
- 0.96.0
|
||||
x-stainless-retry-count:
|
||||
- '0'
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.13.3
|
||||
x-stainless-timeout:
|
||||
- NOT_GIVEN
|
||||
method: POST
|
||||
uri: https://api.anthropic.com/v1/messages
|
||||
response:
|
||||
body:
|
||||
string: "{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01Csx2k6XmGyjfWkdLrXzLyA\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_01DzJ3ZUUnvPPJgzioZnxjKM\",\"name\":\"structured_output\",\"input\":{\"operation\":\"add_numbers\",\"result\":42,\"explanation\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F389\\n\\nUsing the `add_numbers` tool,
|
||||
I computed the sum of 15 and 27, and the result is **42**.\"},\"caller\":{\"type\":\"direct\"}}],\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":1122,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":116,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}"
|
||||
headers:
|
||||
CF-RAY:
|
||||
- CF-RAY-XXX
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Security-Policy:
|
||||
- CSP-FILTERED
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 24 Apr 2026 20:48:34 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
X-Robots-Tag:
|
||||
- none
|
||||
anthropic-organization-id:
|
||||
- ANTHROPIC-ORGANIZATION-ID-XXX
|
||||
anthropic-ratelimit-input-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-input-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-input-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-output-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-output-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-output-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-requests-limit:
|
||||
- '20000'
|
||||
anthropic-ratelimit-requests-remaining:
|
||||
- '19999'
|
||||
anthropic-ratelimit-requests-reset:
|
||||
- '2026-04-24T20:48:32Z'
|
||||
anthropic-ratelimit-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX
|
||||
cf-cache-status:
|
||||
- DYNAMIC
|
||||
request-id:
|
||||
- REQUEST-ID-XXX
|
||||
server-timing:
|
||||
- x-originResponse;dur=1594
|
||||
strict-transport-security:
|
||||
- STS-XXX
|
||||
vary:
|
||||
- Accept-Encoding
|
||||
x-envoy-upstream-service-time:
|
||||
- '1588'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
|
||||
@@ -8,20 +8,10 @@ interactions:
|
||||
[{"toolSpec": {"name": "add_numbers", "description": "Add two numbers together
|
||||
and return the sum.", "inputSchema": {"json": {"properties": {"a": {"title":
|
||||
"A", "type": "integer"}, "b": {"title": "B", "type": "integer"}}, "required":
|
||||
["a", "b"], "type": "object", "additionalProperties": false}}}}, {"toolSpec":
|
||||
{"name": "structured_output", "description": "Use this tool to provide your
|
||||
final structured response. Call this tool when you have gathered all necessary
|
||||
information and are ready to provide the final answer in the required format.",
|
||||
"inputSchema": {"json": {"description": "Structured output for calculation results.",
|
||||
"properties": {"operation": {"description": "The mathematical operation performed",
|
||||
"title": "Operation", "type": "string"}, "result": {"description": "The result
|
||||
of the calculation", "title": "Result", "type": "integer"}, "explanation": {"description":
|
||||
"Brief explanation of the calculation", "title": "Explanation", "type": "string"}},
|
||||
"required": ["operation", "result", "explanation"], "title": "CalculationResult",
|
||||
"type": "object", "additionalProperties": false}}}}]}}'
|
||||
["a", "b"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '1509'
|
||||
- '702'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -36,21 +26,23 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1968},"output":{"message":{"content":[{"text":"Okay,
|
||||
let''s calculate 15 + 27 using the add_numbers tool:"},{"toolUse":{"input":{"a":15,"b":27},"name":"add_numbers","toolUseId":"tooluse_pSseOamVELzpL3kQG5VukN"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":488,"outputTokens":91,"serverToolUsage":{},"totalTokens":579}}'
|
||||
string: '{"metrics":{"latencyMs":1570},"output":{"message":{"content":[{"text":"I''ll
|
||||
calculate 15 + 27 right away using the `add_numbers` tool!"},{"toolUse":{"input":{"a":15,"b":27},"name":"add_numbers","toolUseId":"tooluse_lYs0ulbVGQaYseRBvZ7tdX","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":645,"outputTokens":92,"serverToolUsage":{},"totalTokens":737}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '366'
|
||||
- '500'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 12 Feb 2026 22:01:04 GMT
|
||||
- Fri, 24 Apr 2026 20:49:36 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
@@ -59,29 +51,19 @@ interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 + 27 using your add_numbers tool. Report the result."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "name":
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_lYs0ulbVGQaYseRBvZ7tdX", "name":
|
||||
"add_numbers", "input": {"a": 15, "b": 27}}}]}, {"role": "user", "content":
|
||||
[{"toolResult": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "content": [{"text":
|
||||
[{"toolResult": {"toolUseId": "tooluse_lYs0ulbVGQaYseRBvZ7tdX", "content": [{"text":
|
||||
"42"}]}}]}], "inferenceConfig": {"stopSequences": ["\nObservation:"]}, "system":
|
||||
[{"text": "You are Calculator. You are a calculator assistant that uses tools
|
||||
to compute results.\nYour personal goal is: Perform calculations using available
|
||||
tools"}], "toolConfig": {"tools": [{"toolSpec": {"name": "add_numbers", "description":
|
||||
"Add two numbers together and return the sum.", "inputSchema": {"json": {"properties":
|
||||
{"a": {"title": "A", "type": "integer"}, "b": {"title": "B", "type": "integer"}},
|
||||
"required": ["a", "b"], "type": "object", "additionalProperties": false}}}},
|
||||
{"toolSpec": {"name": "structured_output", "description": "Use this tool to
|
||||
provide your final structured response. Call this tool when you have gathered
|
||||
all necessary information and are ready to provide the final answer in the required
|
||||
format.", "inputSchema": {"json": {"description": "Structured output for calculation
|
||||
results.", "properties": {"operation": {"description": "The mathematical operation
|
||||
performed", "title": "Operation", "type": "string"}, "result": {"description":
|
||||
"The result of the calculation", "title": "Result", "type": "integer"}, "explanation":
|
||||
{"description": "Brief explanation of the calculation", "title": "Explanation",
|
||||
"type": "string"}}, "required": ["operation", "result", "explanation"], "title":
|
||||
"CalculationResult", "type": "object", "additionalProperties": false}}}}]}}'
|
||||
"required": ["a", "b"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '1784'
|
||||
- '977'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -96,41 +78,50 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":7598},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"Addition","result":42,"explanation":"I
|
||||
added 15 and 27 using the add_numbers tool."},"name":"structured_output","toolUseId":"tooluse_RT8uSPaM37Q8CVuo3rJLtI"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":571,"outputTokens":102,"serverToolUsage":{},"totalTokens":673}}'
|
||||
string: "{\"metrics\":{\"latencyMs\":1456},\"output\":{\"message\":{\"content\":[{\"text\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F9EE\\n\\nUsing the `add_numbers` tool,
|
||||
I computed the sum of 15 and 27, and the result is **42**.\"}],\"role\":\"assistant\"}},\"stopReason\":\"end_turn\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":729,\"outputTokens\":51,\"serverToolUsage\":{},\"totalTokens\":780}}"
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '387'
|
||||
- '443'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 12 Feb 2026 22:01:12 GMT
|
||||
- Fri, 24 Apr 2026 20:49:37 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 + 27 using your add_numbers tool. Report the result."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "name":
|
||||
"add_numbers", "input": {"a": 15, "b": 27}}}]}, {"role": "user", "content":
|
||||
[{"toolResult": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "content": [{"text":
|
||||
"42"}]}}]}, {"role": "assistant", "content": [{"text": "{\"operation\":\"Addition\",\"result\":42,\"explanation\":\"I
|
||||
added 15 and 27 using the add_numbers tool.\"}"}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Calculator. You are a calculator
|
||||
assistant that uses tools to compute results.\nYour personal goal is: Perform
|
||||
calculations using available tools"}], "toolConfig": {"tools": [{"toolSpec":
|
||||
{"name": "add_numbers", "description": "Add two numbers together and return
|
||||
the sum.", "inputSchema": {"json": {"properties": {"a": {"title": "A", "type":
|
||||
"integer"}, "b": {"title": "B", "type": "integer"}}, "required": ["a", "b"],
|
||||
"type": "object", "additionalProperties": false}}}}, {"toolSpec": {"name": "structured_output",
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "The result of **15
|
||||
+ 27 = 42**! \ud83e\uddee\n\nUsing the `add_numbers` tool, I computed the sum
|
||||
of 15 and 27, and the result is **42**."}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "Format your final answer according
|
||||
to the following OpenAPI schema: {\n \"type\": \"json_schema\",\n \"json_schema\":
|
||||
{\n \"name\": \"CalculationResult\",\n \"strict\": true,\n \"schema\":
|
||||
{\n \"description\": \"Structured output for calculation results.\",\n \"properties\":
|
||||
{\n \"operation\": {\n \"description\": \"The mathematical operation
|
||||
performed\",\n \"title\": \"Operation\",\n \"type\": \"string\"\n },\n \"result\":
|
||||
{\n \"description\": \"The result of the calculation\",\n \"title\":
|
||||
\"Result\",\n \"type\": \"integer\"\n },\n \"explanation\":
|
||||
{\n \"description\": \"Brief explanation of the calculation\",\n \"title\":
|
||||
\"Explanation\",\n \"type\": \"string\"\n }\n },\n \"required\":
|
||||
[\n \"operation\",\n \"result\",\n \"explanation\"\n ],\n \"title\":
|
||||
\"CalculationResult\",\n \"type\": \"object\",\n \"additionalProperties\":
|
||||
false\n }\n }\n}\n\nIMPORTANT: Preserve the original content exactly as-is.
|
||||
Do NOT rewrite, paraphrase, or modify the meaning of the content. Only structure
|
||||
it to match the schema format.\n\nDo not include the OpenAPI schema in the final
|
||||
output. Ensure the final output does not include any code block markers like
|
||||
```json or ```python."}], "toolConfig": {"tools": [{"toolSpec": {"name": "structured_output",
|
||||
"description": "Use this tool to provide your final structured response. Call
|
||||
this tool when you have gathered all necessary information and are ready to
|
||||
provide the final answer in the required format.", "inputSchema": {"json": {"description":
|
||||
@@ -140,10 +131,10 @@ interactions:
|
||||
"type": "integer"}, "explanation": {"description": "Brief explanation of the
|
||||
calculation", "title": "Explanation", "type": "string"}}, "required": ["operation",
|
||||
"result", "explanation"], "title": "CalculationResult", "type": "object", "additionalProperties":
|
||||
false}}}}]}}'
|
||||
false}}}}], "toolChoice": {"tool": {"name": "structured_output"}}}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '1942'
|
||||
- '2545'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -158,28 +149,27 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"message":"The model returned the following errors: Your API request
|
||||
included an `assistant` message in the final position, which would pre-fill
|
||||
the `assistant` response. When using tools, pre-filling the `assistant` response
|
||||
is not supported."}'
|
||||
string: "{\"metrics\":{\"latencyMs\":1729},\"output\":{\"message\":{\"content\":[{\"toolUse\":{\"input\":{\"operation\":\"add_numbers\",\"result\":42,\"explanation\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F9EE\\n\\nUsing the `add_numbers` tool,
|
||||
I computed the sum of 15 and 27, and the result is **42**.\"},\"name\":\"structured_output\",\"toolUseId\":\"tooluse_FavcTtQCbzFrqURMiduSla\",\"type\":\"tool_use\"}}],\"role\":\"assistant\"}},\"stopReason\":\"tool_use\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":1150,\"outputTokens\":116,\"serverToolUsage\":{},\"totalTokens\":1266}}"
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '246'
|
||||
- '603'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 12 Feb 2026 22:01:12 GMT
|
||||
x-amzn-ErrorType:
|
||||
- ValidationException:http://internal.amazon.com/coral/com.amazon.bedrock/
|
||||
- Fri, 24 Apr 2026 20:49:39 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 400
|
||||
message: Bad Request
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
|
||||
@@ -975,7 +975,7 @@ def test_anthropic_agent_kickoff_structured_output_with_tools():
|
||||
role="Calculator",
|
||||
goal="Perform calculations using available tools",
|
||||
backstory="You are a calculator assistant that uses tools to compute results.",
|
||||
llm=LLM(model="anthropic/claude-3-5-haiku-20241022"),
|
||||
llm=LLM(model="anthropic/claude-sonnet-4-6"),
|
||||
tools=[add_numbers],
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
@@ -952,7 +952,7 @@ def test_bedrock_agent_kickoff_structured_output_with_tools():
|
||||
role="Calculator",
|
||||
goal="Perform calculations using available tools",
|
||||
backstory="You are a calculator assistant that uses tools to compute results.",
|
||||
llm=LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"),
|
||||
llm=LLM(model="bedrock/us.anthropic.claude-sonnet-4-6"),
|
||||
tools=[add_numbers],
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user