module AiModelCatalog
Constants
- LIST_MODELS_PATTERN
- MODELS_HEADER_PATTERN
- MODELS_TIP_PATTERN
- ModelEntry
Public Instance Methods
Source
# File lib/ai/model_catalog.rb, line 128 def build_paragraphs(items, max_bytes:, separator: ", ") paragraphs = [] current = +"" items.each do |item| candidate = current.empty? ? item : "#{current}#{separator}#{item}" if candidate.bytesize > max_bytes && !current.empty? paragraphs << current current = item.dup else current = candidate end end paragraphs << current unless current.empty? paragraphs end
Source
# File lib/ai/model_catalog.rb, line 96 def format_bases(catalog, max_bytes:) bases = catalog.bases header = "AI models (bases):" body = build_paragraphs(bases, max_bytes: max_bytes).join("\n\n") "#{header} #{body}" end
Source
# File lib/ai/model_catalog.rb, line 70 def format_listing(catalog, base: nil, version: nil, max_bytes: RabbotConfig::PRIVMSG_CHUNK_BYTES) return "No models available." if catalog.empty? if base.nil? return format_bases(catalog, max_bytes: max_bytes) end base_key = base.to_s.downcase unless catalog.base?(base_key) return unknown_base_message(catalog, base_key) end versions = catalog.versions_for(base_key) if version.nil? return format_versions(catalog, base_key, max_bytes: max_bytes) if versions.any? return format_variants(catalog, base_key, nil, max_bytes: max_bytes) end unless catalog.version?(base_key, version) return unknown_version_message(catalog, base_key, version) end format_variants(catalog, base_key, version, max_bytes: max_bytes) end
Source
# File lib/ai/model_catalog.rb, line 110 def format_variants(catalog, base, version, max_bytes:) entries = catalog.variants_for(base, version) label = version ? "#{base} #{version}" : base header = "AI models (#{label}):" lines = entries.map { |entry| "#{entry.model} - #{entry.desc}" } paragraphs = build_paragraphs(lines, max_bytes: max_bytes) ([header] + paragraphs).join("\n\n") end
Source
# File lib/ai/model_catalog.rb, line 103 def format_versions(catalog, base, max_bytes:) versions = catalog.versions_for(base) header = "AI models (#{base} versions):" body = build_paragraphs(versions, max_bytes: max_bytes).join("\n\n") "#{header} #{body}" end
Source
# File lib/ai/model_catalog.rb, line 61 def load(raw_text) lines = raw_text.to_s.lines.map(&:strip).reject(&:empty?) model_lines = lines.reject do |line| line.match?(MODELS_HEADER_PATTERN) || models_tip_line?(line) end entries = model_lines.map { |line| parse_model_line(line) } Catalog.new(entries) end
Source
# File lib/ai/model_catalog.rb, line 19 def models_command?(question) match = question.to_s.strip.match(LIST_MODELS_PATTERN) return nil unless match { base: match[1]&.downcase, version: match[2] } end
Source
# File lib/ai/model_catalog.rb, line 29 def models_tip_line?(line) line.to_s.strip.match?(MODELS_TIP_PATTERN) end
Source
# File lib/ai/model_catalog.rb, line 42 def parse_model_id(model_id) model_id = model_id.to_s.strip return ["auto", nil, nil] if model_id == "auto" if (match = model_id.match(/\A((?:claude-opus|claude-fable))-(\d+)-(\d+)(?:-(.+))?\z/)) return [match[1], "#{match[2]}.#{match[3]}", match[4]] end if (match = model_id.match(/\Aclaude-fable-(\d+)(?:-(.+))?\z/)) return ["claude-fable", match[1], match[2]] end if (match = model_id.match(/\A(.+?)-(\d+\.\d+)(?:-(.+))?\z/)) return [match[1], match[2], match[3]] end [model_id, nil, nil] end
Source
# File lib/ai/model_catalog.rb, line 33 def parse_model_line(line) model_id, desc = line.to_s.split(/\s+-\s+/, 2) model_id = model_id.to_s.strip desc = desc.to_s.strip desc = model_id if desc.empty? base, version, variant = parse_model_id(model_id) ModelEntry.new(model: model_id, base: base, version: version, variant: variant, desc: desc) end
Source
# File lib/ai/model_catalog.rb, line 119 def unknown_base_message(catalog, base) "Unknown base '#{base}'. Bases: #{catalog.bases.join(', ')}" end
Source
# File lib/ai/model_catalog.rb, line 123 def unknown_version_message(catalog, base, version) versions = catalog.versions_for(base) "Unknown version '#{version}' for #{base}. Versions: #{versions.join(', ')}" end