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 request into calls against functions.
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