brainiac-discord 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5edd0068ecc82d20372d269791ff8e750fcec8106f4adcc99fdef3c252e03ada
4
- data.tar.gz: b30c999fc3497d7608463975a3d9f4a8c09b135e3d7bc9da1099b6a5306594c2
3
+ metadata.gz: 38d2ec15ff61cbaaac7cc9c0ad3d090950c62e081bd353654ed48c70b982cc97
4
+ data.tar.gz: 167309f8288bbb17d8bc4f1dff9b3c85765e5bede1ec6f786aca076bc27fe705
5
5
  SHA512:
6
- metadata.gz: f65f1deefed415c9b3a038162ad6c59714f2677c9ce8ec201e880ce9ae9b159571cb4910a7515268d0e09ad262e69011ea6f7b1c40471bc846ea5f84fa74d366
7
- data.tar.gz: 23ba4bda9f6eb4e9797e6724ad57f12908da3176f116eacdaa11f8b5c3462647180cb8c0a1a1766c00ac12de49c2216e8fdf84da9ad719dcde0bae42307851f9
6
+ metadata.gz: b34ea4880a65b80733996be50b6609aa59a2327f021ffe1d140e4475b9ee1b259322efb400998511b164677aa81f065d3975804669d25154822ab1db5d8c4840
7
+ data.tar.gz: 5d661b2560f6ba4bc25a4b5a2b04a2840f9710da16595f551b8de7197346b47769f82495e414b3fb076b28ed5bc8f58e16a918253333cc6f0bb08ef40216a141
@@ -10,8 +10,8 @@ module Brainiac
10
10
  #
11
11
  # Handles incoming messages: authorization, cross-agent routing, project detection,
12
12
  # worktree management, prompt building, agent spawning, and response monitoring.
13
- module Message
14
- class << self
13
+ module Message # rubocop:disable Metrics/ModuleLength
14
+ class << self # rubocop:disable Metrics/ClassLength
15
15
  def handle(message, agent_key, bot_token, bot_user_id)
16
16
  channel_id = message["channel_id"]
17
17
  message_id = message["id"]
