anima-core 1.2.0 → 1.4.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/.reek.yml +14 -8
- data/README.md +96 -23
- data/agents/codebase-analyzer.md +1 -1
- data/agents/codebase-pattern-finder.md +1 -1
- data/agents/documentation-researcher.md +1 -1
- data/agents/thoughts-analyzer.md +1 -1
- data/agents/web-search-researcher.md +2 -2
- data/app/channels/session_channel.rb +53 -35
- data/app/decorators/tool_call_decorator.rb +7 -7
- data/app/decorators/user_message_decorator.rb +3 -17
- data/app/jobs/agent_request_job.rb +15 -6
- data/app/jobs/passive_recall_job.rb +6 -11
- data/app/models/concerns/message/broadcasting.rb +1 -0
- data/app/models/goal.rb +14 -0
- data/app/models/message.rb +13 -31
- data/app/models/pending_message.rb +191 -0
- data/app/models/secret.rb +72 -0
- data/app/models/session.rb +480 -271
- data/bin/inspect-cassette +144 -0
- data/bin/release +212 -0
- data/bin/with-llms +20 -0
- data/config/database.yml +1 -0
- data/config/environments/test.rb +5 -0
- data/config/initializers/time_nanoseconds.rb +11 -0
- data/db/cable_structure.sql +9 -0
- data/db/migrate/20260328100000_create_secrets.rb +15 -0
- data/db/migrate/20260328152142_add_evicted_at_to_goals.rb +6 -0
- data/db/migrate/20260329120000_create_pending_messages.rb +11 -0
- data/db/migrate/20260330120000_add_source_to_pending_messages.rb +8 -0
- data/db/migrate/20260401180000_add_api_metrics_to_messages.rb +7 -0
- data/db/migrate/20260401210935_remove_recalled_message_ids_from_sessions.rb +5 -0
- data/db/migrate/20260403080031_add_initial_cwd_to_sessions.rb +5 -0
- data/db/queue_structure.sql +61 -0
- data/db/structure.sql +120 -0
- data/lib/agent_loop.rb +53 -51
- data/lib/agents/definition.rb +1 -1
- data/lib/analytical_brain/runner.rb +19 -6
- data/lib/analytical_brain/tools/activate_skill.rb +2 -2
- data/lib/analytical_brain/tools/assign_nickname.rb +1 -1
- data/lib/analytical_brain/tools/deactivate_skill.rb +2 -1
- data/lib/analytical_brain/tools/deactivate_workflow.rb +2 -1
- data/lib/analytical_brain/tools/finish_goal.rb +3 -0
- data/lib/analytical_brain/tools/goal_messaging.rb +28 -0
- data/lib/analytical_brain/tools/read_workflow.rb +2 -2
- data/lib/analytical_brain/tools/set_goal.rb +5 -1
- data/lib/analytical_brain/tools/update_goal.rb +5 -1
- data/lib/anima/cli/mcp/secrets.rb +4 -4
- data/lib/anima/cli/mcp.rb +4 -4
- data/lib/anima/cli.rb +41 -13
- data/lib/anima/installer.rb +20 -1
- data/lib/anima/settings.rb +37 -2
- data/lib/anima/version.rb +1 -1
- data/lib/anima.rb +1 -1
- data/lib/credential_store.rb +17 -66
- data/lib/events/agent_message.rb +14 -0
- data/lib/events/base.rb +1 -1
- data/lib/events/subscribers/persister.rb +12 -18
- data/lib/events/subscribers/subagent_message_router.rb +18 -9
- data/lib/events/user_message.rb +2 -13
- data/lib/llm/client.rb +91 -50
- data/lib/mcp/config.rb +2 -2
- data/lib/mcp/secrets.rb +7 -8
- data/lib/mneme/compressed_viewport.rb +9 -5
- data/lib/mneme/passive_recall.rb +85 -16
- data/lib/mneme/runner.rb +15 -4
- data/lib/providers/anthropic.rb +112 -7
- data/lib/shell_session.rb +239 -18
- data/lib/tools/base.rb +22 -0
- data/lib/tools/bash.rb +61 -7
- data/lib/tools/edit.rb +2 -2
- data/lib/tools/mark_goal_completed.rb +85 -0
- data/lib/tools/read.rb +2 -1
- data/lib/tools/recall.rb +98 -0
- data/lib/tools/registry.rb +41 -7
- data/lib/tools/remember.rb +1 -1
- data/lib/tools/response_truncator.rb +70 -0
- data/lib/tools/spawn_specialist.rb +11 -8
- data/lib/tools/spawn_subagent.rb +19 -13
- data/lib/tools/subagent_prompts.rb +41 -5
- data/lib/tools/think.rb +23 -0
- data/lib/tools/write.rb +1 -1
- data/lib/tui/app.rb +545 -137
- data/lib/tui/braille_spinner.rb +152 -0
- data/lib/tui/cable_client.rb +13 -20
- data/lib/tui/decorators/base_decorator.rb +40 -11
- data/lib/tui/decorators/bash_decorator.rb +3 -3
- data/lib/tui/decorators/edit_decorator.rb +7 -4
- data/lib/tui/decorators/read_decorator.rb +6 -8
- data/lib/tui/decorators/think_decorator.rb +4 -6
- data/lib/tui/decorators/web_get_decorator.rb +4 -3
- data/lib/tui/decorators/write_decorator.rb +7 -4
- data/lib/tui/flash.rb +19 -14
- data/lib/tui/formatting.rb +33 -0
- data/lib/tui/input_buffer.rb +6 -6
- data/lib/tui/message_store.rb +159 -27
- data/lib/tui/performance_logger.rb +2 -3
- data/lib/tui/screens/chat.rb +302 -103
- data/lib/tui/settings.rb +86 -0
- data/skills/activerecord/SKILL.md +1 -1
- data/skills/dragonruby/SKILL.md +1 -1
- data/skills/draper-decorators/SKILL.md +1 -1
- data/skills/gh-issue.md +1 -1
- data/skills/mcp-server/SKILL.md +1 -1
- data/skills/ratatui-ruby/SKILL.md +1 -1
- data/skills/rspec/SKILL.md +1 -1
- data/templates/config.toml +30 -1
- data/templates/tui.toml +209 -0
- metadata +24 -3
- data/config/initializers/fts5_schema_dump.rb +0 -21
- data/lib/environment_probe.rb +0 -232
|
@@ -1,23 +1,59 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Tools
|
|
4
|
-
# Shared prompt fragments and
|
|
4
|
+
# Shared prompt fragments and spawn logic for tools that create sub-agent sessions.
|
|
5
5
|
# Included by {SpawnSubagent} and {SpawnSpecialist} to avoid duplication.
|
|
6
6
|
module SubagentPrompts
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
# Prepended to every sub-agent's stored prompt after nickname assignment.
|
|
8
|
+
# Establishes identity before any other instruction.
|
|
9
|
+
IDENTITY_TEMPLATE = "You are %s, a sub-agent of the primary agent."
|
|
10
|
+
|
|
11
|
+
COMMUNICATION_INSTRUCTION = "Your messages reach the parent automatically. " \
|
|
12
|
+
"Ask if you need clarification — the parent can reply."
|
|
10
13
|
|
|
11
14
|
private
|
|
12
15
|
|
|
13
|
-
#
|
|
16
|
+
# Creates the sub-agent's Goal from the task description, inserts the
|
|
17
|
+
# task as the first user message, and pins it to the Goal so it survives
|
|
18
|
+
# viewport eviction for as long as the Goal is active.
|
|
19
|
+
#
|
|
20
|
+
# @param child [Session] the newly created child session
|
|
21
|
+
# @param task [String] the task description
|
|
22
|
+
# @return [void]
|
|
23
|
+
def create_goal_with_pinned_task(child, task)
|
|
24
|
+
goal = child.goals.create!(description: task)
|
|
25
|
+
message = child.create_user_message(task)
|
|
26
|
+
pin = PinnedMessage.create!(
|
|
27
|
+
message: message,
|
|
28
|
+
display_text: task.truncate(PinnedMessage::MAX_DISPLAY_TEXT_LENGTH)
|
|
29
|
+
)
|
|
30
|
+
GoalPinnedMessage.create!(goal: goal, pinned_message: pin)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Runs the analytical brain synchronously to assign a nickname,
|
|
34
|
+
# then prepends identity context to the stored prompt.
|
|
14
35
|
# Falls back to a sequential "agent-N" name on any failure.
|
|
36
|
+
# Identity injection runs in +ensure+ so it applies to both
|
|
37
|
+
# brain-assigned and fallback nicknames.
|
|
15
38
|
def assign_nickname_via_brain(child)
|
|
16
39
|
AnalyticalBrain::Runner.new(child).call
|
|
17
40
|
child.reload
|
|
18
41
|
rescue => error
|
|
19
42
|
Rails.logger.warn("Sub-agent nickname assignment failed: #{error.message}")
|
|
20
43
|
child.update!(name: fallback_nickname)
|
|
44
|
+
ensure
|
|
45
|
+
inject_identity_context(child)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Prepends identity context (nickname + sub-agent status) to the child's
|
|
49
|
+
# stored prompt. Called after nickname assignment so the sub-agent knows
|
|
50
|
+
# who it is from first token.
|
|
51
|
+
#
|
|
52
|
+
# @param child [Session] the child session with a nickname already set
|
|
53
|
+
# @return [void]
|
|
54
|
+
def inject_identity_context(child)
|
|
55
|
+
identity = format(IDENTITY_TEMPLATE, child.name)
|
|
56
|
+
child.update!(prompt: "#{identity}\n#{child.prompt}")
|
|
21
57
|
end
|
|
22
58
|
|
|
23
59
|
def fallback_nickname
|
data/lib/tools/think.rb
CHANGED
|
@@ -13,6 +13,10 @@ module Tools
|
|
|
13
13
|
# - **inner** (default) — silent reasoning, visible only in verbose/debug
|
|
14
14
|
# - **aloud** — narration shown in all view modes with a thought bubble
|
|
15
15
|
#
|
|
16
|
+
# The +maxLength+ on thoughts is controlled by +thinking_budget+ in settings.
|
|
17
|
+
# Sub-agents receive half the main agent's budget — their tasks are scoped
|
|
18
|
+
# and less complex, so runaway reasoning is a stronger signal of confusion.
|
|
19
|
+
#
|
|
16
20
|
# @example Silent planning between tool calls
|
|
17
21
|
# think(thoughts: "Three auth failures — likely a config issue, not individual tests.")
|
|
18
22
|
#
|
|
@@ -23,6 +27,8 @@ module Tools
|
|
|
23
27
|
|
|
24
28
|
def self.description = "Think out loud or silently."
|
|
25
29
|
|
|
30
|
+
# Schema is static — maxLength is injected at runtime by the registry
|
|
31
|
+
# via {#dynamic_schema} when session context is available.
|
|
26
32
|
def self.input_schema
|
|
27
33
|
{
|
|
28
34
|
type: "object",
|
|
@@ -38,6 +44,23 @@ module Tools
|
|
|
38
44
|
}
|
|
39
45
|
end
|
|
40
46
|
|
|
47
|
+
# @param session [Session, nil] current session for budget calculation
|
|
48
|
+
def initialize(session: nil, **)
|
|
49
|
+
@session = session
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Returns the tool schema with a thinking budget applied as maxLength
|
|
53
|
+
# on the thoughts property. Sub-agents get half the budget.
|
|
54
|
+
#
|
|
55
|
+
# @return [Hash] Anthropic tool schema with maxLength constraint
|
|
56
|
+
def dynamic_schema
|
|
57
|
+
schema = self.class.schema.deep_dup
|
|
58
|
+
budget = Anima::Settings.thinking_budget
|
|
59
|
+
budget /= 2 if @session&.sub_agent?
|
|
60
|
+
schema[:input_schema][:properties][:thoughts][:maxLength] = budget
|
|
61
|
+
schema
|
|
62
|
+
end
|
|
63
|
+
|
|
41
64
|
# @param input [Hash] with "thoughts" and optional "visibility"
|
|
42
65
|
# @return [String] acknowledgement — the value is in the call, not the result
|
|
43
66
|
def execute(input)
|
data/lib/tools/write.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Tools
|
|
|
15
15
|
# tool.execute("path" => "README.md", "content" => "# Title\n")
|
|
16
16
|
# # => "Wrote 9 bytes to /home/user/project/README.md"
|
|
17
17
|
class Write < Base
|
|
18
|
-
def self.tool_name = "
|
|
18
|
+
def self.tool_name = "write_file"
|
|
19
19
|
|
|
20
20
|
def self.description = "Write file."
|
|
21
21
|
|