Module: OllamaAgent::Skills::JsonExtractor

Defined in:
lib/ollama_agent/skills/json_extractor.rb

Overview

Extracts the first balanced JSON object/array from raw LLM text. Tolerates leading prose, trailing commentary, and “‘json fenced blocks. Skips brackets inside JSON string literals so embedded braces don’t break parsing.

Defined Under Namespace

Classes: BalancedScan, ExtractionError

Constant Summary collapse

FENCED =
/```(?:json)?\s*(\{.*?\}|\[.*?\])\s*```/m
CLOSERS =
{ "{" => "}", "[" => "]" }.freeze

Class Method Summary collapse

Class Method Details

.balanced_slice(text) ⇒ Object



33
34
35
36
37
38
39
# File 'lib/ollama_agent/skills/json_extractor.rb', line 33

def balanced_slice(text)
  start = text.index(/[{\[]/)
  return nil if start.nil?

  length = BalancedScan.new(text[start..]).length
  length && text[start, length]
end

.extract(text) ⇒ Object

Raises:



24
25
26
27
28
29
30
31
# File 'lib/ollama_agent/skills/json_extractor.rb', line 24

def extract(text)
  raise ExtractionError, "empty model output" if text.to_s.strip.empty?

  fenced = text.match(FENCED)
  return fenced[1] if fenced

  balanced_slice(text) || raise(ExtractionError, "no JSON object found in model output")
end

.parse(text) ⇒ Object



18
19
20
21
22
# File 'lib/ollama_agent/skills/json_extractor.rb', line 18

def parse(text)
  JSON.parse(extract(text), symbolize_names: true)
rescue JSON::ParserError => e
  raise ExtractionError, "invalid JSON in model output: #{e.message}"
end