@@ -101,9 +101,9 @@ module Brainiac
101
101
  content.match?(/<@&#{Regexp.escape(role_id)}>/)
102
102
  end
103
103
 
104
- # Check if another agent bot is explicitly mentioned in this message.
105
- # When a user @mentions a specific agent, thread participants who weren't
106
- # mentioned should stay silent — no intent check needed.
104
+ # Check if another agent bot or a known human user is explicitly mentioned
105
+ # in this message. When a user @mentions someone specific, thread participants
106
+ # who weren't mentioned should stay silent — no intent check needed.
107
107
  def other_agent_mentioned?(mentions, content, agent_key)
108
108
  mention_roles = []
109
109
 
@@ -118,7 +118,18 @@ module Brainiac
118
118
  mention_roles << role_id if role_id
119
119
  end
120
120
 
121
- mention_roles.any? { |rid| content.match?(/<@&#{Regexp.escape(rid)}>/) }
121
+ return true if mention_roles.any? { |rid| content.match?(/<@&#{Regexp.escape(rid)}>/) }
122
+
123
+ # Also check human user_mappings — if a human was explicitly @mentioned,
124
+ # thread participants should stand down (message directed at someone specific)
125
+ Config.user_mappings.each_value do |discord_id|
126
+ next unless discord_id
127
+
128
+ return true if mentions.any? { |m| m["id"].to_s == discord_id.to_s } ||
129
+ content.match?(/<@!?#{Regexp.escape(discord_id.to_s)}>/)
130
+ end
131
+
132
+ false
122
133
  end
123
134
 
124
135
  def validate_cross_agent_dispatch(sender_agent_key, agent_key, mentioned, content, channel_id)
@@ -487,7 +498,7 @@ module Brainiac
487
498
  thread_root_context = build_thread_root_context(is_thread, root_message, parent_channel_id, channel_id, bot_token)
488
499
  brain_context = build_brain_context(agent_name: agent_name, card_title: clean_content, comment_body: clean_content)
489
500
 
490
- should_resume, thread_worktree_path, thread_cli_provider, thread_model, thread_effort = manage_worktree(
501
+ should_resume, thread_worktree_path, thread_cli_provider, thread_model, thread_effort, thread_map_key = manage_worktree(
491
502
  agent_key: agent_key, agent_name: agent_name, channel_id: channel_id, message_id: message_id,
492
503
  is_thread: is_thread, is_dm: is_dm, project_config: project_config, clean_content: clean_content,
493
504
  chat_mode: chat_mode, bot_token: bot_token
@@ -511,6 +522,10 @@ module Brainiac
511
522
  clean_content, project_config, thread_model, thread_effort, thread_cli_provider
512
523
  )
513
524
 
525
+ persist_overrides(thread_map_key, clean_content, project_config,
526
+ cli_provider: cli_provider_override, model: model, effort: effort,
527
+ prev_cli_provider: thread_cli_provider, prev_model: thread_model, prev_effort: thread_effort)
528
+
514
529
  meta_file = File.join(Delivery::DRAFT_DIR, "#{response_basename}.meta.json")
515
530
  write_meta(meta_file,
516
531
  channel_id: channel_id, message_id: message_id, agent_key: agent_key,
@@ -582,6 +597,55 @@ module Brainiac
582
597
  [model, effort, cli_provider]
583
598
  end
584
599
 
600
+ # Persist inline overrides to the thread map (and work item map if a work item exists).
601
+ # Only writes when a new inline tag was detected (differs from previously stored values).
602
+ def persist_overrides(thread_map_key, clean_content, project_config,
603
+ cli_provider:, model:, effort:,
604
+ prev_cli_provider:, prev_model:, prev_effort:)
605
+ return unless thread_map_key
606
+
607
+ inline_cli = detect_cli_provider(text: clean_content)
608
+ inline_model = explicit_model_tag?(clean_content, project_config) ? model : nil
609
+ inline_effort = clean_content.match?(/\[effort:\w+\]/i) ? effort : nil
610
+
611
+ return unless inline_cli || inline_model || inline_effort
612
+
613
+ changed = (inline_cli && inline_cli != prev_cli_provider) ||
614
+ (inline_model && inline_model != prev_model) ||
615
+ (inline_effort && inline_effort != prev_effort)
616
+ return unless changed
617
+
618
+ # Update thread map entry with new overrides
619
+ Config.thread_map_mutex.synchronize do
620
+ map = Config.load_thread_map
621
+ entry = map[thread_map_key]
622
+ if entry
623
+ entry["cli_provider"] = cli_provider if inline_cli
624
+ entry["model"] = model if inline_model
625
+ entry["effort"] = effort if inline_effort
626
+ Config.save_thread_map(map)
627
+ end
628
+ end
629
+
630
+ # Also persist to core work item map (if a work item exists for this branch)
631
+ branch = Config.thread_map_mutex.synchronize do
632
+ Config.load_thread_map.dig(thread_map_key, "branch")
633
+ end
634
+ if branch && defined?(resolve_work_item_overrides)
635
+ resolve_work_item_overrides(
636
+ branch: branch,
637
+ inline_cli_provider: inline_cli,
638
+ inline_model: inline_model,
639
+ inline_effort: inline_effort
640
+ )
641
+ end
642
+
643
+ return unless defined?(LOG)
644
+
645
+ LOG.info "[Discord] Persisted overrides for #{thread_map_key}: " \
646
+ "cli=#{cli_provider}, model=#{model}, effort=#{effort}"
647
+ end
648
+
585
649
  def explicit_model_tag?(clean_content, project_config)
586
650
  return false unless project_config
587
651
 
@@ -651,7 +715,7 @@ module Brainiac
651
715
  create_chat_mode_dir(agent_key, agent_name, effective_thread_id, project_config, clean_content, thread_map_key)
652
716
  end
653
717
 
654
- [should_resume, thread_worktree_path, thread_cli_provider, thread_model, thread_effort]
718
+ [should_resume, thread_worktree_path, thread_cli_provider, thread_model, thread_effort, thread_map_key]
655
719
  end
656
720
 
657
721
  def pre_create_thread(agent_key, agent_name, channel_id, message_id, clean_content, bot_token)
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Discord
6
- VERSION = "0.0.5"
6
+ VERSION = "0.0.7"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac-discord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis