Class: Legion::CLI::Chat::DaemonChat

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/cli/chat/daemon_chat.rb

Overview

Daemon-backed chat adapter. Matches the interface that Session expects from a chat object (ask, with_tools, with_instructions, on_tool_call, on_tool_result, model, add_message, reset_messages!, with_model).

All LLM inference is routed through the running daemon via POST /api/llm/inference. Tool execution runs locally on the client machine — the daemon returns tool_call requests and the client executes them and loops.

Defined Under Namespace

Classes: ModelInfo, Response, ToolResult

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model: nil, provider: nil) ⇒ DaemonChat

Returns a new instance of DaemonChat.



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/legion/cli/chat/daemon_chat.rb', line 41

def initialize(model: nil, provider: nil)
  @model    = ModelInfo.new(id: model)
  @provider = provider
  @messages = []
  @tools    = []
  @instructions = nil
  @on_tool_call   = nil
  @on_tool_result = nil
  @conversation_id = SecureRandom.uuid
  @caller_context  = build_caller
end

Instance Attribute Details

#caller_contextObject (readonly)

Returns the value of attribute caller_context.



39
40
41
# File 'lib/legion/cli/chat/daemon_chat.rb', line 39

def caller_context
  @caller_context
end

#conversation_idObject (readonly)

Returns the value of attribute conversation_id.



39
40
41
# File 'lib/legion/cli/chat/daemon_chat.rb', line 39

def conversation_id
  @conversation_id
end

#modelObject (readonly)

Returns the value of attribute model.



39
40
41
# File 'lib/legion/cli/chat/daemon_chat.rb', line 39

def model
  @model
end

Instance Method Details

#add_message(role:, content:) ⇒ Object

Appends a message to the conversation history directly (used by slash commands /fetch, /search, /agent, etc. that inject context).



84
85
86
# File 'lib/legion/cli/chat/daemon_chat.rb', line 84

def add_message(role:, content:)
  @messages << { role: role.to_s, content: content }
end

#ask(message, &on_chunk) ⇒ Object

Sends a message through the daemon inference loop. Executes any tool_calls locally and loops until the LLM stops. Yields response-like chunks for streaming display (Phase 1: single chunk). Returns a Response object compatible with Session#send_message.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/legion/cli/chat/daemon_chat.rb', line 97

def ask(message, &on_chunk)
  @messages << { role: 'user', content: message }

  loop do
    result = call_daemon_inference

    raise CLI::Error, "Daemon inference error: #{result[:error]}" if result[:status] == :error
    raise CLI::Error, 'Daemon is unavailable' if result[:status] == :unavailable

    data = extract_data(result)

    if data[:tool_calls]&.any?
      execute_tool_calls(data[:tool_calls], data[:content])
    else
      on_chunk&.call(Response.new(content: data[:content]))
      @messages << { role: 'assistant', content: data[:content] }
      return build_response(data)
    end
  end
end

#on_tool_call(&block) ⇒ Object

Stores a tool_call callback invoked before each local tool execution.



73
74
75
# File 'lib/legion/cli/chat/daemon_chat.rb', line 73

def on_tool_call(&block)
  @on_tool_call = block
end

#on_tool_result(&block) ⇒ Object

Stores a tool_result callback invoked after each local tool execution.



78
79
80
# File 'lib/legion/cli/chat/daemon_chat.rb', line 78

def on_tool_result(&block)
  @on_tool_result = block
end

#reset_messages!Object

Clears all conversation history (used by /clear slash command).



89
90
91
# File 'lib/legion/cli/chat/daemon_chat.rb', line 89

def reset_messages!
  @messages = []
end

#with_instructions(prompt) ⇒ Object

Sets the system prompt. Returns self for chaining.



54
55
56
57
# File 'lib/legion/cli/chat/daemon_chat.rb', line 54

def with_instructions(prompt)
  @instructions = prompt
  self
end

#with_model(model_id) ⇒ Object

Switches the active model. Returns self for chaining.



67
68
69
70
# File 'lib/legion/cli/chat/daemon_chat.rb', line 67

def with_model(model_id)
  @model = ModelInfo.new(id: model_id)
  self
end

#with_tools(*tools) ⇒ Object

Registers tool classes for local execution and schema forwarding. Returns self for chaining.



61
62
63
64
# File 'lib/legion/cli/chat/daemon_chat.rb', line 61

def with_tools(*tools)
  @tools = tools.flatten
  self
end