Class: Yorishiro::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/yorishiro/configuration.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/yorishiro/configuration.rb', line 9

def initialize
  @provider_name = nil
  @api_key = nil
  @model = nil
  @allowed_tools = []
  @skills = []
  @mcp_servers = {}
  @system_prompt_text = nil
  @plan_mode_enabled = false
  @ollama_num_ctx_value = nil
  @auto_compact_enabled = true
  @hooks = Hooks.new
end

Instance Attribute Details

#allowed_toolsObject (readonly)

Returns the value of attribute allowed_tools.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def allowed_tools
  @allowed_tools
end

#api_keyObject (readonly)

Returns the value of attribute api_key.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def api_key
  @api_key
end

#auto_compact_enabledObject (readonly)

Returns the value of attribute auto_compact_enabled.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def auto_compact_enabled
  @auto_compact_enabled
end

#hooksObject (readonly)

Returns the value of attribute hooks.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def hooks
  @hooks
end

#mcp_serversObject (readonly)

Returns the value of attribute mcp_servers.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def mcp_servers
  @mcp_servers
end

#modelObject (readonly)

Returns the value of attribute model.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def model
  @model
end

#ollama_num_ctx_valueObject (readonly)

Returns the value of attribute ollama_num_ctx_value.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def ollama_num_ctx_value
  @ollama_num_ctx_value
end

#plan_mode_enabledObject (readonly)

Returns the value of attribute plan_mode_enabled.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def plan_mode_enabled
  @plan_mode_enabled
end

#provider_nameObject (readonly)

Returns the value of attribute provider_name.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def provider_name
  @provider_name
end

#skillsObject (readonly)

Returns the value of attribute skills.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def skills
  @skills
end

#system_prompt_textObject (readonly)

Returns the value of attribute system_prompt_text.



5
6
7
# File 'lib/yorishiro/configuration.rb', line 5

def system_prompt_text
  @system_prompt_text
end

Instance Method Details

#allow_tool(tool, **options) ⇒ Object



43
44
45
46
# File 'lib/yorishiro/configuration.rb', line 43

def allow_tool(tool, **options)
  tool.configure(options) if tool.respond_to?(:configure)
  @allowed_tools << tool
end

#auto_compact(enabled) ⇒ Object

Toggle automatic context compaction (LLM summarization of old history when the conversation nears the context window). Enabled by default; disable from .yorishirorc with auto_compact false.



85
86
87
# File 'lib/yorishiro/configuration.rb', line 85

def auto_compact(enabled)
  @auto_compact_enabled = enabled
end

#deny(reason = "denied by hook") ⇒ Object

Hook helper: return deny("reason") from a before_tool_use or user_prompt_submit block to veto the action.



99
100
101
# File 'lib/yorishiro/configuration.rb', line 99

def deny(reason = "denied by hook")
  Hooks::Denial.new(reason)
end

#find_tool(name) ⇒ Object



123
124
125
# File 'lib/yorishiro/configuration.rb', line 123

def find_tool(name)
  @allowed_tools.find { |t| t.name == name }
end

#load!Object



103
104
105
106
107
108
109
# File 'lib/yorishiro/configuration.rb', line 103

def load!
  load_rc_file(global_rc_path)
  load_rc_file(local_rc_path)
  load_skill_files(global_skills_dir)
  load_skill_files(local_skills_dir)
  validate!
end

#mcp_server(name, command:, args: [], env: {}) ⇒ Object



64
65
66
# File 'lib/yorishiro/configuration.rb', line 64

def mcp_server(name, command:, args: [], env: {})
  @mcp_servers[name] = { command: command, args: args, env: env }
end

#ollama_num_ctx(value) ⇒ Object

Override the Ollama context window (num_ctx). Set from .yorishirorc, e.g. ollama_num_ctx 16384. Also settable via the OLLAMA_NUM_CTX env var.



78
79
80
# File 'lib/yorishiro/configuration.rb', line 78

def ollama_num_ctx(value)
  @ollama_num_ctx_value = value
end

#on(event) ⇒ Object

Register a lifecycle hook from .yorishirorc, e.g. on :before_tool_use do |tool_name, args| deny("rm is not allowed") if args.to_s.start_with?("rm") end



93
94
95
# File 'lib/yorishiro/configuration.rb', line 93

def on(event, &)
  @hooks.on(event, &)
end

#plan_mode(enabled) ⇒ Object



72
73
74
# File 'lib/yorishiro/configuration.rb', line 72

def plan_mode(enabled)
  @plan_mode_enabled = enabled
end

#read_only_tool_definitionsObject



131
132
133
# File 'lib/yorishiro/configuration.rb', line 131

def read_only_tool_definitions
  @allowed_tools.select(&:read_only?).map(&:definition)
end

#replace_skill(skill_instance) ⇒ Object

Register a skill, replacing any same-name skill registered earlier (so ./.yorishiro/skills overrides ~/.yorishiro/skills).



57
58
59
60
61
62
# File 'lib/yorishiro/configuration.rb', line 57

def replace_skill(skill_instance)
  raise SkillNotImplementedError, "Skill must implement #name" unless skill_instance.respond_to?(:name)

  @skills.reject! { |s| s.name == skill_instance.name }
  skill(skill_instance)
end

#skill(skill_instance) ⇒ Object



48
49
50
51
52
53
# File 'lib/yorishiro/configuration.rb', line 48

def skill(skill_instance)
  raise SkillNotImplementedError, "Skill must implement #name" unless skill_instance.respond_to?(:name)
  raise SkillNotImplementedError, "Skill must implement #execute" unless skill_instance.respond_to?(:execute)

  @skills << skill_instance
end

#switch!(provider:, model:, api_key:) ⇒ Object

Switch provider/model at runtime (e.g. the /model command). Re-validates and rolls back to the previous settings if the new combination is invalid, so a rejected switch never leaves the config half-changed.



32
33
34
35
36
37
38
39
40
41
# File 'lib/yorishiro/configuration.rb', line 32

def switch!(provider:, model:, api_key:)
  previous = [@provider_name, @api_key, @model]
  @provider_name = provider
  @api_key = api_key
  @model = model
  validate!
rescue ConfigurationError
  @provider_name, @api_key, @model = previous
  raise
end

#system_prompt(text) ⇒ Object



68
69
70
# File 'lib/yorishiro/configuration.rb', line 68

def system_prompt(text)
  @system_prompt_text = text
end

#tool_definitionsObject



127
128
129
# File 'lib/yorishiro/configuration.rb', line 127

def tool_definitions
  @allowed_tools.map(&:definition)
end

#use(provider:, api_key: nil, model: nil) ⇒ Object



23
24
25
26
27
# File 'lib/yorishiro/configuration.rb', line 23

def use(provider:, api_key: nil, model: nil)
  @provider_name = provider
  @api_key = api_key
  @model = model
end

#validate!Object

Raises:



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/yorishiro/configuration.rb', line 111

def validate!
  raise ConfigurationError, "Provider is not set. Use `use provider: :provider_name`" unless @provider_name

  raise ConfigurationError, "Unsupported provider: #{@provider_name}" unless %i[anthropic open_ai ollama].include?(@provider_name)

  if @provider_name != :ollama && (@api_key.nil? || @api_key.empty?)
    raise ConfigurationError, "API key is required for #{@provider_name}"
  end

  validate_model! if @model
end