mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-22 09:28:12 +00:00
Compare commits
5 Commits
main
...
codex/fix-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
584baaef55 | ||
|
|
8b2e7e6004 | ||
|
|
1700a38fd2 | ||
|
|
3349cfcb92 | ||
|
|
4b08a8308d |
@@ -28,6 +28,7 @@ from pydantic import (
|
||||
ConfigDict,
|
||||
Field,
|
||||
PrivateAttr,
|
||||
ValidationError,
|
||||
model_validator,
|
||||
)
|
||||
from pydantic.functional_serializers import PlainSerializer
|
||||
@@ -1691,24 +1692,32 @@ class Agent(BaseAgent):
|
||||
elif response_format:
|
||||
raw_output = str(output) if not isinstance(output, str) else output
|
||||
try:
|
||||
model_schema = generate_model_description(response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice("formatted_task_instructions").format(
|
||||
output_format=schema
|
||||
)
|
||||
formatted_result = response_format.model_validate_json(raw_output)
|
||||
except ValidationError:
|
||||
# Direct JSON validation failed; fall back to converter-based parsing below.
|
||||
formatted_result = None
|
||||
|
||||
converter = Converter(
|
||||
llm=cast(BaseLLM, self.llm),
|
||||
text=raw_output,
|
||||
model=response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
if formatted_result is None:
|
||||
try:
|
||||
model_schema = generate_model_description(response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice(
|
||||
"formatted_task_instructions"
|
||||
).format(output_format=schema)
|
||||
|
||||
conversion_result = converter.to_pydantic()
|
||||
if isinstance(conversion_result, BaseModel):
|
||||
formatted_result = conversion_result
|
||||
except ConverterError:
|
||||
pass
|
||||
converter = Converter(
|
||||
llm=cast(BaseLLM, self.llm),
|
||||
text=raw_output,
|
||||
model=response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
conversion_result = converter.to_pydantic()
|
||||
if isinstance(conversion_result, BaseModel):
|
||||
formatted_result = conversion_result
|
||||
except ConverterError:
|
||||
# Conversion failure is non-fatal; raw output is preserved below.
|
||||
pass
|
||||
else:
|
||||
raw_output = str(output) if not isinstance(output, str) else output
|
||||
|
||||
|
||||
@@ -350,6 +350,10 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
effective_response_model = (
|
||||
None if self.original_tools else self.response_model
|
||||
)
|
||||
|
||||
answer = get_llm_response(
|
||||
llm=cast("BaseLLM", self.llm),
|
||||
messages=self.messages,
|
||||
@@ -357,11 +361,11 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=effective_response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
if self.response_model is not None:
|
||||
if effective_response_model is not None:
|
||||
try:
|
||||
if isinstance(answer, BaseModel):
|
||||
output_json = answer.model_dump_json()
|
||||
@@ -502,7 +506,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=None,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
@@ -1161,6 +1165,10 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
effective_response_model = (
|
||||
None if self.original_tools else self.response_model
|
||||
)
|
||||
|
||||
answer = await aget_llm_response(
|
||||
llm=cast("BaseLLM", self.llm),
|
||||
messages=self.messages,
|
||||
@@ -1168,12 +1176,12 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=effective_response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
if self.response_model is not None:
|
||||
if effective_response_model is not None:
|
||||
try:
|
||||
if isinstance(answer, BaseModel):
|
||||
output_json = answer.model_dump_json()
|
||||
@@ -1314,7 +1322,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=None,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
@@ -1224,6 +1224,10 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
|
||||
try:
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
effective_response_model = (
|
||||
None if self.original_tools else self.response_model
|
||||
)
|
||||
|
||||
answer = get_llm_response(
|
||||
llm=self.llm,
|
||||
messages=list(self.state.messages),
|
||||
@@ -1231,7 +1235,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=effective_response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
@@ -1319,7 +1323,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=self.response_model,
|
||||
response_model=None,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
@@ -23,6 +23,7 @@ from pydantic import (
|
||||
BaseModel,
|
||||
Field,
|
||||
PrivateAttr,
|
||||
ValidationError,
|
||||
field_validator,
|
||||
model_validator,
|
||||
)
|
||||
@@ -639,29 +640,38 @@ class LiteAgent(FlowTrackable, BaseModel):
|
||||
formatted_result = agent_finish.output
|
||||
elif active_response_format:
|
||||
try:
|
||||
model_schema = generate_model_description(active_response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice("formatted_task_instructions").format(
|
||||
output_format=schema
|
||||
formatted_result = active_response_format.model_validate_json(
|
||||
str(agent_finish.output)
|
||||
)
|
||||
except ValidationError:
|
||||
# Direct JSON validation failed; fall back to converter-based parsing below.
|
||||
formatted_result = None
|
||||
|
||||
converter = Converter(
|
||||
llm=self.llm,
|
||||
text=agent_finish.output,
|
||||
model=active_response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
if formatted_result is None:
|
||||
try:
|
||||
model_schema = generate_model_description(active_response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice(
|
||||
"formatted_task_instructions"
|
||||
).format(output_format=schema)
|
||||
|
||||
result = converter.to_pydantic()
|
||||
if isinstance(result, BaseModel):
|
||||
formatted_result = result
|
||||
except ConverterError as e:
|
||||
if self.verbose:
|
||||
PRINTER.print(
|
||||
content=f"Failed to parse output into response format after retries: {e.message}",
|
||||
color="yellow",
|
||||
converter = Converter(
|
||||
llm=self.llm,
|
||||
text=agent_finish.output,
|
||||
model=active_response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
result = converter.to_pydantic()
|
||||
if isinstance(result, BaseModel):
|
||||
formatted_result = result
|
||||
except ConverterError as e:
|
||||
if self.verbose:
|
||||
PRINTER.print(
|
||||
content=f"Failed to parse output into response format after retries: {e.message}",
|
||||
color="yellow",
|
||||
)
|
||||
|
||||
# Calculate token usage metrics
|
||||
if isinstance(self.llm, BaseLLM):
|
||||
usage_metrics = self.llm.get_token_usage_summary()
|
||||
|
||||
@@ -12,6 +12,7 @@ from typing import Any
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from crewai.agents.tools_handler import ToolsHandler as _ToolsHandler
|
||||
from crewai.agents.step_executor import StepExecutor
|
||||
@@ -108,6 +109,9 @@ class TestAgentExecutorState:
|
||||
class TestAgentExecutor:
|
||||
"""Test AgentExecutor class."""
|
||||
|
||||
class StructuredResult(BaseModel):
|
||||
value: str
|
||||
|
||||
@pytest.fixture
|
||||
def mock_dependencies(self):
|
||||
"""Create mock dependencies for executor."""
|
||||
@@ -215,6 +219,49 @@ class TestAgentExecutor:
|
||||
|
||||
assert result == "check_iteration"
|
||||
|
||||
def test_call_llm_and_parse_does_not_pass_response_model_with_tools(
|
||||
self, mock_dependencies
|
||||
):
|
||||
"""Structured output should not be requested during ReAct tool loops."""
|
||||
executor = _build_executor(
|
||||
**mock_dependencies,
|
||||
original_tools=[Mock()],
|
||||
response_model=self.StructuredResult,
|
||||
callbacks=[],
|
||||
)
|
||||
executor.state.messages = [{"role": "user", "content": "Use a tool"}]
|
||||
|
||||
with patch(
|
||||
"crewai.experimental.agent_executor.get_llm_response",
|
||||
return_value="Thought: done\nFinal Answer: complete",
|
||||
) as get_llm_response_mock:
|
||||
result = executor.call_llm_and_parse()
|
||||
|
||||
assert result == "parsed"
|
||||
assert get_llm_response_mock.call_args.kwargs["response_model"] is None
|
||||
|
||||
def test_call_llm_native_tools_does_not_pass_response_model_with_tools(
|
||||
self, mock_dependencies
|
||||
):
|
||||
"""Structured output should not be requested during native tool calls."""
|
||||
executor = _build_executor(
|
||||
**mock_dependencies,
|
||||
original_tools=[Mock()],
|
||||
response_model=self.StructuredResult,
|
||||
callbacks=[],
|
||||
)
|
||||
executor._openai_tools = [{"type": "function", "function": {"name": "lookup"}}]
|
||||
executor.state.messages = [{"role": "user", "content": "Use a tool"}]
|
||||
|
||||
with patch(
|
||||
"crewai.experimental.agent_executor.get_llm_response",
|
||||
return_value="complete",
|
||||
) as get_llm_response_mock:
|
||||
result = executor.call_llm_native_tools()
|
||||
|
||||
assert result == "native_finished"
|
||||
assert get_llm_response_mock.call_args.kwargs["response_model"] is None
|
||||
|
||||
def test_finalize_success(self, mock_dependencies):
|
||||
"""Test finalize with valid AgentFinish."""
|
||||
with patch.object(AgentExecutor, "_show_logs") as mock_show_logs:
|
||||
|
||||
@@ -8,18 +8,8 @@ interactions:
|
||||
[{"description": "Add two numbers together and return the sum.", "name": "add_numbers",
|
||||
"parameters_json_schema": {"properties": {"a": {"title": "A", "type": "integer"},
|
||||
"b": {"title": "B", "type": "integer"}}, "required": ["a", "b"], "type": "object",
|
||||
"additionalProperties": false}}, {"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.",
|
||||
"name": "structured_output", "parameters_json_schema": {"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, "propertyOrdering": ["operation", "result", "explanation"]}}]}], "generationConfig":
|
||||
{"stopSequences": ["\nObservation:"]}}'
|
||||
"additionalProperties": false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"],
|
||||
"thinkingConfig": {"include_thoughts": true}}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -30,13 +20,13 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1592'
|
||||
- '784'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.3
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
@@ -44,27 +34,36 @@ interactions:
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"add_numbers\",\n
|
||||
\ \"args\": {\n \"a\": 15,\n \"b\":
|
||||
27\n }\n },\n \"thoughtSignature\": \"CqMFAb4+9vtoEAola3khZd5LD4cccGlQsdVI9cPJGQBURT0qF5Xqp8o1L7oGN4s5trQpk7NPhKe1CYDMXDJueC7zM/zGlcy2daSJAeuTd9pxAbtndEXCGjM/9Nt8QRpvaDV3Ff2bkKSn/JCOJdzsN5m6G5C6BMRGVt8bZyRHelwu7tjCNYiMEvFqVoQIWN6d+CWKkHnbSwOlSUTDXJEcWvUwP82Ou7s68l2k7XNbDWCY5Tt8LUdPgeqjfH15JoEgZUbPxbVKA0ykRln1svfpvQ4Vm3Hn7PL3voWZWGzP5uLnH6JF2M8H6TokSDYZETvlDo5bK1Cx9IzrdUgHkku6gNbct/e53CPEUgqSKbY1VhsLAXAHieT4PKqeMQ4B+7gyCLXHeL6TOGjqSVGBBOQLtF9yCbKbkXa5pPu3+DnPhoOeH7jEPb+bqIWv6rxERErbKhu0IlP+UNBRAAj+wXNDZxQvLnlrlXrLtWllO9wFshr1DzgDgNZSRsPQeVQq2L0bL+KRobCXAfjMpH/8bhxdTI3sgsCtU3+dKwV5Z8Fg6e5oRyBAss8AE2CmYtdnYpt+iss9IT8NlSpI2DcdmVErEFNsebVcSwnr+9YXoESh4O1i8er9lX59hKTBdYXdP2GJ63cq9cSOalzx/doKxA2FzP3QhdV+H11LiUQzsQCXHqv0D+D290z1QoPhpsHEd7b/1EoW7D/2rub4acV8tpUcG2oe/Mj1kzYQoiEwZkgM56JoUs++5+5tWBMW68e4y1AmkyhDTCDkiNIa4noE6AOdNsLjL/+EHvcNFRmayFXXiUShIcMT0WQ9xNriWQP/dbhd6F5K7BKSajdB1391OYeHVmSEzzXYxjnUWXd+jqORQcsiPNIVRQkZI7ZGl6+4exmZsfrKzbFy\"\n
|
||||
[\n {\n \"text\": \"Okay, here's my thought process on
|
||||
tackling this simple addition problem:\\n\\n**Calculating 15 + 27**\\n\\nRight,
|
||||
so I need to calculate 15 plus 27. It's a straightforward arithmetic operation,
|
||||
and I know I have a dedicated tool for that \u2013 the `add_numbers` function.
|
||||
No need to reinvent the wheel, I should use the appropriate tool in my toolbox.\\n\\nTo
|
||||
use the tool effectively, I need to provide the correct inputs. In this case,
|
||||
I'll set `a` equal to 15, and `b` equal to 27. That should be a piece of cake
|
||||
for the function. Now I just need to call it!\\n\",\n \"thought\":
|
||||
true\n },\n {\n \"functionCall\": {\n \"name\":
|
||||
\"add_numbers\",\n \"args\": {\n \"a\": 15,\n
|
||||
\ \"b\": 27\n }\n },\n \"thoughtSignature\":
|
||||
\"CqwBAQw51sfkbjIDS7wS47oc/Bej+AYsUu5Cs+BC2Ae5NMasRmWa/u5Ct426qkpkIpgzGSNjwwfitf1gK93Abse9EGj5m1swXmPU2XSkqhMYMEXZGH1mW2U2XH8zaXHRIAx2aI0O8VbJ3sL8h1lJgbVCkvLa2RyWwY6E8FRPhQOHtrOQEQtfAUtHdJz928j6UEgS818X/7hEwuWsQhIho0frtziX30UlI7yXOeBBWw==\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0,\n \"finishMessage\": \"Model generated
|
||||
function call(s).\"\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
202,\n \"candidatesTokenCount\": 22,\n \"totalTokenCount\": 403,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 202\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 179\n },\n \"modelVersion\":
|
||||
\"gemini-2.5-flash\",\n \"responseId\": \"AlCOadrrK7aVjMcPksrU-A0\"\n}\n"
|
||||
104,\n \"candidatesTokenCount\": 22,\n \"totalTokenCount\": 173,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 104\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 47,\n \"serviceTier\": \"standard\"\n
|
||||
\ },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"MpgPapmwO_vN-sAPvrWJmA0\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Thu, 12 Feb 2026 22:11:14 GMT
|
||||
- Thu, 21 May 2026 23:41:40 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=1417
|
||||
- gfet4t7; dur=1920
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -75,6 +74,8 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
@@ -83,7 +84,7 @@ interactions:
|
||||
- request:
|
||||
body: '{"contents": [{"parts": [{"text": "\nCurrent Task: Calculate 15 + 27 using
|
||||
your add_numbers tool. Report the result."}], "role": "user"}, {"parts": [{"functionCall":
|
||||
{"args": {"a": 15, "b": 27}, "name": "add_numbers"}, "thoughtSignature": "CqMFAb4-9vtoEAola3khZd5LD4cccGlQsdVI9cPJGQBURT0qF5Xqp8o1L7oGN4s5trQpk7NPhKe1CYDMXDJueC7zM_zGlcy2daSJAeuTd9pxAbtndEXCGjM_9Nt8QRpvaDV3Ff2bkKSn_JCOJdzsN5m6G5C6BMRGVt8bZyRHelwu7tjCNYiMEvFqVoQIWN6d-CWKkHnbSwOlSUTDXJEcWvUwP82Ou7s68l2k7XNbDWCY5Tt8LUdPgeqjfH15JoEgZUbPxbVKA0ykRln1svfpvQ4Vm3Hn7PL3voWZWGzP5uLnH6JF2M8H6TokSDYZETvlDo5bK1Cx9IzrdUgHkku6gNbct_e53CPEUgqSKbY1VhsLAXAHieT4PKqeMQ4B-7gyCLXHeL6TOGjqSVGBBOQLtF9yCbKbkXa5pPu3-DnPhoOeH7jEPb-bqIWv6rxERErbKhu0IlP-UNBRAAj-wXNDZxQvLnlrlXrLtWllO9wFshr1DzgDgNZSRsPQeVQq2L0bL-KRobCXAfjMpH_8bhxdTI3sgsCtU3-dKwV5Z8Fg6e5oRyBAss8AE2CmYtdnYpt-iss9IT8NlSpI2DcdmVErEFNsebVcSwnr-9YXoESh4O1i8er9lX59hKTBdYXdP2GJ63cq9cSOalzx_doKxA2FzP3QhdV-H11LiUQzsQCXHqv0D-D290z1QoPhpsHEd7b_1EoW7D_2rub4acV8tpUcG2oe_Mj1kzYQoiEwZkgM56JoUs--5-5tWBMW68e4y1AmkyhDTCDkiNIa4noE6AOdNsLjL_-EHvcNFRmayFXXiUShIcMT0WQ9xNriWQP_dbhd6F5K7BKSajdB1391OYeHVmSEzzXYxjnUWXd-jqORQcsiPNIVRQkZI7ZGl6-4exmZsfrKzbFy"}],
|
||||
{"args": {"a": 15, "b": 27}, "name": "add_numbers"}, "thoughtSignature": "CqwBAQw51sfkbjIDS7wS47oc_Bej-AYsUu5Cs-BC2Ae5NMasRmWa_u5Ct426qkpkIpgzGSNjwwfitf1gK93Abse9EGj5m1swXmPU2XSkqhMYMEXZGH1mW2U2XH8zaXHRIAx2aI0O8VbJ3sL8h1lJgbVCkvLa2RyWwY6E8FRPhQOHtrOQEQtfAUtHdJz928j6UEgS818X_7hEwuWsQhIho0frtziX30UlI7yXOeBBWw=="}],
|
||||
"role": "model"}, {"parts": [{"functionResponse": {"name": "add_numbers", "response":
|
||||
{"result": 42}}}], "role": "user"}], "systemInstruction": {"parts": [{"text":
|
||||
"You are Calculator. You are a calculator assistant that uses tools to compute
|
||||
@@ -92,18 +93,8 @@ interactions:
|
||||
numbers together and return the sum.", "name": "add_numbers", "parameters_json_schema":
|
||||
{"properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B",
|
||||
"type": "integer"}}, "required": ["a", "b"], "type": "object", "additionalProperties":
|
||||
false}}, {"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.", "name": "structured_output",
|
||||
"parameters_json_schema": {"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, "propertyOrdering":
|
||||
["operation", "result", "explanation"]}}]}], "generationConfig": {"stopSequences":
|
||||
["\nObservation:"]}}'
|
||||
false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"], "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -114,13 +105,13 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2725'
|
||||
- '1249'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.3
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
@@ -128,28 +119,24 @@ interactions:
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"structured_output\",\n
|
||||
\ \"args\": {\n \"result\": 42,\n \"explanation\":
|
||||
\"The sum of 15 and 27 is 42.\",\n \"operation\": \"Addition\"\n
|
||||
\ }\n },\n \"thoughtSignature\": \"CtYCAb4+9vsKJoVFV1W8ORKk+Likt7GS9CuzuE53V9sbS2gFuiEjJ7ghBqWDG2UrgyRYFjPl6EalXUBnEbEq9rZNYGY27VpcweI1tv6p+477bgz1pmZnL0nfAcrp4nuphL+Ij0nXZQoo5cF4Gk29RQSNy49VRn3eP9eUW0hG7EpkPmfJiUSSDuaQENHN1UBBnFS9QUC+Fw+unnQ10B57fauyiXWNrBUkE2PYqgj5vELa5lVMtk5beh4ydWNnZ04t8gvQniCJ38EWWQr8VAXrSqE156oCBMwkFaFM7huPWHZk53n/HAG/VsQgPayf045STWKWjBzp6uTiwH9pYtoI1LBah3uxVbJRKOzH7HI4U0cHsffQqIIUn8cW4SP1UK/nvAivU1l0p6Bot8KIVJ5vqoF+o2oDmTuZv0HkDo5+UvXRqfsO5AylpUdM+JMGaXVAA7oZNqVPQybw\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0,\n \"finishMessage\": \"Model generated
|
||||
function call(s).\"\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
240,\n \"candidatesTokenCount\": 39,\n \"totalTokenCount\": 357,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 240\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 78\n },\n \"modelVersion\":
|
||||
\"gemini-2.5-flash\",\n \"responseId\": \"A1COaaWbKvKGjMcPsN-EkAs\"\n}\n"
|
||||
[\n {\n \"text\": \"The sum of 15 and 27 is 42.\"\n }\n
|
||||
\ ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
142,\n \"candidatesTokenCount\": 15,\n \"totalTokenCount\": 157,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 142\n
|
||||
\ }\n ],\n \"serviceTier\": \"standard\"\n },\n \"modelVersion\":
|
||||
\"gemini-2.5-flash\",\n \"responseId\": \"NZgPasTKBf3F-sAP4Lu48Ak\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Thu, 12 Feb 2026 22:11:15 GMT
|
||||
- Thu, 21 May 2026 23:41:41 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=906
|
||||
- gfet4t7; dur=750
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -160,6 +147,107 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"contents": [{"parts": [{"text": "The sum of 15 and 27 is 42."}], "role":
|
||||
"user"}], "systemInstruction": {"parts": [{"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."}], "role": "user"}, "generationConfig": {"responseMimeType":
|
||||
"application/json", "responseJsonSchema": {"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, "propertyOrdering": ["operation", "result", "explanation"]}, "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
accept:
|
||||
- '*/*'
|
||||
accept-encoding:
|
||||
- ACCEPT-ENCODING-XXX
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2247'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"text\": \"**Analyzing the User's Statement**\\n\\nOkay,
|
||||
so the user has given me the statement: \\\"The sum of 15 and 27 is 42.\\\"
|
||||
My task is to break this down into a structured JSON object according to the
|
||||
`CalculationResult` schema I'm working with. This is straightforward; let's
|
||||
extract the key pieces:\\n\\nFirst, the **operation**: The word \\\"sum\\\"
|
||||
is a clear indicator that we're dealing with addition. No ambiguity there.\\n\\nNext,
|
||||
the **result**: The statement explicitly tells us that the result \\\"is 42\\\".
|
||||
That's a direct, easily extracted value.\\n\\nFinally, the **explanation**:
|
||||
I can use the entire original statement, \\\"The sum of 15 and 27 is 42.\\\",
|
||||
as the explanation. It's concise and perfectly encapsulates the context of
|
||||
the calculation.\\n\",\n \"thought\": true\n },\n {\n
|
||||
\ \"text\": \"{\\\"operation\\\":\\\"addition\\\",\\\"result\\\":42,\\\"explanation\\\":\\\"The
|
||||
sum of 15 and 27 is 42.\\\"}\"\n }\n ],\n \"role\":
|
||||
\"model\"\n },\n \"finishReason\": \"STOP\",\n \"index\": 0\n
|
||||
\ }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\": 321,\n \"candidatesTokenCount\":
|
||||
28,\n \"totalTokenCount\": 480,\n \"promptTokensDetails\": [\n {\n
|
||||
\ \"modality\": \"TEXT\",\n \"tokenCount\": 321\n }\n ],\n
|
||||
\ \"thoughtsTokenCount\": 131,\n \"serviceTier\": \"standard\"\n },\n
|
||||
\ \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"NZgPasDuKf2VjMcPwc6D4Ak\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Thu, 21 May 2026 23:41:44 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=2425
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
- Origin
|
||||
- X-Origin
|
||||
- Referer
|
||||
X-Content-Type-Options:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
|
||||
@@ -23,17 +23,8 @@ interactions:
|
||||
numbers together and return the sum.", "name": "add_numbers", "parameters_json_schema":
|
||||
{"properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B",
|
||||
"type": "integer"}}, "required": ["a", "b"], "type": "object", "additionalProperties":
|
||||
false}}, {"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.", "name": "structured_output",
|
||||
"parameters_json_schema": {"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, "propertyOrdering": ["operation", "result", "explanation"]}}]}], "generationConfig":
|
||||
{"stopSequences": ["\nObservation:"]}}'
|
||||
false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"], "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -44,41 +35,67 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2763'
|
||||
- '2016'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.12
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-001:generateContent
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"add_numbers\",\n
|
||||
[\n {\n \"text\": \"**My Calculation Process**\\n\\nAlright,
|
||||
the user wants me to compute 15 + 27. Simple enough. I have a tool specifically
|
||||
designed for this: `add_numbers(a: int, b: int)`. This is ideal; I'll utilize
|
||||
that.\\n\\nSo, first step: I need to call the `add_numbers` tool. The inputs
|
||||
are straightforward: `a` should be 15 and `b` should be 27. I'll execute that
|
||||
call immediately.\\n\\nOnce I have the result \u2013 the sum \u2013 in hand,
|
||||
I need to format the output. The user is specific about the structure; it
|
||||
needs to be a JSON object conforming to that OpenAPI schema. Specifically,
|
||||
the JSON should include: an \\\"operation\\\" field set to \\\"Addition\\\",
|
||||
a \\\"result\\\" field populated with the calculated sum, and an \\\"explanation\\\"
|
||||
field giving some context, which should be \\\"Added 15 and 27 together.\\\"\\n\\nTherefore,
|
||||
my workflow is: call the tool with the provided numbers, get the sum, and
|
||||
then construct the final JSON object in the required format.\\n\",\n \"thought\":
|
||||
true\n },\n {\n \"text\": \"**My Reasoning for
|
||||
Calculating 15 + 27**\\n\\nOkay, the user wants me to compute 15 plus 27.
|
||||
No problem; that's straightforward. I've got a dedicated `add_numbers` tool
|
||||
for this, which is exactly the right approach. Let's see...I need to call
|
||||
that tool, providing `a=15` and `b=27` as input parameters. Once I receive
|
||||
the sum, I can move on to formatting the result.\\n\\nNow, the important part:
|
||||
the output needs to be a JSON object, specifically structured as dictated
|
||||
by the OpenAPI schema. I need to make sure I include the \\\"operation\\\",
|
||||
\\\"result\\\", and \\\"explanation\\\" fields. \\\"operation\\\" will be
|
||||
\\\"Addition\\\", the \\\"result\\\" will naturally be the sum I get from
|
||||
the tool, and the \\\"explanation\\\" will simply be \\\"Added 15 and 27 together.\\\"
|
||||
That should cover everything, and the user should get a perfectly formatted
|
||||
response.\\n\",\n \"thought\": true\n },\n {\n
|
||||
\ \"functionCall\": {\n \"name\": \"add_numbers\",\n
|
||||
\ \"args\": {\n \"a\": 15,\n \"b\":
|
||||
27\n }\n }\n }\n ],\n \"role\":
|
||||
\"model\"\n },\n \"finishReason\": \"STOP\",\n \"avgLogprobs\":
|
||||
4.3579145442760951e-06\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
377,\n \"candidatesTokenCount\": 7,\n \"totalTokenCount\": 384,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 377\n
|
||||
\ }\n ],\n \"candidatesTokensDetails\": [\n {\n \"modality\":
|
||||
\"TEXT\",\n \"tokenCount\": 7\n }\n ]\n },\n \"modelVersion\":
|
||||
\"gemini-2.0-flash-001\",\n \"responseId\": \"vVefaYDSOouXjMcPicLCsQY\"\n}\n"
|
||||
27\n }\n },\n \"thoughtSignature\": \"CtkGAQw51sf8m1RivBZ7Zp+ZkaqxDdZzSlzepmvlCKak9gl6edIuej/pHxR5dg3qZf89XmHvQ6HigZyzqHcYbSvcRHVGbpNkTr62FC0g10oK5ZEp/r1otLIcgXoVgyFGguJPe/NsfWSX3Uc7ZaYgV0Q2MHBsjUmEHicPH0Pj4Xmbe2I1pK/9DPrzSQqZW3duhLBlBIF9RwZUiltPH6mK+k71l8bN/ebsbbZM18FMXf0wg/7lf3OjvY2wdLDNUD/F2M7T8yfi7NelPWorjIuTGOVWlVRsdGW0QEzuVoyYY7OfbBJC+XsmTumYt+vqgIR3jcQZlA5/3yJdj3e/3mrNmzGt+8VvkjUnu3pz0IUkq2SoTG0+6Y/ajsUI0YA/BFiAXHjrRhH1Nx3ihGWT7E7VzpU/E1ZPFMJIOPLRSpRv8G6ITnjZGthozTZtKLgoHCF7kx4Ni8eVdOh2Us6kY7tYpVabM1dmw0gextEEt+fBMoI+qZGkXdL1YW6SEtQBHh3BGKX8khcrqNvqPZDFzSG0iieMJq7abbEYAIc8zRkeGlWEdX6ES6e+njnFN7JX0Nc32GzOjmpgx9gRhYe+wKonqBQ9RwLLNK+lFuflLTrU3D8jMiPCJyvoRsjdjEc+2JtHXo14ibOVXvZ6oYCHsTEB7f+90/qzcrITESyDBD/rmiT/SqgitBa44MZE9CZ9Ml+BW0xd9FfCy4oLy8w4vszVFDw9Eotr4pEzdCeDeWjMn35taJnWf6jUeF0z/0iyHjbi7XRubJXxI2YuKQ+HRCKX1RFaJWLhmxO4JNBDBqfYZqsO/FefqxjWi2pRzE8U/Upp8Tv/hy1FoN9Abs8W6lPoqgOyEiOcpVkM+u0CgUbf87I1X2EiPpuJF4D9dHlEJqumiPqIGazSLnrjW1qqbM5UpQQuPoTC7q+G092CEnNJBIwrufddZPDfD9rqINpmMa+7OswldKViVaCWR3VsgrSXJj7lVRntCyE2atWxTvtQVnR/JLDdyc98CAUChtAPnC4K/K3OVI4jffQQsHmfeOnTyg0n2VnZ6Yhgo0lMdE4IfMrNOWOuNvHodeHisD2yXjvTCgScO8B3s+EJTvenHMert3nRgjNRmFZ0cRNSjbTeG0UlB9s7Uy0uyrn5ODkKIgEMOdbH9yJU53jInG9boFeMXb1qif47Pc72taZkl6ZaMK4=\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0,\n \"finishMessage\": \"Model generated
|
||||
function call(s).\"\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
383,\n \"candidatesTokenCount\": 22,\n \"totalTokenCount\": 658,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 383\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 253,\n \"serviceTier\": \"standard\"\n
|
||||
\ },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"qagPas37Ba2R-8YPzYzI8AY\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Wed, 25 Feb 2026 20:12:46 GMT
|
||||
- Fri, 22 May 2026 00:51:56 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=718
|
||||
- gfet4t7; dur=3892
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -89,6 +106,8 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
@@ -112,27 +131,17 @@ interactions:
|
||||
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."}], "role": "user"}, {"parts": [{"functionCall": {"args": {"a":
|
||||
15, "b": 27}, "name": "add_numbers"}}], "role": "model"}, {"parts": [{"functionResponse":
|
||||
{"name": "add_numbers", "response": {"result": 42}}}], "role": "user"}, {"parts":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}],
|
||||
"role": "user"}], "systemInstruction": {"parts": [{"text": "You are Calculator.
|
||||
You are a calculator assistant that uses tools to compute results.\nYour personal
|
||||
goal is: Perform calculations using available tools"}], "role": "user"}, "tools":
|
||||
[{"functionDeclarations": [{"description": "Add two numbers together and return
|
||||
the sum.", "name": "add_numbers", "parameters_json_schema": {"properties": {"a":
|
||||
{"title": "A", "type": "integer"}, "b": {"title": "B", "type": "integer"}},
|
||||
"required": ["a", "b"], "type": "object", "additionalProperties": false}}, {"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.", "name": "structured_output", "parameters_json_schema":
|
||||
{"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, "propertyOrdering": ["operation",
|
||||
"result", "explanation"]}}]}], "generationConfig": {"stopSequences": ["\nObservation:"]}}'
|
||||
15, "b": 27}, "name": "add_numbers"}, "thoughtSignature": "CtkGAQw51sf8m1RivBZ7Zp-ZkaqxDdZzSlzepmvlCKak9gl6edIuej_pHxR5dg3qZf89XmHvQ6HigZyzqHcYbSvcRHVGbpNkTr62FC0g10oK5ZEp_r1otLIcgXoVgyFGguJPe_NsfWSX3Uc7ZaYgV0Q2MHBsjUmEHicPH0Pj4Xmbe2I1pK_9DPrzSQqZW3duhLBlBIF9RwZUiltPH6mK-k71l8bN_ebsbbZM18FMXf0wg_7lf3OjvY2wdLDNUD_F2M7T8yfi7NelPWorjIuTGOVWlVRsdGW0QEzuVoyYY7OfbBJC-XsmTumYt-vqgIR3jcQZlA5_3yJdj3e_3mrNmzGt-8VvkjUnu3pz0IUkq2SoTG0-6Y_ajsUI0YA_BFiAXHjrRhH1Nx3ihGWT7E7VzpU_E1ZPFMJIOPLRSpRv8G6ITnjZGthozTZtKLgoHCF7kx4Ni8eVdOh2Us6kY7tYpVabM1dmw0gextEEt-fBMoI-qZGkXdL1YW6SEtQBHh3BGKX8khcrqNvqPZDFzSG0iieMJq7abbEYAIc8zRkeGlWEdX6ES6e-njnFN7JX0Nc32GzOjmpgx9gRhYe-wKonqBQ9RwLLNK-lFuflLTrU3D8jMiPCJyvoRsjdjEc-2JtHXo14ibOVXvZ6oYCHsTEB7f-90_qzcrITESyDBD_rmiT_SqgitBa44MZE9CZ9Ml-BW0xd9FfCy4oLy8w4vszVFDw9Eotr4pEzdCeDeWjMn35taJnWf6jUeF0z_0iyHjbi7XRubJXxI2YuKQ-HRCKX1RFaJWLhmxO4JNBDBqfYZqsO_FefqxjWi2pRzE8U_Upp8Tv_hy1FoN9Abs8W6lPoqgOyEiOcpVkM-u0CgUbf87I1X2EiPpuJF4D9dHlEJqumiPqIGazSLnrjW1qqbM5UpQQuPoTC7q-G092CEnNJBIwrufddZPDfD9rqINpmMa-7OswldKViVaCWR3VsgrSXJj7lVRntCyE2atWxTvtQVnR_JLDdyc98CAUChtAPnC4K_K3OVI4jffQQsHmfeOnTyg0n2VnZ6Yhgo0lMdE4IfMrNOWOuNvHodeHisD2yXjvTCgScO8B3s-EJTvenHMert3nRgjNRmFZ0cRNSjbTeG0UlB9s7Uy0uyrn5ODkKIgEMOdbH9yJU53jInG9boFeMXb1qif47Pc72taZkl6ZaMK4="}],
|
||||
"role": "model"}, {"parts": [{"functionResponse": {"name": "add_numbers", "response":
|
||||
{"result": 42}}}], "role": "user"}], "systemInstruction": {"parts": [{"text":
|
||||
"You are Calculator. You are a calculator assistant that uses tools to compute
|
||||
results.\nYour personal goal is: Perform calculations using available tools"}],
|
||||
"role": "user"}, "tools": [{"functionDeclarations": [{"description": "Add two
|
||||
numbers together and return the sum.", "name": "add_numbers", "parameters_json_schema":
|
||||
{"properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B",
|
||||
"type": "integer"}}, "required": ["a", "b"], "type": "object", "additionalProperties":
|
||||
false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"], "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -143,42 +152,50 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '3166'
|
||||
- '3441'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.12
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-001:generateContent
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"structured_output\",\n
|
||||
\ \"args\": {\n \"result\": 42,\n \"explanation\":
|
||||
\"15 + 27 = 42\",\n \"operation\": \"addition\"\n }\n
|
||||
\ }\n }\n ],\n \"role\": \"model\"\n },\n
|
||||
\ \"finishReason\": \"STOP\",\n \"avgLogprobs\": -0.07498827245500353\n
|
||||
\ }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\": 421,\n \"candidatesTokenCount\":
|
||||
18,\n \"totalTokenCount\": 439,\n \"promptTokensDetails\": [\n {\n
|
||||
\ \"modality\": \"TEXT\",\n \"tokenCount\": 421\n }\n ],\n
|
||||
\ \"candidatesTokensDetails\": [\n {\n \"modality\": \"TEXT\",\n
|
||||
\ \"tokenCount\": 18\n }\n ]\n },\n \"modelVersion\": \"gemini-2.0-flash-001\",\n
|
||||
\ \"responseId\": \"vlefac7bJb6TjMcPzYWh0Ag\"\n}\n"
|
||||
[\n {\n \"text\": \"**My Calculation and OpenAPI Formatting**\\n\\nOkay,
|
||||
so I've just crunched the numbers, 15 plus 27, and the answer, as expected,
|
||||
is 42. Now comes the formatting, the part I truly appreciate. It's time to
|
||||
translate this into the precise structure that the OpenAPI schema dictates.\\n\\nLet's
|
||||
see\u2026 I need to populate three key fields: `operation`, `result`, and
|
||||
`explanation`. This is straightforward. For `operation`, I'll enter \\\"Addition,\\\"
|
||||
because, well, that's what I did! For `result`, the answer I painstakingly
|
||||
produced, 42. And for `explanation`, a concise note, \\\"Added 15 and 27 together.\\\"
|
||||
Perfect. That should do the trick. Now I can move on to the next task.\\n\",\n
|
||||
\ \"thought\": true\n },\n {\n \"text\":
|
||||
\"{\\n \\\"operation\\\": \\\"Addition\\\",\\n \\\"result\\\": 42,\\n \\\"explanation\\\":
|
||||
\\\"Added 15 and 27 together.\\\"\\n}\",\n \"thoughtSignature\":
|
||||
\"CrcDAQw51sd+vh7cJvN7WGZKQIJGL6Xtr/+CNnL2r9YWGHv5EBrOm/Qdzr4eK0eyrJhuJGBZg5V5XakEuLMULUvth7stE+FTz16F5Vzx2yKMuM5Ictv/DlI7s4Z5WFaI5HJVJTojOhW9K/1TM8y48+eStJre8Qyz3tOvFg1DPEau6JCk+1uoRil2RoZHxFQpd0LaDhl4sKZkRr1e5c2gtfZiK3NHR3ipbRejIOGjDQah4+q4D6ASTiHZxHCBIjAP4HH8DF40oylF6mQR1WHWezKzvkZ0sz3ydPGExM5+lFOE8z1NUpqH2kJ3PfzdrbX2VccIT+5pWz9NsIW8N1JYbPvb7xKENh7mTI+tmCtuAiO9DTwWUf450OHNWdrHQPxn3MMT10+4RMzKBeDAjEFVZ6M68CyUDTJ0uDtqJZ6SXs3ZdmmLGQY1lAk29r0eklaMJLk226uMUKCXlHKwyDbJVH3+SwGkgU+Am81AiekV5ZWQjfe3gUN8ojOLSNvpAfaf/K8ZvR4uGCEMs2pJ2sqI6sCIE9w9+u2biTattqWtcO+wmPXZ/CwU/ASXHlBqt55cvB2XyFTXO7kQGw==\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
421,\n \"candidatesTokenCount\": 36,\n \"totalTokenCount\": 560,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 421\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 103,\n \"serviceTier\": \"standard\"\n
|
||||
\ },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"ragPaseeA6nT_uMP653cmAc\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Wed, 25 Feb 2026 20:12:47 GMT
|
||||
- Fri, 22 May 2026 00:51:59 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=774
|
||||
- gfet4t7; dur=2377
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -189,6 +206,8 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
|
||||
@@ -1025,7 +1025,7 @@ def test_gemini_crew_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="google/gemini-2.0-flash-001"),
|
||||
llm=LLM(model="google/gemini-2.5-flash"),
|
||||
tools=[add_numbers],
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user