Skip to content

Commit cd77de9

Browse files
authored
Merge pull request #853 from rumpl/gemini-3
Add thought signature
2 parents 4fdd8fd + b0f6eac commit cd77de9

File tree

5 files changed

+50
-9
lines changed

5 files changed

+50
-9
lines changed

e2e/testdata/cassettes/TestExec_Gemini_ToolCall.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@ interactions:
1919
proto_major: 2
2020
proto_minor: 0
2121
content_length: -1
22-
body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"list_directory\",\"args\": {\"path\": \"testdata/working_dir\"}},\"thoughtSignature\": \"CikB0e2Kb2OlLMPMPLZsUR7QGgyeriJhzBVTgK9+Lq++85CcQS8Tee7QtgpwAdHtim9TIoVh62etSFEDN50Tr6ga/e+FqRayGoH61KhdeIuqzpcBXanhthX3rKVZufVgxJzhXb+a7gRlVyq3sVgZAZD6hBgjOi83IUnQLp/qKGW8PwBpCKFOUh17D7+yQ62JbrOHFlfesG3HrIBT/AqpAQHR7Ypv8DVsbwmPd0SyM9uLRCXNOnR40RjP+BN3foP7Qu+A7/365fDL/+6IaQeYMMBmY77XQvkjvKqAJx1gIPbsVtgB1eKbxVBr9UF147gkkYtcqjAiTK13tG6KSUK2itZHcbibJi7hOLLCdELMZxz3WG8iWcQdRswlLEZYiCeGZx9QYxAyUO1BuIUkWsPZsmxc4H2DoPxYWiJI09FpgJ8F1BFByGbwomE=\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 1251,\"candidatesTokenCount\": 20,\"totalTokenCount\": 1326,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 1251}],\"thoughtsTokenCount\": 55},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"GAsWaaTmO9O9jrEP3b7t0Q4\"}\r\n\r\n"
22+
body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"functionCall\": {\"name\": \"list_directory\",\"args\": {\"path\": \"testdata/working_dir\"}},\"thoughtSignature\": \"CiQB0e2Kb8f55SOYzHzh/VoESz0UqNZk0m2s+yiiWKfUEKIQ1nEKZgHR7YpvEobm0Mf3tP07MuK/fwYBk9GcW3aZdUiSDZbGWOJgWAhZ0IXZmpNVOlL5gEBRX9le7ej0zokjdkHv8cExdGd1O58CjB8tKJFbqb8dRaBOmPoqx0UoZAruFr6KsYleL2z5rQrUAQHR7Ypvk6sBdUg6OPTJeHJJ1N5uOPZYAyLUyp66e93CCQ7GCcms8AW/okDM42XJia6UCAjySJpEkzAlgPVRrPN4b6BiH7LMNHnP8PTvASeelDIHu29jflUyNS4imM1dg/ocTCTZOs8/fvVHpU28BAc7WgmtdSymGSx1DrlcesGo2yRMZv41EvK9lhsy332LSf0oTdCQXvYbL7TPdis2v6kde8mkM1K1KfYc/H3lqwOBYLojiETjwtTxZxfAiJn5MWOiPZI7EQ8mYJJOkZepC9QEK/8x\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0,\"finishMessage\": \"Model generated function call(s).\"}],\"usageMetadata\": {\"promptTokenCount\": 1251,\"candidatesTokenCount\": 20,\"totalTokenCount\": 1331,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 1251}],\"thoughtsTokenCount\": 60},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"TKocaeS9N_DjkdUP2eDb-Ak\"}\r\n\r\n"
2323
headers: {}
2424
status: 200 OK
2525
code: 200
26-
duration: 1.445599334s
26+
duration: 785.43625ms
2727
- id: 1
2828
request:
2929
proto: HTTP/1.1
3030
proto_major: 1
3131
proto_minor: 1
3232
content_length: 0
3333
host: generativelanguage.googleapis.com
34-
body: "{\"contents\":[{\"parts\":[{\"text\":\"You are a knowledgeable assistant that helps users with various tasks.\\nBe helpful, accurate, and concise in your responses.\\n\"}],\"role\":\"user\"},{\"parts\":[{\"text\":\"## Filesystem Tool Instructions\\n\\nThis toolset provides comprehensive filesystem operations with built-in security restrictions.\\n\\n### Security Model\\n- All operations are restricted to allowed directories only\\n- Use list_allowed_directories to see available paths\\n- Subdirectories within allowed directories are accessible\\n- Use add_allowed_directory to request access to new directories (requires user consent)\\n\\n### Directory Access Management\\n- If you need access to a directory outside the allowed list, use add_allowed_directory\\n- This will request user consent before expanding filesystem access\\n- Always provide a clear reason when requesting new directory access\\n\\n### Common Patterns\\n- Always check if directories exist before creating files\\n- Prefer read_multiple_files for batch operations\\n- Use search_files_content for finding specific code or text\\n\\n### Performance Tips\\n- Use read_multiple_files instead of multiple read_file calls\\n- Use directory_tree with max_depth to limit large traversals\\n- Use appropriate exclude patterns in search operations\"}],\"role\":\"user\"},{\"parts\":[{\"text\":\"How many files in testdata/working_dir? Only output the number.\"}],\"role\":\"user\"},{\"parts\":[{\"functionCall\":{\"args\":{\"path\":\"testdata/working_dir\"},\"name\":\"list_directory\"}}],\"role\":\"model\"},{\"parts\":[{\"functionResponse\":{\"name\":\"call_8d644b69-7ee9-4f53-b375-9a99945a25dc\",\"response\":{\"result\":\"FILE README.me\\n\"}}}],\"role\":\"user\"}],\"generationConfig\":{},\"toolConfig\":{\"functionCallingConfig\":{\"mode\":\"AUTO\"}},\"tools\":[{\"functionDeclarations\":[{\"description\":\"Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation.\",\"name\":\"create_directory\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to create\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Get a recursive tree view of files and directories as a JSON structure.\",\"name\":\"directory_tree\",\"parameters\":{\"properties\":{\"max_depth\":{\"description\":\"Maximum depth to traverse (optional)\",\"type\":\"integer\"},\"path\":{\"description\":\"The directory path to traverse\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Make line-based edits to a text file. Each edit replaces exact line sequences with new content.\",\"name\":\"edit_file\",\"parameters\":{\"properties\":{\"edits\":{\"description\":\"Array of edit operations\",\"items\":{\"properties\":{\"newText\":{\"description\":\"The replacement text\",\"type\":\"string\"},\"oldText\":{\"description\":\"The exact text to replace\",\"type\":\"string\"}},\"required\":[\"oldText\",\"newText\"],\"type\":\"object\"},\"type\":\"array\"},\"path\":{\"description\":\"The file path to edit\",\"type\":\"string\"}},\"required\":[\"path\",\"edits\"],\"type\":\"object\"}},{\"description\":\"Retrieve detailed metadata about a file or directory.\",\"name\":\"get_file_info\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The file or directory path to inspect\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Returns a list of directories that the server has permission to access. Don't call if you access only the current working directory. It's always allowed.\",\"name\":\"list_allowed_directories\",\"parameters\":{\"type\":\"object\"}},{\"description\":\"Request to add a new directory to the allowed directories list. This requires explicit user consent for security reasons.\",\"name\":\"add_allowed_directory\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to add to allowed directories\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Get a detailed listing of all files and directories in a specified path.\",\"name\":\"list_directory\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to list\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Get a detailed listing of all files and directories in a specified path, including sizes.\",\"name\":\"list_directory_with_sizes\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to list\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Move or rename files and directories.\",\"name\":\"move_file\",\"parameters\":{\"properties\":{\"destination\":{\"description\":\"The destination path\",\"type\":\"string\"},\"source\":{\"description\":\"The source path\",\"type\":\"string\"}},\"required\":[\"source\",\"destination\"],\"type\":\"object\"}},{\"description\":\"Read the complete contents of a file from the file system.\",\"name\":\"read_file\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The file path to read\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Read the contents of multiple files simultaneously.\",\"name\":\"read_multiple_files\",\"parameters\":{\"properties\":{\"json\":{\"description\":\"Whether to return the result as JSON\",\"type\":\"boolean\"},\"paths\":{\"description\":\"Array of file paths to read\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"paths\"],\"type\":\"object\"}},{\"description\":\"Recursively search for files and directories matching a pattern. Prints the full paths of matching files and the total number of files found.\",\"name\":\"search_files\",\"parameters\":{\"properties\":{\"excludePatterns\":{\"description\":\"Patterns to exclude from search\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"path\":{\"description\":\"The starting directory path\",\"type\":\"string\"},\"pattern\":{\"description\":\"The search pattern\",\"type\":\"string\"}},\"required\":[\"path\",\"pattern\"],\"type\":\"object\"}},{\"description\":\"Searches for text or regex patterns in the content of files matching a GLOB pattern.\",\"name\":\"search_files_content\",\"parameters\":{\"properties\":{\"excludePatterns\":{\"description\":\"Patterns to exclude from search\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"is_regex\":{\"description\":\"If true, treat query as regex; otherwise literal text\",\"type\":\"boolean\"},\"path\":{\"description\":\"The starting directory path\",\"type\":\"string\"},\"query\":{\"description\":\"The text or regex pattern to search for\",\"type\":\"string\"}},\"required\":[\"path\",\"query\"],\"type\":\"object\"}},{\"description\":\"Create a new file or completely overwrite an existing file with new content.\",\"name\":\"write_file\",\"parameters\":{\"properties\":{\"content\":{\"description\":\"The content to write to the file\",\"type\":\"string\"},\"path\":{\"description\":\"The file path to write\",\"type\":\"string\"}},\"required\":[\"path\",\"content\"],\"type\":\"object\"}}]}]}\n"
34+
body: "{\"contents\":[{\"parts\":[{\"text\":\"You are a knowledgeable assistant that helps users with various tasks.\\nBe helpful, accurate, and concise in your responses.\\n\"}],\"role\":\"user\"},{\"parts\":[{\"text\":\"## Filesystem Tool Instructions\\n\\nThis toolset provides comprehensive filesystem operations with built-in security restrictions.\\n\\n### Security Model\\n- All operations are restricted to allowed directories only\\n- Use list_allowed_directories to see available paths\\n- Subdirectories within allowed directories are accessible\\n- Use add_allowed_directory to request access to new directories (requires user consent)\\n\\n### Directory Access Management\\n- If you need access to a directory outside the allowed list, use add_allowed_directory\\n- This will request user consent before expanding filesystem access\\n- Always provide a clear reason when requesting new directory access\\n\\n### Common Patterns\\n- Always check if directories exist before creating files\\n- Prefer read_multiple_files for batch operations\\n- Use search_files_content for finding specific code or text\\n\\n### Performance Tips\\n- Use read_multiple_files instead of multiple read_file calls\\n- Use directory_tree with max_depth to limit large traversals\\n- Use appropriate exclude patterns in search operations\"}],\"role\":\"user\"},{\"parts\":[{\"text\":\"How many files in testdata/working_dir? Only output the number.\"}],\"role\":\"user\"},{\"parts\":[{\"functionCall\":{\"args\":{\"path\":\"testdata/working_dir\"},\"name\":\"list_directory\"},\"thoughtSignature\":\"CiQB0e2Kb8f55SOYzHzh/VoESz0UqNZk0m2s+yiiWKfUEKIQ1nEKZgHR7YpvEobm0Mf3tP07MuK/fwYBk9GcW3aZdUiSDZbGWOJgWAhZ0IXZmpNVOlL5gEBRX9le7ej0zokjdkHv8cExdGd1O58CjB8tKJFbqb8dRaBOmPoqx0UoZAruFr6KsYleL2z5rQrUAQHR7Ypvk6sBdUg6OPTJeHJJ1N5uOPZYAyLUyp66e93CCQ7GCcms8AW/okDM42XJia6UCAjySJpEkzAlgPVRrPN4b6BiH7LMNHnP8PTvASeelDIHu29jflUyNS4imM1dg/ocTCTZOs8/fvVHpU28BAc7WgmtdSymGSx1DrlcesGo2yRMZv41EvK9lhsy332LSf0oTdCQXvYbL7TPdis2v6kde8mkM1K1KfYc/H3lqwOBYLojiETjwtTxZxfAiJn5MWOiPZI7EQ8mYJJOkZepC9QEK/8x\"}],\"role\":\"model\"},{\"parts\":[{\"functionResponse\":{\"name\":\"call_831be108-7307-4e54-9a9d-66906dfab974\",\"response\":{\"result\":\"FILE README.me\\n\"}}}],\"role\":\"user\"}],\"generationConfig\":{},\"toolConfig\":{\"functionCallingConfig\":{\"mode\":\"AUTO\"}},\"tools\":[{\"functionDeclarations\":[{\"description\":\"Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation.\",\"name\":\"create_directory\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to create\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Get a recursive tree view of files and directories as a JSON structure.\",\"name\":\"directory_tree\",\"parameters\":{\"properties\":{\"max_depth\":{\"description\":\"Maximum depth to traverse (optional)\",\"type\":\"integer\"},\"path\":{\"description\":\"The directory path to traverse\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Make line-based edits to a text file. Each edit replaces exact line sequences with new content.\",\"name\":\"edit_file\",\"parameters\":{\"properties\":{\"edits\":{\"description\":\"Array of edit operations\",\"items\":{\"properties\":{\"newText\":{\"description\":\"The replacement text\",\"type\":\"string\"},\"oldText\":{\"description\":\"The exact text to replace\",\"type\":\"string\"}},\"required\":[\"oldText\",\"newText\"],\"type\":\"object\"},\"type\":\"array\"},\"path\":{\"description\":\"The file path to edit\",\"type\":\"string\"}},\"required\":[\"path\",\"edits\"],\"type\":\"object\"}},{\"description\":\"Retrieve detailed metadata about a file or directory.\",\"name\":\"get_file_info\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The file or directory path to inspect\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Returns a list of directories that the server has permission to access. Don't call if you access only the current working directory. It's always allowed.\",\"name\":\"list_allowed_directories\",\"parameters\":{\"type\":\"object\"}},{\"description\":\"Request to add a new directory to the allowed directories list. This requires explicit user consent for security reasons.\",\"name\":\"add_allowed_directory\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to add to allowed directories\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Get a detailed listing of all files and directories in a specified path.\",\"name\":\"list_directory\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to list\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Get a detailed listing of all files and directories in a specified path, including sizes.\",\"name\":\"list_directory_with_sizes\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The directory path to list\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Move or rename files and directories.\",\"name\":\"move_file\",\"parameters\":{\"properties\":{\"destination\":{\"description\":\"The destination path\",\"type\":\"string\"},\"source\":{\"description\":\"The source path\",\"type\":\"string\"}},\"required\":[\"source\",\"destination\"],\"type\":\"object\"}},{\"description\":\"Read the complete contents of a file from the file system.\",\"name\":\"read_file\",\"parameters\":{\"properties\":{\"path\":{\"description\":\"The file path to read\",\"type\":\"string\"}},\"required\":[\"path\"],\"type\":\"object\"}},{\"description\":\"Read the contents of multiple files simultaneously.\",\"name\":\"read_multiple_files\",\"parameters\":{\"properties\":{\"json\":{\"description\":\"Whether to return the result as JSON\",\"type\":\"boolean\"},\"paths\":{\"description\":\"Array of file paths to read\",\"items\":{\"type\":\"string\"},\"type\":\"array\"}},\"required\":[\"paths\"],\"type\":\"object\"}},{\"description\":\"Recursively search for files and directories matching a pattern. Prints the full paths of matching files and the total number of files found.\",\"name\":\"search_files\",\"parameters\":{\"properties\":{\"excludePatterns\":{\"description\":\"Patterns to exclude from search\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"path\":{\"description\":\"The starting directory path\",\"type\":\"string\"},\"pattern\":{\"description\":\"The search pattern\",\"type\":\"string\"}},\"required\":[\"path\",\"pattern\"],\"type\":\"object\"}},{\"description\":\"Searches for text or regex patterns in the content of files matching a GLOB pattern.\",\"name\":\"search_files_content\",\"parameters\":{\"properties\":{\"excludePatterns\":{\"description\":\"Patterns to exclude from search\",\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"is_regex\":{\"description\":\"If true, treat query as regex; otherwise literal text\",\"type\":\"boolean\"},\"path\":{\"description\":\"The starting directory path\",\"type\":\"string\"},\"query\":{\"description\":\"The text or regex pattern to search for\",\"type\":\"string\"}},\"required\":[\"path\",\"query\"],\"type\":\"object\"}},{\"description\":\"Create a new file or completely overwrite an existing file with new content.\",\"name\":\"write_file\",\"parameters\":{\"properties\":{\"content\":{\"description\":\"The content to write to the file\",\"type\":\"string\"},\"path\":{\"description\":\"The file path to write\",\"type\":\"string\"}},\"required\":[\"path\",\"content\"],\"type\":\"object\"}}]}]}\n"
3535
form:
3636
alt:
3737
- sse
@@ -42,8 +42,8 @@ interactions:
4242
proto_major: 2
4343
proto_minor: 0
4444
content_length: -1
45-
body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"1\",\"thoughtSignature\": \"CikB0e2Kb42OK8teDyhqaDnoUT0ce+C51Jq40cgh0j8PwIpKKNoQMEVgqwpwAdHtim+vseQjz0kQ4tl57L5XV1uY90HsM2VSV+FhUhfEtW9kqrt8vDV8fvrpMpuoH4z2JCD1QD5ZwoRp1H64NDrBibL5thM3jX9g583b2qxnMRQ341vkoDS7npCpgUT4B6ig0iK45daNSU/62j6PRQrcAQHR7YpvQtivT5eXDp0mZvyTxpf6M9LmVjCbkIN3of3QFmgowK6qkGSA4XniTZgDEzPWEm6MSo8iJt9wLOqWytSDHdqFucm9Fc5xw1urMpboBABa7Zfr3/yCjIv3+o7E2B+kB/rABM+cjdYG+svBE2UiT7Ju+IMcMtVtAiBv7kiUV0dTWWuUYrvhpTHtThZ2f5uQH6syJMhXg+eePrvQXp0YgigKXPCCe5vTVeCpOjxb2GgkPt3hSZ5iOOUNRzHgktX76ginv5/5AIjLEZhJ2Kv2oas9HdIuumQx00gKPAHR7Ypv4KAhsYBbBG6TS1jrOL9FcbxNXaC+kP70/IbUtKxo6pBFb8SB2ONgank4TBQRuk5FKI1d1Sp9FQ==\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 1324,\"candidatesTokenCount\": 1,\"totalTokenCount\": 1405,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 1324}],\"thoughtsTokenCount\": 80},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"GgsWaYf3F_egxN8P06_M2A4\"}\r\n\r\n"
45+
body: "data: {\"candidates\": [{\"content\": {\"parts\": [{\"text\": \"1\",\"thoughtSignature\": \"CisB0e2Kb/snMJjkCwgprc1hS8RyOF2TyLcdopWuqRkVAhcCWPX10EoQBjVfClkB0e2Kb+kML2HtOf0M6nLMgwVmYOBMkpXntlpxET+KYEALmFtJSqZazPUB6TKU4D4Fd4OaHpWS6NlN2Gmt+01W1nin7H+I0EiU0ZUSkdnUoikF/91Ti9Y+2A==\"}],\"role\": \"model\"},\"finishReason\": \"STOP\",\"index\": 0}],\"usageMetadata\": {\"promptTokenCount\": 1381,\"candidatesTokenCount\": 1,\"totalTokenCount\": 1402,\"cachedContentTokenCount\": 779,\"promptTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 1381}],\"cacheTokensDetails\": [{\"modality\": \"TEXT\",\"tokenCount\": 779}],\"thoughtsTokenCount\": 20},\"modelVersion\": \"gemini-2.5-flash\",\"responseId\": \"TaocacWdJaDhnsEPkvrygAc\"}\r\n\r\n"
4646
headers: {}
4747
status: 200 OK
4848
code: 200
49-
duration: 1.093186042s
49+
duration: 460.39925ms

pkg/chat/chat.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ type Message struct {
5252
// ThinkingSignature is used for Anthropic's extended thinking feature
5353
ThinkingSignature string `json:"thinking_signature,omitempty"`
5454

55+
ThoughtSignature []byte `json:"thought_signature,omitempty"`
56+
5557
FunctionCall *tools.FunctionCall `json:"function_call,omitempty"`
5658

5759
// For Role=assistant prompts this may be set to the tool calls generated by the model, such as function calls.
@@ -93,6 +95,7 @@ type MessageDelta struct {
9395
Content string `json:"content,omitempty"`
9496
ReasoningContent string `json:"reasoning_content,omitempty"`
9597
ThinkingSignature string `json:"thinking_signature,omitempty"`
98+
ThoughtSignature []byte `json:"thought_signature,omitempty"`
9699
FunctionCall *tools.FunctionCall `json:"function_call,omitempty"`
97100
ToolCalls []tools.ToolCall `json:"tool_calls,omitempty"`
98101
}

0 commit comments

Comments
 (0)