ToolExtractor class
Custom function calling, emulated on a backend that has none.
The conversation protocol has nowhere to declare a caller's functions: the only tool flags it understands switch on tools that run inside OpenAI and come back as prose. So calls are produced the way JSON mode already is — by prompt — but through a dedicated, stateless request rather than the conversation itself.
That separation is the whole design, not an implementation detail. Measured anonymously on 2026-08-20: with the manifest in a live conversation's system prompt, "weather in Lima and Quito" produced a usable envelope 0 times out of 5 — the model answered from its own web search instead, and turning search off did not reliably stop it. With the manifest in the user turn of a throwaway session, the same request went 4 for 4, and 25 of 28 over a wider battery, with no false positives on 8 prompts that needed no function at all.
So: an extraction is not part of a conversation and cannot see one. Feed it the user's request, run whatever calls come back yourself, and send the results into your chat session as ordinary text.
final extractor = ToolExtractor(client: client);
final result = await extractor.extract(
'weather in Lima and Quito',
functions: [
const FunctionTool(
name: 'get_weather',
description: 'Current weather for a city',
parameters: {
'type': 'object',
'properties': {'city': {'type': 'string'}},
'required': ['city'],
},
),
],
);
switch (result) {
case ToolCallsExtracted(:final calls):
for (final call in calls) await run(call.name, call.arguments);
case ToolInfoNeeded(:final missing):
ask(user, 'I still need: ${missing.join(', ')}');
case NoToolCall():
await session.send(request);
}
Constructors
- ToolExtractor({required ChatGptClient client, String model = 'auto'})
-
Creates an extractor over
client.
Properties
- client → ChatGptClient
-
The client whose transport and quota the extraction spends.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- model → String
-
The model asked for. See the constructor's note.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
extract(
String request, {required List< FunctionTool> functions, ToolChoice choice = ToolChoice.auto, bool verify = false}) → Future<ToolExtraction> -
Turns
requestinto calls againstfunctions. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited