validateToolCalls function

List<String> validateToolCalls(
  1. List<ToolCall> calls,
  2. List<FunctionTool> functions
)

Checks each call's arguments against its function's JSON Schema.

Returns human-readable errors, empty when everything fits. Recursive: nested objects, arrays of objects and enums are all checked, because the measured structural reliability (42 of 42 schema-valid extractions over three levels of nesting) is only meaningful if the check goes that deep.

This is a deliberate subset of JSON Schema — type, required, enum, properties, items, additionalProperties: false. It exists to catch a model that misread a schema, not to be a conformant validator. A keyword it does not know is ignored rather than treated as a failure: rejecting a valid call is worse here than passing an unusual one through.

Implementation

List<String> validateToolCalls(
  List<ToolCall> calls,
  List<FunctionTool> functions,
) {
  final byName = {for (final f in functions) f.name: f};
  final errors = <String>[];

  for (final call in calls) {
    final fn = byName[call.name];
    if (fn == null) {
      errors.add('unknown function "${call.name}"');
      continue;
    }
    errors.addAll(
      _walk(call.arguments, fn.parameters).map((e) => '${fn.name}: $e'),
    );
  }
  return errors;
}