generateStructured method

Future<StructuredResult> generateStructured(
  1. String prompt,
  2. String schema, {
  3. StructuredOutputMode mode = StructuredOutputMode.validationOnly,
  4. LlmOptions? options,
})

Generate a completion constrained to schema.

mode picks how the schema is enforced:

Throws SDKException when mode cannot be honored, generation fails, or the output cannot be parsed against the schema.

Implementation

Future<StructuredResult> generateStructured(
  String prompt,
  String schema, {
  StructuredOutputMode mode = StructuredOutputMode.validationOnly,
  LlmOptions? options,
}) async {
  if (mode == StructuredOutputMode.constrained) {
    throw SDKException.featureNotAvailable(
      'llm.generateStructured(mode: constrained) needs engine-level '
      'constrained decoding, which is not wired in yet; use validationOnly or repair',
    );
  }
  await ModelGate.ensureLoaded(
    modelId: options?.model,
    category: ModelCategory.MODEL_CATEGORY_LANGUAGE,
  );
  final effective = options ?? LlmOptions();
  final model =
      await ModelGate.currentId(ModelCategory.MODEL_CATEGORY_LANGUAGE) ?? '';
  var proto = await RunAnywhereStructuredOutput.generateStructured(
    prompt: prompt,
    schema: schema,
    options: effective.toProto(
      registeredTools: RunAnywhereTools.shared.getRegisteredTools(),
    ),
  );
  if (mode == StructuredOutputMode.repair && !proto.validation.isValid) {
    final repairPrompt =
        '$prompt\n\n'
        'Your previous answer did not match the required JSON schema. '
        'Reply again with ONLY JSON that satisfies this schema.\n\n'
        'Previous invalid answer: '
        '${proto.hasRawText() ? proto.rawText : ''}';
    proto = await RunAnywhereStructuredOutput.generateStructured(
      prompt: repairPrompt,
      schema: schema,
      options: effective.toProto(
        registeredTools: RunAnywhereTools.shared.getRegisteredTools(),
      ),
    );
  }
  return StructuredResult.fromProto(
    proto,
    GenerationResult(text: proto.hasRawText() ? proto.rawText : '', model: model),
  );
}