scanMarkdownForRendering function

MarkdownRenderDecision scanMarkdownForRendering(
  1. String source, {
  2. required ChatInputBudget budget,
})

Implementation

MarkdownRenderDecision scanMarkdownForRendering(
  String source, {
  required ChatInputBudget budget,
}) {
  budget.validate();
  var tokens = 0;
  var syntaxExceeded = false;
  final lineScanner = _MarkdownLineScanner();
  final fallback = StringBuffer();
  var fallbackBytes = 0;
  var fallbackNextIndex = 0;
  var fallbackFull = false;

  for (var index = 0; index < source.length; index += 1) {
    final codeUnit = source.codeUnitAt(index);
    if (!fallbackFull && index == fallbackNextIndex) {
      final scalar = _plainFallbackScalar(source, index);
      if (scalar.bytes > budget.maxMarkdownFallbackBytes - fallbackBytes) {
        fallbackFull = true;
      } else {
        fallback.write(scalar.text);
        fallbackBytes += scalar.bytes;
        fallbackNextIndex += scalar.codeUnits;
      }
    }
    if (!syntaxExceeded) {
      final lineTokens = lineScanner.consume(codeUnit);
      final syntaxTokens = _isMarkdownSyntaxCodeUnit(codeUnit) ? 1 : 0;
      tokens += lineTokens + syntaxTokens;
      if (tokens > budget.maxMarkdownSyntaxTokens) {
        syntaxExceeded = true;
      }
    }
    if (syntaxExceeded && fallbackFull) break;
  }

  if (!syntaxExceeded) {
    tokens += lineScanner.finish();
    syntaxExceeded = tokens > budget.maxMarkdownSyntaxTokens;
  }

  if (!syntaxExceeded) {
    return MarkdownRenderDecision(text: source, useMarkdown: true);
  }

  return MarkdownRenderDecision(
    text: fallback.toString(),
    useMarkdown: false,
    omission: ChatInputOmission(
      reason: ChatInputOmissionReason.inputLimit,
      resource: 'markdown syntax tokens',
      truncated: true,
      limit: budget.maxMarkdownSyntaxTokens,
      observedAtLeast: tokens,
    ),
  );
}