module AiAgent
Constants
- AgentResult
Public Instance Methods
Source
# File lib/ai/agent.rb, line 45 def build_agent_prompt(question:, context_lines:, chat_history_lines:, empty_prompt_channel_lines: [], episode_context_lines: [], asker:, channel:, profile: nil) question = question.to_s.strip parts = [] profile_prompt = render_profile_prompt(profile) if profile_prompt && !profile_prompt.empty? parts << profile_prompt parts << "" end if episode_context_lines.any? parts << "ATHF episode context from Fandom (use only if relevant):" parts.concat(episode_context_lines) parts << "" end if empty_prompt_channel_lines.any? parts << "Recent messages in #{channel} (oldest to newest; use for context):" parts.concat(empty_prompt_channel_lines) parts << "" end if chat_history_lines.any? parts << "Recent !ai exchanges in #{channel} (use only if helpful for this question):" parts.concat(chat_history_lines) parts << "" end if context_lines.any? parts << "Recent IRC chat from #{channel} (use only lines that help answer the question; ignore unrelated chatter):" parts.concat(context_lines) parts << "" end parts << "Question from #{asker}: #{question}" AiGuard.guard_prompt(parts.join("\n")) end
Source
# File lib/ai/agent.rb, line 114 def default_runner(prompt, model) CursorAgentRunner.capture3( "cursor-agent", "--model=#{model}", "--print", "--output-format", "json", "--mode", "ask", "--sandbox", "enabled", prompt.to_s, lane: :chat ) end
Source
# File lib/ai/agent.rb, line 84 def parse_agent_json(stdout, stderr, status, model: nil) json_line = stdout.to_s.lines.map(&:strip).reject(&:empty?).last raise JSON::ParserError, "empty agent output" if json_line.nil? || json_line.empty? json = JSON.parse(json_line) usage = json["usage"] || {} AgentResult.new( success: status.success? && json["is_error"] != true, text: json["result"].to_s.strip, model: model, input_tokens: usage["inputTokens"].to_i, output_tokens: usage["outputTokens"].to_i, duration_ms: json["duration_ms"].to_i, error: nil ) rescue JSON::ParserError AgentResult.new( success: false, text: stdout.to_s.strip, model: model, input_tokens: 0, output_tokens: 0, duration_ms: 0, error: CursorAgentRunner.friendly_error( stderr.to_s.strip.empty? ? stdout.to_s.strip : stderr.to_s.strip ) ) end
Source
# File lib/ai/agent.rb, line 34 def render_profile_prompt(profile) case profile when nil nil when CharacterProfile profile.render_prompt else profile.to_s.strip end end
Source
# File lib/ai/agent.rb, line 127 def run_agent(prompt, model:, runner: method(:default_runner)) stdout, stderr, status = runner.call(prompt, model) result = parse_agent_json(stdout, stderr, status, model: model) unless result.success? result.text = CursorAgentRunner.failure_message( stdout: result.text, stderr: result.error, fallback: "AI request failed" ) end result end