brainiac 0.4.6 → 0.5.0

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: 31251e710a5798457b27ce451afac8416c61581a3c5e443766baac9523ecc2b6
4
- data.tar.gz: 78519e9435feed9506750c3556f4ea9b2ea31a34bdc25bf1a1282cb9fb7f27a5
3
+ metadata.gz: 4f17a8d317d56d8048d7f894c2c60832dd31db1feaa38a3692e566e995c54683
4
+ data.tar.gz: 8f9d3e551d2a6fb4e0db4bb0514a2f37ea484cabdc18e9a8232d2fc509c7aa05
5
5
  SHA512:
6
- metadata.gz: e57de5ea8715a63a478bfba62af31f691f9f89948dfa82dd8d1a2cd1a4a81b9c743a6edd316c02a8ee00ede53893729dc1f955f43b1736fc339890a01cb6ed15
7
- data.tar.gz: 7b3a815f89bbdad976f5db659d4e0f82ae2b0862a29814ed4394a713c94a25ebe3cf7f8b705197163ddc13f4166ce54c729435b8ddbeb63fea690a7a12b83390
6
+ metadata.gz: 6f97132829338b279fe162668705141ba70de45fbffcbc8524b3a56d1c7dd3c9143664643001b41c0c60ef9290ddfef847f7b60e01d2465ea5aec48a3cf41d9a
7
+ data.tar.gz: cc521e5d9ceb8c5f578b049c6b11f3b48b6f5371bbb288d0fab54f9798564d5e6940ffb7327784f3962f4f2ba858ddaee6229aa1ae304b73aec4b1f48edb4d93
data/README.md CHANGED
@@ -13,6 +13,7 @@ brainiac install fizzy # Card management
13
13
  brainiac install discord # Conversational bots
14
14
  brainiac install github # PR reviews, CI notifications
15
15
  brainiac install zoho # Email notifications and triage
16
+ brainiac install featureparity # Agents take work from FeatureParity
16
17
  ```
17
18
 
18
19
  Because each agent maintains its own unique persona and configuration, you can deploy a specialized team—all managed through `~/.brainiac/agents.json`. Project tracking is handled via `~/.brainiac/projects.json`, and because the system reloads configurations dynamically, you can iterate on your agent workflows in real-time without ever needing a restart.
@@ -34,6 +35,7 @@ Each plugin adds its own webhook routes and event handling. Here's what's availa
34
35
  | GitHub | Workflow run | `brainiac-github` | Notifies on CI failures and deploys |
35
36
  | Discord | @bot mention | `brainiac-discord` | Each agent has its own bot — @mention routes directly, conversational |
36
37
  | Zoho Mail | Incoming email | `brainiac-zoho` | Rule-based matching, notifies via Discord or triages to card |
38
+ | FeatureParity | Start work / agent tagged | `brainiac-featureparity` | Picked agent implements the requirement, or answers the comment, in an `fp-<slug>` worktree |
37
39
 
38
40
  ### Inline Tags
39
41
 
@@ -331,6 +333,16 @@ A provider without `readonly_args` can't be used read-only; the call fails inste
331
333
 
332
334
  `claude` is the only `stream_format` so far. Lines that aren't JSON pass through unchanged.
333
335
 
336
+ `subagents` is optional and writes the "Subagents" section of the agent's prompt. `tool` is the CLI's subagent tool, `usage` lines become how-to bullets, and `models` maps each job to a cheaper model. The session's own model (the `[fable]`/`[opus]` tag) stays the orchestrator: it plans, decides and reviews, and hands research and well-specified labor down a tier. A provider without the block gets no Subagents section, so an agent is never told to call a tool its CLI doesn't have.
337
+
338
+ ```json
339
+ "subagents": {
340
+ "tool": "Agent",
341
+ "models": { "research and file sweeps": "haiku", "well-specified implementation": "sonnet" },
342
+ "usage": ["Pass `model` (`haiku`, `sonnet`, `opus`, `fable`) to pick the tier. Omit it and the subagent runs on your model."]
343
+ }
344
+ ```
345
+
334
346
  Which provider runs is decided in this order: a `[cli:X]` tag, the agent's `cli_provider` in `agents.json`, the project's `cli_provider`, then `default_cli_provider` in `brainiac.json`. With none of those set, brainiac uses the `AGENT_CLI` env var, or kiro-cli.
335
347
 
336
348
  #### Asking an agent from a plugin
@@ -396,6 +408,7 @@ brainiac install discord # Discord bots
396
408
  brainiac install fizzy # Fizzy card management
397
409
  brainiac install github # GitHub webhooks
398
410
  brainiac install zoho # Zoho Mail
411
+ brainiac install featureparity # FeatureParity requirements
399
412
  ```
