Skip to content

Commit 5626e6a

Browse files
authored
Merge pull request #6 from llm-agents-php/feature/tool-choise
Adds an ability configuring function calling behavior using the `tool_choice` parameter
2 parents 46d55be + 1e24b35 commit 5626e6a

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

Diff for: composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"require": {
66
"php": "^8.3",
77
"openai-php/client": "^0.10.1",
8-
"llm-agents/agents": "^1.5",
8+
"llm-agents/agents": "^1.6",
99
"guzzlehttp/guzzle": "^7.0"
1010
},
1111
"require-dev": {

Diff for: src/LLM.php

+36-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use LLM\Agents\OpenAI\Client\Exception\LimitExceededException;
1616
use LLM\Agents\OpenAI\Client\Exception\RateLimitException;
1717
use LLM\Agents\OpenAI\Client\Exception\TimeoutException;
18+
use LLM\Agents\Tool\ToolChoice;
1819
use OpenAI\Contracts\ClientContract;
1920

2021
final class LLM implements LLMInterface
@@ -61,16 +62,7 @@ public function generate(
6162
}
6263

6364
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);
7466
}
7567

7668
$callback = null;
@@ -88,7 +80,7 @@ public function generate(
8880
return $this->streamParser->parse($stream, $callback);
8981
} catch (LimitExceededException) {
9082
throw new \LLM\Agents\LLM\Exception\LimitExceededException(
91-
currentLimit: $request['max_tokens'],
83+
currentLimit: $request[Option::MaxTokens->value],
9284
);
9385
} catch (RateLimitException) {
9486
throw new \LLM\Agents\LLM\Exception\RateLimitException();
@@ -115,4 +107,37 @@ protected function buildOptions(OptionsInterface $options): array
115107
// filter out null options
116108
return \array_filter($result, static fn($value): bool => $value !== null);
117109
}
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+
}
118143
}

Diff for: src/Option.php

+1
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ enum Option: string
2121

2222
// Application options
2323
case Tools = 'tools';
24+
case ToolChoice = 'tool_choice';
2425
case StreamChunkCallback = 'stream_chunk_callback';
2526
}

0 commit comments

Comments
 (0)