15
15
use LLM \Agents \OpenAI \Client \Exception \LimitExceededException ;
16
16
use LLM \Agents \OpenAI \Client \Exception \RateLimitException ;
17
17
use LLM \Agents \OpenAI \Client \Exception \TimeoutException ;
18
+ use LLM \Agents \Tool \ToolChoice ;
18
19
use OpenAI \Contracts \ClientContract ;
19
20
20
21
final class LLM implements LLMInterface
@@ -61,16 +62,7 @@ public function generate(
61
62
}
62
63
63
64
if ($ options ->has (Option::Tools)) {
64
- $ tools = \array_values (
65
- \array_map (
66
- fn (Tool $ tool ): array => $ this ->messageMapper ->map ($ tool ),
67
- $ options ->get (Option::Tools),
68
- ),
69
- );
70
-
71
- if ($ tools !== []) {
72
- $ request ['tools ' ] = $ tools ;
73
- }
65
+ $ request = $ this ->configureTools ($ options , $ request );
74
66
}
75
67
76
68
$ callback = null ;
@@ -88,7 +80,7 @@ public function generate(
88
80
return $ this ->streamParser ->parse ($ stream , $ callback );
89
81
} catch (LimitExceededException ) {
90
82
throw new \LLM \Agents \LLM \Exception \LimitExceededException (
91
- currentLimit: $ request [' max_tokens ' ],
83
+ currentLimit: $ request [Option::MaxTokens-> value ],
92
84
);
93
85
} catch (RateLimitException ) {
94
86
throw new \LLM \Agents \LLM \Exception \RateLimitException ();
@@ -115,4 +107,37 @@ protected function buildOptions(OptionsInterface $options): array
115
107
// filter out null options
116
108
return \array_filter ($ result , static fn ($ value ): bool => $ value !== null );
117
109
}
110
+
111
+ protected function configureTools (Options $ options , array $ request ): array
112
+ {
113
+ $ tools = \array_values (
114
+ \array_map (
115
+ fn (Tool $ tool ): array => $ this ->messageMapper ->map ($ tool ),
116
+ $ options ->get (Option::Tools),
117
+ ),
118
+ );
119
+
120
+ if ($ tools === []) {
121
+ return $ request ;
122
+ }
123
+
124
+ $ request ['tools ' ] = $ tools ;
125
+
126
+ $ choice = $ options ->get (Option::ToolChoice->value );
127
+ if ($ choice instanceof ToolChoice) {
128
+ $ request ['tool_choice ' ] = match (true ) {
129
+ $ choice ->isAuto () => 'auto ' ,
130
+ $ choice ->isAny () => 'required ' ,
131
+ $ choice ->isNone () => 'none ' ,
132
+ $ choice ->isSpecific () => [
133
+ 'type ' => 'function ' ,
134
+ 'function ' => [
135
+ 'name ' => $ choice ->toolName ,
136
+ ],
137
+ ],
138
+ };
139
+ }
140
+
141
+ return $ request ;
142
+ }
118
143
}
0 commit comments