anima-core 1.3.0 → 1.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/.reek.yml +23 -26
- data/README.md +118 -104
- data/agents/thoughts-analyzer.md +12 -7
- data/anima-core.gemspec +1 -0
- data/app/channels/session_channel.rb +38 -58
- data/app/decorators/agent_message_decorator.rb +7 -2
- data/app/decorators/message_decorator.rb +31 -100
- data/app/decorators/pending_from_melete_decorator.rb +36 -0
- data/app/decorators/pending_from_melete_goal_decorator.rb +13 -0
- data/app/decorators/pending_from_melete_skill_decorator.rb +19 -0
- data/app/decorators/pending_from_melete_workflow_decorator.rb +13 -0
- data/app/decorators/pending_from_mneme_decorator.rb +44 -0
- data/app/decorators/pending_message_decorator.rb +94 -0
- data/app/decorators/pending_subagent_decorator.rb +46 -0
- data/app/decorators/pending_tool_response_decorator.rb +51 -0
- data/app/decorators/pending_user_message_decorator.rb +22 -0
- data/app/decorators/system_message_decorator.rb +5 -0
- data/app/decorators/tool_call_decorator.rb +16 -5
- data/app/decorators/tool_response_decorator.rb +2 -2
- data/app/decorators/user_message_decorator.rb +7 -2
- data/app/jobs/count_tokens_job.rb +23 -0
- data/app/jobs/drain_job.rb +169 -0
- data/app/jobs/melete_enrichment_job/goal_change_listener.rb +52 -0
- data/app/jobs/melete_enrichment_job.rb +48 -0
- data/app/jobs/mneme_enrichment_job.rb +46 -0
- data/app/jobs/tool_execution_job.rb +87 -0
- data/app/models/concerns/token_estimation.rb +54 -0
- data/app/models/goal.rb +23 -11
- data/app/models/message.rb +46 -48
- data/app/models/pending_message.rb +407 -12
- data/app/models/pinned_message.rb +8 -3
- data/app/models/session.rb +660 -566
- data/app/models/snapshot.rb +11 -21
- data/bin/inspect-cassette +157 -0
- data/bin/release +212 -0
- data/bin/with-llms +20 -0
- data/config/application.rb +1 -0
- data/config/database.yml +1 -0
- data/config/initializers/event_subscribers.rb +71 -4
- data/config/initializers/inflections.rb +3 -1
- data/db/cable_structure.sql +9 -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/migrate/20260407170803_remove_viewport_message_ids_from_sessions.rb +5 -0
- data/db/migrate/20260407180400_remove_mneme_snapshot_pointer_columns_from_sessions.rb +6 -0
- data/db/migrate/20260411120553_add_token_count_to_pinned_messages.rb +5 -0
- data/db/migrate/20260411172926_remove_active_skills_and_workflow_from_sessions.rb +6 -0
- data/db/migrate/20260412110625_replace_processing_with_aasm_state.rb +6 -0
- data/db/migrate/20260418150323_add_kind_and_message_type_to_pending_messages.rb +6 -0
- data/db/migrate/20260419120000_add_drain_fields_to_pending_messages.rb +7 -0
- data/db/migrate/20260419130000_drop_pending_messages_kind_default.rb +5 -0
- data/db/migrate/20260419140000_add_drain_indexes_to_pending_messages.rb +8 -0
- data/db/migrate/20260420100000_add_hud_visibility_to_sessions.rb +15 -0
- data/db/queue_structure.sql +61 -0
- data/db/structure.sql +133 -0
- data/lib/agents/registry.rb +1 -1
- data/lib/anima/cli.rb +41 -13
- data/lib/anima/installer.rb +13 -0
- data/lib/anima/settings.rb +16 -36
- data/lib/anima/version.rb +1 -1
- data/lib/events/authentication_required.rb +24 -0
- data/lib/events/bounce_back.rb +4 -4
- data/lib/events/eviction_completed.rb +28 -0
- data/lib/events/goal_created.rb +28 -0
- data/lib/events/goal_updated.rb +32 -0
- data/lib/events/llm_responded.rb +35 -0
- data/lib/events/message_created.rb +27 -0
- data/lib/events/message_updated.rb +25 -0
- data/lib/events/session_state_changed.rb +30 -0
- data/lib/events/skill_activated.rb +28 -0
- data/lib/events/start_melete.rb +36 -0
- data/lib/events/start_mneme.rb +33 -0
- data/lib/events/start_processing.rb +32 -0
- data/lib/events/subagent_evicted.rb +31 -0
- data/lib/events/subscribers/active_state_broadcaster.rb +27 -0
- data/lib/events/subscribers/authentication_broadcaster.rb +34 -0
- data/lib/events/subscribers/drain_kickoff.rb +20 -0
- data/lib/events/subscribers/eviction_broadcaster.rb +26 -0
- data/lib/events/subscribers/llm_response_handler.rb +111 -0
- data/lib/events/subscribers/melete_kickoff.rb +24 -0
- data/lib/events/subscribers/message_broadcaster.rb +34 -0
- data/lib/events/subscribers/mneme_kickoff.rb +24 -0
- data/lib/events/subscribers/mneme_scheduler.rb +21 -0
- data/lib/events/subscribers/persister.rb +8 -9
- data/lib/events/subscribers/session_state_broadcaster.rb +33 -0
- data/lib/events/subscribers/subagent_message_router.rb +28 -34
- data/lib/events/subscribers/subagent_visibility_broadcaster.rb +33 -0
- data/lib/events/subscribers/tool_response_creator.rb +33 -0
- data/lib/events/subscribers/transient_broadcaster.rb +1 -1
- data/lib/events/tool_executed.rb +34 -0
- data/lib/events/workflow_activated.rb +27 -0
- data/lib/llm/client.rb +46 -199
- data/lib/mcp/client_manager.rb +41 -46
- data/lib/mcp/stdio_transport.rb +9 -5
- data/lib/{analytical_brain → melete}/runner.rb +73 -68
- data/lib/{analytical_brain → melete}/tools/activate_skill.rb +3 -3
- data/lib/{analytical_brain → melete}/tools/assign_nickname.rb +3 -3
- data/lib/{analytical_brain → melete}/tools/everything_is_ready.rb +2 -2
- data/lib/{analytical_brain → melete}/tools/finish_goal.rb +6 -3
- data/lib/melete/tools/goal_messaging.rb +29 -0
- data/lib/{analytical_brain → melete}/tools/read_workflow.rb +4 -4
- data/lib/{analytical_brain → melete}/tools/rename_session.rb +3 -3
- data/lib/{analytical_brain → melete}/tools/set_goal.rb +6 -2
- data/lib/{analytical_brain → melete}/tools/update_goal.rb +9 -5
- data/lib/{analytical_brain.rb → melete.rb} +6 -3
- data/lib/mneme/base_runner.rb +121 -0
- data/lib/mneme/l2_runner.rb +14 -20
- data/lib/mneme/recall_runner.rb +132 -0
- data/lib/mneme/runner.rb +123 -165
- data/lib/mneme/search.rb +104 -62
- data/lib/mneme/tools/nothing_to_surface.rb +25 -0
- data/lib/mneme/tools/save_snapshot.rb +2 -10
- data/lib/mneme/tools/surface_memory.rb +89 -0
- data/lib/mneme.rb +11 -5
- data/lib/providers/anthropic.rb +112 -7
- data/lib/shell_session.rb +290 -432
- data/lib/skills/definition.rb +2 -2
- data/lib/skills/registry.rb +1 -1
- data/lib/tools/base.rb +16 -1
- data/lib/tools/bash.rb +25 -55
- data/lib/tools/edit.rb +2 -0
- data/lib/tools/mark_goal_completed.rb +4 -5
- data/lib/tools/read.rb +2 -0
- data/lib/tools/registry.rb +85 -4
- data/lib/tools/response_truncator.rb +1 -1
- data/lib/tools/{recall.rb → search_messages.rb} +19 -21
- data/lib/tools/spawn_specialist.rb +22 -14
- data/lib/tools/spawn_subagent.rb +30 -20
- data/lib/tools/subagent_prompts.rb +17 -19
- data/lib/tools/think.rb +1 -1
- data/lib/tools/{remember.rb → view_messages.rb} +10 -10
- data/lib/tools/write.rb +2 -0
- data/lib/tui/app.rb +393 -149
- data/lib/tui/braille_spinner.rb +7 -7
- data/lib/tui/cable_client.rb +9 -16
- data/lib/tui/decorators/base_decorator.rb +47 -6
- data/lib/tui/decorators/bash_decorator.rb +1 -1
- data/lib/tui/decorators/edit_decorator.rb +4 -2
- data/lib/tui/decorators/read_decorator.rb +4 -2
- data/lib/tui/decorators/think_decorator.rb +2 -2
- data/lib/tui/decorators/web_get_decorator.rb +1 -1
- data/lib/tui/decorators/write_decorator.rb +4 -2
- data/lib/tui/flash.rb +19 -14
- data/lib/tui/formatting.rb +20 -9
- data/lib/tui/input_buffer.rb +6 -6
- data/lib/tui/message_store.rb +165 -28
- data/lib/tui/performance_logger.rb +2 -3
- data/lib/tui/screens/chat.rb +149 -79
- data/lib/tui/settings.rb +93 -0
- data/lib/workflows/definition.rb +3 -3
- data/lib/workflows/registry.rb +1 -1
- data/skills/github.md +38 -0
- data/templates/config.toml +16 -32
- data/templates/tui.toml +209 -0
- data/workflows/review_pr.md +18 -14
- metadata +98 -29
- data/app/jobs/agent_request_job.rb +0 -199
- data/app/jobs/analytical_brain_job.rb +0 -33
- data/app/jobs/count_message_tokens_job.rb +0 -39
- data/app/jobs/passive_recall_job.rb +0 -29
- data/app/models/concerns/message/broadcasting.rb +0 -85
- data/config/initializers/fts5_schema_dump.rb +0 -21
- data/lib/agent_loop.rb +0 -186
- data/lib/analytical_brain/tools/deactivate_skill.rb +0 -39
- data/lib/analytical_brain/tools/deactivate_workflow.rb +0 -34
- data/lib/environment_probe.rb +0 -232
- data/lib/events/agent_message.rb +0 -11
- data/lib/events/subscribers/message_collector.rb +0 -64
- data/lib/events/tool_call.rb +0 -31
- data/lib/events/tool_response.rb +0 -33
- data/lib/mneme/compressed_viewport.rb +0 -200
- data/lib/mneme/passive_recall.rb +0 -69
|
@@ -6,39 +6,37 @@ module Tools
|
|
|
6
6
|
module SubagentPrompts
|
|
7
7
|
# Prepended to every sub-agent's stored prompt after nickname assignment.
|
|
8
8
|
# Establishes identity before any other instruction.
|
|
9
|
-
IDENTITY_TEMPLATE = "You are
|
|
9
|
+
IDENTITY_TEMPLATE = "You are %s, a sub-agent of the primary agent."
|
|
10
10
|
|
|
11
11
|
COMMUNICATION_INSTRUCTION = "Your messages reach the parent automatically. " \
|
|
12
12
|
"Ask if you need clarification — the parent can reply."
|
|
13
13
|
|
|
14
|
-
# Framing message inserted as the sub-agent's first user message.
|
|
15
|
-
# This is the "brake" between inherited parent context and the sub-agent's
|
|
16
|
-
# own task — without it, the model continues the parent's trajectory.
|
|
17
|
-
FORK_FRAMING_MESSAGE = "You were spawned to help with a single task. " \
|
|
18
|
-
"The messages above are the parent agent's context — background for your work, " \
|
|
19
|
-
"but the parent's goals are not yours. " \
|
|
20
|
-
"Your sole task is described in your Goal."
|
|
21
|
-
|
|
22
14
|
private
|
|
23
15
|
|
|
24
|
-
# Creates the sub-agent's Goal from the task description
|
|
25
|
-
# the
|
|
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.
|
|
26
19
|
#
|
|
27
20
|
# @param child [Session] the newly created child session
|
|
28
|
-
# @param task [String] the task description
|
|
21
|
+
# @param task [String] the task description
|
|
29
22
|
# @return [void]
|
|
30
|
-
def
|
|
31
|
-
child.goals.create!(description: task)
|
|
32
|
-
child.create_user_message(
|
|
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)
|
|
33
31
|
end
|
|
34
32
|
|
|
35
|
-
# Runs
|
|
33
|
+
# Runs Melete synchronously to assign a nickname,
|
|
36
34
|
# then prepends identity context to the stored prompt.
|
|
37
35
|
# Falls back to a sequential "agent-N" name on any failure.
|
|
38
36
|
# Identity injection runs in +ensure+ so it applies to both
|
|
39
|
-
#
|
|
40
|
-
def
|
|
41
|
-
|
|
37
|
+
# Melete-assigned and fallback nicknames.
|
|
38
|
+
def assign_nickname_via_melete(child)
|
|
39
|
+
Melete::Runner.new(child).call
|
|
42
40
|
child.reload
|
|
43
41
|
rescue => error
|
|
44
42
|
Rails.logger.warn("Sub-agent nickname assignment failed: #{error.message}")
|
data/lib/tools/think.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Tools
|
|
|
5
5
|
# pause between tool calls where the agent can organize thoughts, plan
|
|
6
6
|
# next steps, or make decisions without interrupting the user.
|
|
7
7
|
#
|
|
8
|
-
# Think events bridge the gap between
|
|
8
|
+
# Think events bridge the gap between Melete (subconscious
|
|
9
9
|
# background processing) and speech (user-facing messages). Without this
|
|
10
10
|
# tool, reasoning leaks into tool arguments as comments.
|
|
11
11
|
#
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Tools
|
|
4
|
-
# Fractal-resolution
|
|
5
|
-
#
|
|
6
|
-
# at the edges — sharp fovea, blurry periphery.
|
|
4
|
+
# Fractal-resolution window into long-term memory. Given a message_id,
|
|
5
|
+
# returns the surrounding conversation with full detail at the center
|
|
6
|
+
# and compressed snapshots at the edges — sharp fovea, blurry periphery.
|
|
7
7
|
#
|
|
8
8
|
# Output structure:
|
|
9
9
|
# [Previous snapshots — compressed context before]
|
|
10
10
|
# [Messages N-M — full detail, tool_responses compressed to checkmarks]
|
|
11
11
|
# [Following snapshots — compressed context after]
|
|
12
12
|
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
13
|
+
# Aoide discovers target message IDs via {SearchMessages} and drills
|
|
14
|
+
# down here to recover the full context around any moment.
|
|
15
15
|
#
|
|
16
16
|
# @example
|
|
17
|
-
#
|
|
18
|
-
class
|
|
17
|
+
# view_messages(message_id: 42)
|
|
18
|
+
class ViewMessages < Base
|
|
19
19
|
# Messages around the target to include at full resolution.
|
|
20
20
|
# ±10 messages provides sharp foveal detail while keeping output readable.
|
|
21
21
|
CONTEXT_WINDOW = 20
|
|
@@ -26,9 +26,9 @@ module Tools
|
|
|
26
26
|
"system_message" => "System"
|
|
27
27
|
}.freeze
|
|
28
28
|
|
|
29
|
-
def self.tool_name = "
|
|
29
|
+
def self.tool_name = "view_messages"
|
|
30
30
|
|
|
31
|
-
def self.description = "
|
|
31
|
+
def self.description = "View the full conversation around a message in long-term memory. Pass a message_id — typically one returned by search_messages — to see the surrounding exchange with compressed snapshots at the edges."
|
|
32
32
|
|
|
33
33
|
def self.input_schema
|
|
34
34
|
{
|
|
@@ -112,7 +112,7 @@ module Tools
|
|
|
112
112
|
# @return [Array<Message>] chronologically ordered
|
|
113
113
|
def fetch_center_messages(target, target_session)
|
|
114
114
|
half = CONTEXT_WINDOW / 2
|
|
115
|
-
scope = target_session.messages
|
|
115
|
+
scope = target_session.messages
|
|
116
116
|
target_id = target.id
|
|
117
117
|
|
|
118
118
|
before = scope.where("id <= ?", target_id).reorder(id: :desc).limit(half + 1).to_a.reverse
|