brainiac 0.4.5 → 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 +4 -4
- data/README.md +15 -1
- data/lib/brainiac/helpers.rb +3 -2
- data/lib/brainiac/intent.rb +48 -43
- data/lib/brainiac/prompts.rb +61 -28
- data/lib/brainiac/version.rb +1 -1
- data/templates/cli-providers/kiro.json.example +9 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4f17a8d317d56d8048d7f894c2c60832dd31db1feaa38a3692e566e995c54683
|
|
4
|
+
data.tar.gz: 8f9d3e551d2a6fb4e0db4bb0514a2f37ea484cabdc18e9a8232d2fc509c7aa05
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
|
data/lib/brainiac/helpers.rb
CHANGED
|
@@ -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
|
|
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,
|
data/lib/brainiac/intent.rb
CHANGED
|
@@ -142,7 +142,7 @@ def check_intent(message, agent_name:, channel: "conversation", context: nil)
|
|
|
142
142
|
# Deterministic pre-check: if the message explicitly names another agent
|
|
143
143
|
# and does NOT name this agent, skip without consulting the LLM.
|
|
144
144
|
# This handles the common case of "Effie, tell me another" when checking Galen.
|
|
145
|
-
if intent_names_other_agent?(message, agent_name)
|
|
145
|
+
if intent_names_other_agent?(message, agent_name, context)
|
|
146
146
|
LOG.info "[Intent] Deterministic skip for #{agent_name} — message addresses another agent"
|
|
147
147
|
return false
|
|
148
148
|
end
|
|
@@ -327,11 +327,16 @@ end
|
|
|
327
327
|
# - "Was Effie nice to you?" (asking about Effie)
|
|
328
328
|
# - "I liked what Effie said" (referencing Effie)
|
|
329
329
|
#
|
|
330
|
+
# Agents running on other machines aren't in AGENT_REGISTRY, so bot authors seen in
|
|
331
|
+
# the conversation context ("Name [bot]: ...") count as agents too.
|
|
332
|
+
#
|
|
330
333
|
# @param message [String] The message text
|
|
331
334
|
# @param agent_name [String] The agent being evaluated
|
|
335
|
+
# @param context [String, nil] Conversation history
|
|
332
336
|
# @return [Boolean] true if another agent is directly addressed and this one isn't
|
|
333
|
-
def intent_names_other_agent?(message, agent_name)
|
|
334
|
-
|
|
337
|
+
def intent_names_other_agent?(message, agent_name, context = nil)
|
|
338
|
+
names = intent_agent_display_names.keys | context_bot_names(context).map(&:downcase)
|
|
339
|
+
return false if names.empty?
|
|
335
340
|
|
|
336
341
|
msg_lower = message.downcase.strip
|
|
337
342
|
agent_lower = agent_name.downcase
|
|
@@ -340,9 +345,7 @@ def intent_names_other_agent?(message, agent_name)
|
|
|
340
345
|
return false if directly_addressed_to?(msg_lower, agent_lower)
|
|
341
346
|
|
|
342
347
|
# Check if any OTHER agent is directly addressed (not merely mentioned)
|
|
343
|
-
|
|
344
|
-
display = entry.is_a?(Hash) ? (entry["display_name"] || key.capitalize) : key.capitalize
|
|
345
|
-
other_lower = display.downcase
|
|
348
|
+
names.each do |other_lower|
|
|
346
349
|
next if other_lower == agent_lower
|
|
347
350
|
next unless msg_lower.match?(/\b#{Regexp.escape(other_lower)}\b/)
|
|
348
351
|
|
|
@@ -403,64 +406,66 @@ def build_intent_agent_roster(agent_name)
|
|
|
403
406
|
names.join(", ")
|
|
404
407
|
end
|
|
405
408
|
|
|
409
|
+
# Map of lowercased agent display name => display name, from the local AGENT_REGISTRY.
|
|
410
|
+
def intent_agent_display_names
|
|
411
|
+
return {} unless defined?(AGENT_REGISTRY) && !AGENT_REGISTRY.empty?
|
|
412
|
+
|
|
413
|
+
AGENT_REGISTRY.each_with_object({}) do |(key, entry), names|
|
|
414
|
+
display = entry.is_a?(Hash) ? (entry["display_name"] || key.capitalize) : key.capitalize
|
|
415
|
+
names[display.downcase] = display
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# Parse a context line ("username: message", or "username [bot]: message" when the
|
|
420
|
+
# plugin knows the author is a bot). Returns [username, bot?] or nil.
|
|
421
|
+
def parse_context_author(line)
|
|
422
|
+
match = line.match(/\A(\S+?)( \[bot\])?:\s/)
|
|
423
|
+
match && [match[1], !match[2].nil?]
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
# Usernames of every bot author in the context.
|
|
427
|
+
def context_bot_names(context)
|
|
428
|
+
return [] if context.nil?
|
|
429
|
+
|
|
430
|
+
context.lines.filter_map do |line|
|
|
431
|
+
username, bot = parse_context_author(line)
|
|
432
|
+
username if bot
|
|
433
|
+
end.uniq
|
|
434
|
+
end
|
|
435
|
+
|
|
406
436
|
# Detect the last agent to respond in the conversation context.
|
|
407
437
|
# Returns a prompt-friendly string telling the model who was last to respond.
|
|
408
438
|
#
|
|
409
|
-
# The context is formatted as "username: message\n..." lines.
|
|
410
|
-
# We scan backwards to find the most recent line authored by a known agent.
|
|
411
|
-
#
|
|
412
439
|
# @param context [String, nil] Conversation history
|
|
413
440
|
# @param agent_name [String] The current agent being evaluated
|
|
414
441
|
# @return [String] Prompt block describing the last responder
|
|
415
442
|
def detect_last_responder(context, _agent_name = nil)
|
|
416
|
-
|
|
417
|
-
return "No agent has spoken yet." unless
|
|
418
|
-
|
|
419
|
-
# Build a lookup of agent display names (lowercase) to their proper display name
|
|
420
|
-
agent_names = {}
|
|
421
|
-
AGENT_REGISTRY.each do |key, entry|
|
|
422
|
-
display = entry.is_a?(Hash) ? (entry["display_name"] || key.capitalize) : key.capitalize
|
|
423
|
-
agent_names[display.downcase] = display
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
# Scan context lines in reverse to find the last agent message
|
|
427
|
-
lines = context.strip.lines.reverse
|
|
428
|
-
lines.each do |line|
|
|
429
|
-
# Lines are formatted as "username: message content"
|
|
430
|
-
match = line.match(/\A(\S+?):\s/)
|
|
431
|
-
next unless match
|
|
443
|
+
responder = detect_last_responder_name(context)
|
|
444
|
+
return "No agent has spoken yet." unless responder
|
|
432
445
|
|
|
433
|
-
|
|
434
|
-
next unless agent_names.key?(username)
|
|
435
|
-
|
|
436
|
-
responder = agent_names[username]
|
|
437
|
-
return "#{responder} was the last to speak. The human is continuing the conversation with #{responder}."
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
"No agent has spoken yet."
|
|
446
|
+
"#{responder} was the last to speak. The human is continuing the conversation with #{responder}."
|
|
441
447
|
end
|
|
442
448
|
|
|
443
449
|
# Detect the last agent to respond — returns just the display name (or nil).
|
|
444
450
|
# Used for deterministic conversational-flow checks without LLM involvement.
|
|
445
451
|
#
|
|
452
|
+
# The context is formatted as "username: message\n..." lines. We scan backwards for
|
|
453
|
+
# the most recent line from a known agent, or from any bot — an agent on another
|
|
454
|
+
# machine is still the one the human is talking to.
|
|
455
|
+
#
|
|
446
456
|
# @param context [String, nil] Conversation history
|
|
447
457
|
# @return [String, nil] Display name of last agent to speak, or nil
|
|
448
458
|
def detect_last_responder_name(context)
|
|
449
459
|
return nil if context.nil? || context.strip.empty?
|
|
450
|
-
return nil unless defined?(AGENT_REGISTRY) && !AGENT_REGISTRY.empty?
|
|
451
460
|
|
|
452
|
-
agent_names =
|
|
453
|
-
AGENT_REGISTRY.each do |key, entry|
|
|
454
|
-
display = entry.is_a?(Hash) ? (entry["display_name"] || key.capitalize) : key.capitalize
|
|
455
|
-
agent_names[display.downcase] = display
|
|
456
|
-
end
|
|
461
|
+
agent_names = intent_agent_display_names
|
|
457
462
|
|
|
458
463
|
context.strip.lines.reverse_each do |line|
|
|
459
|
-
|
|
460
|
-
next unless
|
|
464
|
+
username, bot = parse_context_author(line)
|
|
465
|
+
next unless username
|
|
461
466
|
|
|
462
|
-
username
|
|
463
|
-
return
|
|
467
|
+
return agent_names[username.downcase] if agent_names.key?(username.downcase)
|
|
468
|
+
return username if bot
|
|
464
469
|
end
|
|
465
470
|
|
|
466
471
|
nil
|
data/lib/brainiac/prompts.rb
CHANGED
|
@@ -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
|
-
|
|
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.
|
data/lib/brainiac/version.rb
CHANGED
|
@@ -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
|
}
|