Module: Brainiac::Plugins::Fizzy::Summarize

Defined in:
lib/brainiac/plugins/fizzy/handlers/summarize.rb

Overview

Handles re-dispatch summarize sessions and fallback comment posting. Extracted from Hooks to keep module length manageable.

Constant Summary collapse

CLOCK_SKEW_BUFFER =

Check if the agent posted a comment on the card since a given time. If no since is provided, checks for any agent comment (legacy behavior). Subtracts a 30s buffer from since to account for clock skew between the local server and the Fizzy API.

30

Class Method Summary collapse

Class Method Details

.agent_commented_on_card?(card_number, agent_name, repo_path:, since: nil) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/brainiac/plugins/fizzy/handlers/summarize.rb', line 51

def agent_commented_on_card?(card_number, agent_name, repo_path:, since: nil)
  env = Helpers.fizzy_env_for(agent_name)
  output = run_cmd("fizzy", "comment", "list", "--card", card_number.to_s, chdir: repo_path, env: env)
  comments = JSON.parse(output)["data"] || []
  agent_display = agent_display_name(agent_name)

  agent_comments = comments.select { |c| c["creator_name"]&.downcase == agent_display.downcase }
  return agent_comments.any? unless since

  buffered_since = since - CLOCK_SKEW_BUFFER
  agent_comments.any? do |c|
    comment_time = c["created_at"] && Time.parse(c["created_at"])
    comment_time && comment_time > buffered_since
  end
rescue StandardError
  false
end

.dispatch_summarize_session(ctx) ⇒ Object

Re-dispatch an agent to post a summary comment when it completed work but didn't comment on the card. Fires async with a 60s timeout. If this session also fails to comment, posts a minimal fallback.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/brainiac/plugins/fizzy/handlers/summarize.rb', line 15

def dispatch_summarize_session(ctx)
  card_number = ctx[:card_number]
  agent_name = ctx[:agent_name]
  project_config = ctx[:project_config]
  repo_path = project_config["repo_path"]
  session_started_at = ctx[:source_context]&.dig(:dispatched_at)

  map = load_work_item_map
  work_item = find_work_item(map, card_number)

  branch = work_item&.dig("branch") || "unknown"
  card_title = work_item&.dig("title") || ctx[:source_context]&.dig(:card_title) || "untitled"
  worktree_path = work_item&.dig("worktree") || repo_path

  if defined?(LOG)
    LOG.info "[Fizzy] Agent #{agent_name} completed card ##{card_number} without commenting — " \
             "dispatching summarize session"
  end

  pid, log_file = dispatch_summarize_agent(card_number, card_title, branch, agent_name,
                                           project_config, worktree_path)
  register_session("card-#{card_number}-summarize", pid, log_file: log_file, agent_name: agent_name)

  monitor_summarize_session(pid, card_number, agent_name, branch, repo_path, session_started_at,
                            project_config)
rescue StandardError => e
  LOG.error "[Fizzy] Failed to dispatch summarize session for card ##{card_number}: #{e.message}" if defined?(LOG)
  post_fallback_comment(card_number, work_item&.dig("branch") || "unknown", agent_name, project_config)
end

.post_fallback_comment(card_number, branch, agent_name, project_config) ⇒ Object

Post a minimal server-generated comment when all else fails.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/brainiac/plugins/fizzy/handlers/summarize.rb', line 70

def post_fallback_comment(card_number, branch, agent_name, project_config)
  repo_path = project_config["repo_path"]
  env = Helpers.fizzy_env_for(agent_name)

  pr_url = Helpers.send(:detect_pr_url, branch, project_config)
  body = "<p>✅ Work completed on this card.</p>"
  body += "<p><a href=\"#{pr_url}\">View PR</a></p>" if pr_url
  body += "<p><strong>Branch:</strong> <code>#{branch}</code></p>"

  run_cmd("fizzy", "comment", "create", "--card", card_number.to_s, "--body", body,
          chdir: repo_path, env: env)
  LOG.info "[Fizzy] Posted fallback comment on card ##{card_number}" if defined?(LOG)
rescue StandardError => e
  LOG.error "[Fizzy] Failed to post fallback comment on card ##{card_number}: #{e.message}" if defined?(LOG)
end