400
413
 
401
414
  Each plugin has its own setup command (e.g. `brainiac github setup`) and documentation. See [Plugins](#plugins-gem-based-handlers) for details.
@@ -407,6 +420,7 @@ Each plugin provides its own webhook endpoint. Point your tools at your ngrok UR
407
420
  - **Fizzy:** `https://your-ngrok.ngrok-free.app/fizzy/<board-key>` (see `brainiac fizzy setup`)
408
421
  - **GitHub:** `https://your-ngrok.ngrok-free.app/github` (see `brainiac github setup`)
409
422
  - **Zoho:** `https://your-ngrok.ngrok-free.app/zoho` (see `brainiac zoho setup`)
423
+ - **FeatureParity:** `https://your-ngrok.ngrok-free.app/featureparity`, set as each agent's wake-up address in FeatureParity (see `brainiac featureparity setup`)
410
424
 
411
425
  #### 8. Start
412
426
 
@@ -1282,7 +1296,7 @@ The `Brainiac::Plugins` namespace is defined in `lib/brainiac.rb`. Plugin module
1282
1296
  | github | `brainiac-github` | GitHub webhooks — PR reviews, PR comments, PR merges, CI workflow notifications, deploy tracking |
1283
1297
  | zoho | `brainiac-zoho` | Zoho Mail webhooks — rule-based email notifications, AI triage, OAuth for content fetching |
1284
1298
  | basecamp | `brainiac-basecamp` | Basecamp epic orchestration — card tables, review gates, epic branches |
1285
- | featureparity | `brainiac-featureparity` | FeatureParity integration for Brainiac agents |
1299
+ | featureparity | `brainiac-featureparity` | FeatureParity — starts the agent picked for a requirement, answers comments that tag it, writes missing tests, reworks rejected proposals; verifies signed deliveries |
1286
1300
 
1287
1301
  ### Backward Compatibility
1288
1302
 
@@ -35,7 +35,8 @@ def load_cli_provider(provider_name)
35
35
  %w[prompt_flag readonly_args list_models_command resume_flag resume_args resume_id_flag new_session_id_flag
36
36
  session_list_command session_id_field session_directory_field session_updated_field
37
37
  session_list_path session_dir output_last_message_flag cwd_flag config_override_flag
38
- effort_config_key effort_map title_flag heaviness_probe settings_model_cmd stream_args stream_format].each do |key|
38
+ effort_config_key effort_map title_flag heaviness_probe settings_model_cmd stream_args stream_format
39
+ subagents].each do |key|
39
40
  next unless raw[key]
40
41
  next if raw[key].respond_to?(:empty?) && raw[key].empty?
41
42
 
