Class: RosettAi::Compiler::TargetProfile

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/compiler/target_profile.rb

Overview

Loads and validates target profiles from conf/engines//target.yml, with fallback to conf/targets/.yml for backward compatibility.

Target profiles declare which backend to use, the output format, and rendering options for a specific AI assistant target. Adding a new target requires only a new YAML file — no code changes.

Constant Summary collapse

FIELDS =
[
  :name, :description, :backend, :engine_version, :output_format,
  :output_dir, :max_context_window, :rendering
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ TargetProfile

Returns a new instance of TargetProfile.



25
26
27
28
29
# File 'lib/rosett_ai/compiler/target_profile.rb', line 25

def initialize(data)
  FIELDS.each do |field|
    instance_variable_set(:"@#{field}", data[field.to_s])
  end
end

Class Method Details

.availableArray<String>

Returns sorted list of all available target names (from plugins, engine dir, and legacy targets dir).

Returns:

  • (Array<String>)

    sorted list of all available target names (from plugins, engine dir, and legacy targets dir)



73
74
75
76
77
78
79
80
81
82
# File 'lib/rosett_ai/compiler/target_profile.rb', line 73

def self.available
  plugin_targets = RosettAi::Plugins::Registry.available(:engine)
  engine_targets = Dir.glob(RosettAi.root.join('conf', 'engines', '*', 'target.yml')).map do |file|
    File.basename(File.dirname(file))
  end
  legacy_targets = Dir.glob(legacy_targets_dir.join('*.yml')).map do |file|
    File.basename(file, '.yml')
  end
  (plugin_targets + engine_targets + legacy_targets).uniq.sort
end

.engine_target_path(name) ⇒ Object



84
85
86
# File 'lib/rosett_ai/compiler/target_profile.rb', line 84

def self.engine_target_path(name)
  RosettAi.root.join('conf', 'engines', name, 'target.yml')
end

.legacy_target_path(name) ⇒ Object



88
89
90
# File 'lib/rosett_ai/compiler/target_profile.rb', line 88

def self.legacy_target_path(name)
  legacy_targets_dir.join("#{name}.yml")
end

.legacy_targets_dirObject



92
93
94
# File 'lib/rosett_ai/compiler/target_profile.rb', line 92

def self.legacy_targets_dir
  RosettAi.root.join('conf', 'targets')
end

.load(target_name) ⇒ TargetProfile

Load and validate a target profile by name.

Resolution order:

  1. Plugin registry (engine gem's target_profile_path)
  2. conf/engines/<name>/target.yml (core tree)
  3. conf/targets/<name>.yml (legacy)

Parameters:

  • target_name (String)

    engine/target identifier

Returns:

Raises:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rosett_ai/compiler/target_profile.rb', line 41

def self.load(target_name)
  # 1. Check plugin registry for engine-provided target profile
  if RosettAi::Plugins::Registry.registered?(:engine, target_name)
    plugin = RosettAi::Plugins::Registry.plugin_module(:engine, target_name)
    if plugin.respond_to?(:target_profile_path) && plugin.target_profile_path.exist?
      data = RosettAi::YamlLoader.load_file(plugin.target_profile_path)
      validate!(data, plugin.target_profile_path)
      return new(data)
    end
  end

  # 2. Fallback: file-based lookup (core conf/ tree)
  path = engine_target_path(target_name)
  path = legacy_target_path(target_name) unless path.exist?
  unless path.exist?
    available_list = available
    hint = if available_list.empty?
             "Install an engine: apt install rosett-ai-engine-#{target_name.tr('_', '-')}"
           else
             available_list.join(', ')
           end
    raise RosettAi::CompileError,
          "Unknown target: #{target_name}. Available: #{hint}"
  end

  data = RosettAi::YamlLoader.load_file(path)
  validate!(data, path)
  new(data)
end