Module: Brainiac::Plugins::Zoho::Triage

Defined in:
lib/brainiac/plugins/zoho/triage.rb

Constant Summary collapse

PROMPT_TEMPLATE =
<<~PROMPT
  You are triaging a support email. Decide whether this email needs a card or not.

  ## Email
  **From:** {{FROM}}
  **To:** {{TO}}
  **Subject:** {{SUBJECT}}
  **Body:**
  ```
  {{BODY}}
  ```

  ## Decision Criteria
  **Needs a card** (something is broken, a bug report, a feature request, a workflow issue):
  - Create a card with a clear title summarizing the issue
  - Tag with `support` plus a project tag if you can identify the relevant project
  - Assign to the appropriate agent

  **Does NOT need a card** (account questions, password resets, general inquiries, spam, marketing):
  - Just explain why briefly

  **Borderline** (you're not sure):
  - Mark as borderline and explain why — a human will decide

  ## Project Tags (use the tag name, not the ID)
  {{PROJECT_TAGS}}

  ## Agent Assignment
  {{AGENT_ASSIGNMENT}}

  ## Response Format
  Write ONLY valid JSON to stdout (no markdown, no explanation outside the JSON):

  For "needs a card":
  ```json
  {
    "decision": "create_card",
    "title": "Brief descriptive title for the card",
    "description": "HTML description with relevant details from the email",
    "project_tag": "project-tag-name or null",
    "assign_to": "agent-name from the assignment rules above"
  }
  ```

  For "does not need a card":
  ```json
  {
    "decision": "skip",
    "reason": "Brief explanation of why no card is needed"
  }
  ```

  For "borderline":
  ```json
  {
    "decision": "borderline",
    "reason": "Why you're unsure — what makes this ambiguous"
  }
  ```
PROMPT

Class Method Summary collapse

Class Method Details

.dispatch(email, rule) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/brainiac/plugins/zoho/triage.rb', line 69

def dispatch(email, rule)
  agent_name = rule["dispatch_agent"]
  timestamp = Time.now.strftime("%Y%m%d-%H%M%S")
  triage_dir = File.join(ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac")), "tmp", "zoho", "triage")
  FileUtils.mkdir_p(triage_dir)

  response_file = File.join(triage_dir, "triage-#{timestamp}.json")
  log_file = File.join(triage_dir, "triage-#{timestamp}.log")
  prompt_file = write_prompt(email, response_file, timestamp, triage_dir)

  agent_key = agent_name.downcase.gsub(/[^a-z0-9-]/, "-")
  project_config = default_project_config
  resolved = resolve_project_cli_config(project_config || {})

  cmd = [resolved["agent_cli"]]
  cmd.push("--agent", agent_key)
  cmd.concat(resolved["agent_cli_args"].split)

  spawn_env = {}
  agent_env = agent_env_for(agent_name)
  spawn_env.merge!(agent_env) unless agent_env.empty?

  work_dir = project_config ? project_config["repo_path"] : Dir.pwd

  LOG.info "[Zoho:Triage] Dispatching #{agent_name} for: #{email["subject"]}"
  LOG.info "[Zoho:Triage] Command: #{cmd.join(" ")}"

  pid = spawn(spawn_env, *cmd,
              chdir: work_dir, in: prompt_file,
              out: [log_file, "w"], err: %i[child out])

  monitor(pid, response_file, log_file, prompt_file, email, rule)
  pid
end