@@ -935,7 +936,7 @@ def run_agent(prompt, project_config:, chdir: nil, log_name: "agent", model: nil
935
936
  log_file = File.join(chdir, "tmp/agent-#{log_name}-#{timestamp}.log")
936
937
  FileUtils.mkdir_p(File.dirname(log_file))
937
938
 
938
- prompt_file = write_agent_prompt_file(prompt, log_name, timestamp)
939
+ prompt_file = write_agent_prompt_file(fill_subagent_prompt(prompt, resolved, model: model), log_name, timestamp)
939
940
  output_file = prepare_output_file(resolved, log_name, timestamp)
940
941
 
941
942
  cmd = build_agent_cmd(resolved, agent_config_name: agent_config_name, model: model, effort: effort,
@@ -112,34 +112,7 @@ PROMPT_CORE = <<~PROMPT
112
112
  If the task is ambiguous or you're uncertain about requirements, ask before starting.
113
113
  If you're 90% sure, proceed. If you're 60% sure, ask.
114
114
 
115
- ## Subagents (Delegating Work)
116
- You have access to the `use_subagent` tool, which spawns independent child agents that run
117
- in parallel and report back. Use them to preserve your context window for implementation.
118
-
119
- **When to use subagents:**
120
- - Cross-repo investigation ("how does opszilla-android call this endpoint?")
121
- - Heavy codebase research before implementation (reading many files you won't need later)
122
- - Parallel tasks that don't depend on each other
123
- - When your context is getting heavy and you need to offload research
124
-
125
- **When NOT to use subagents:**
126
- - Simple, directed lookups (one file, one function, one grep)
127
- - Tasks that require your brain context, persona, or memory
128
- - Posting comments or external communication (only you can do that)
129
-
130
- **How to use them effectively:**
131
- - Be specific in your query — tell the subagent exactly what to find and where to look
132
- - Include relevant file paths and repo locations in the query
133
- - Use `relevant_context` to pass information the subagent needs
134
- - You can specify `agent_name` to use a specialized agent (e.g., "robin" for Android research)
135
- - Run `ListAgents` first if you want to see available specialized agents
136
- - Up to 4 subagents can run in parallel
137
- - To discover project locations for cross-repo work, run: `brainiac list`
138
-
139
- **Limitations:** Subagents don't get your brain context, persona, or memory.
140
- They can read files and run commands, but cannot post to Discord, GitHub, or other channels.
141
- They're excellent researchers — use them as such.
142
-
115
+ {{SUBAGENTS}}
143
116
  ## Image Reading Limits
144
117
  Read at most 4-5 images per tool call. Summarize what you saw before reading more.
145
118
  Loading too many images at once can exceed the API request size limit and crash your session.
@@ -251,6 +224,66 @@ def populate_prompt_vars(vars, agent_name:, board_key:)
251
224
  vars["AGENT_ROSTER"] ||= roster_lines
252
225
  end
253
226
 
227
+ # The Subagents section of PROMPT_CORE, built from the provider's `subagents` block in
228
+ # cli-providers/<name>.json. Rendered at dispatch time (run_agent) because that's where the
229
+ # provider is resolved. Providers without the block get no section: telling an agent to call
230
+ # a tool its CLI doesn't have is worse than saying nothing.
231
+ #
232
+ # "subagents": {
233
+ # "tool": "Agent",
234
+ # "models": { "research": "haiku", "implement": "sonnet" },
235
+ # "usage": ["Pass `model` to pick the tier."]
236
+ # }
237
+ def subagent_prompt_section(subagents, model: nil)
238
+ return "" unless subagents.is_a?(Hash) && subagents["tool"]
239
+
240
+ lines = ["## Subagents (Delegating Work)"]
241
+ lines << "You have the `#{subagents["tool"]}` tool, which spawns child agents that run in parallel and report back."
242
+ lines << "Their file dumps stay out of your context, so long sessions stay lean."
243
+ lines << ""
244
+ lines << "**Delegate when the work is big, not because of the channel.** A card or a Discord request that"
245
+ lines << "spans many files or repos is worth delegating. A five-tool-call answer is not: each subagent"
246
+ lines << "starts cold and rereads everything, so it costs more than doing it yourself."
247
+ lines << ""
248
+ lines << "**Good jobs for subagents:** cross-repo investigation, sweeping many files you won't need later,"
249
+ lines << "independent tasks that can run in parallel, and mechanical edits you've already specified exactly."
250
+ lines << ""
251
+ lines << "**Keep for yourself:** design and architecture decisions, judgment calls, anything that needs your"
252
+ lines << "brain context, persona, or memory, final review of the change, and all external communication."
253
+ lines << "Subagents gather facts and do well-specified labor; they don't make the call. If a subagent's"
254
+ lines << "report drives a decision, verify the part that matters before acting on it."
255
+ append_subagent_models(lines, subagents["models"], model)
256
+ lines << ""
257
+ lines << "**How to use them:**"
258
+ Array(subagents["usage"]).each { |line| lines << "- #{line}" }
259
+ lines << "- Brief each subagent like a peer: the goal, exact files and repos, and what you've ruled out."
260
+ lines << "- Run `brainiac list` to find project paths for cross-repo work."
261
+ lines << ""
262
+ lines << "**Limitations:** Subagents don't get your brain context, persona, or memory, and can't post to"
263
+ lines << "Discord, GitHub, or other channels."
264
+ "#{lines.join("\n")}\n\n"
265
+ end
266
+
267
+ # Model tiers: you stay on the session's model (the [fable]/[opus] tag) for planning and the
268
+ # final word; cheaper tiers take the labor.
269
+ def append_subagent_models(lines, models, model)
270
+ return unless models.is_a?(Hash) && !models.empty?
271
+
272
+ lines << ""
273
+ lines << "**Model tiers:** You#{" (#{model})" if model} are the orchestrator. Pick a cheaper model for each subagent's job:"
274
+ models.each { |job, tier| lines << "- #{job}: `#{tier}`" }
275
+ lines << "Never hand a design or review decision down a tier to save money; that's the expensive part you're here for."
276
+ end
277
+
278
+ # Fill the {{SUBAGENTS}} slot left in PROMPT_CORE. A no-op for prompts that don't have it
279
+ # (resume prompts, cron prompts).
280
+ def fill_subagent_prompt(prompt, resolved, model: nil)
281
+ return prompt unless prompt.include?("{{SUBAGENTS}}")
282
+
283
+ section = subagent_prompt_section(resolved["subagents"], model: model)
284
+ prompt.sub("{{SUBAGENTS}}\n", section).sub("{{SUBAGENTS}}", section)
285
+ end
286
+
254
287
  # Lean prompt for resumed sessions. The previous session already has the full context
255
288
  # (role, persona, knowledge, core instructions, channel prompts). We only send the new
256
289
  # comment and any fresh card context so the agent knows what changed.
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Brainiac
4
4
  # @return [String] the current gem version
5
- VERSION = "0.4.6"
5
+ VERSION = "0.5.0"
6
6
  end
@@ -28,5 +28,14 @@
28
28
  "comment": "Optional. Lets brainiac record how 'heavy' a finished session was (context window usage + credits) in the durable session history. type selects the probe strategy; db_path points at the provider's local usage store. Omit this block to record timing/identity only.",
29
29
  "type": "kiro_sqlite",
30
30
  "db_path": "~/.local/share/kiro-cli/data.sqlite3"
31
+ },
32
+ "subagents": {
33
+ "comment": "Optional. Renders the Subagents section of the agent prompt. tool is the CLI's subagent tool; usage lines are appended as how-to bullets; models (job => tier) tells the agent which cheaper model to hand each job. Omit the block for CLIs with no subagent tool.",
34
+ "tool": "use_subagent",
35
+ "usage": [
36
+ "Use `relevant_context` to pass information the subagent needs.",
37
+ "Set `agent_name` for a specialized agent (e.g. \"robin\" for Android research); run `ListAgents` to see them.",
38
+ "Up to 4 subagents can run in parallel."
39
+ ]
31
40
  }
32
41
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis