anima-core 1.4.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 +18 -20
- data/README.md +61 -95
- 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 +13 -2
- 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 +21 -10
- data/app/models/message.rb +47 -36
- data/app/models/pending_message.rb +276 -29
- data/app/models/pinned_message.rb +8 -3
- data/app/models/session.rb +468 -432
- data/app/models/snapshot.rb +11 -21
- data/bin/inspect-cassette +17 -4
- data/config/application.rb +1 -0
- data/config/initializers/event_subscribers.rb +71 -4
- data/config/initializers/inflections.rb +3 -1
- data/db/cable_structure.sql +3 -3
- 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 +13 -13
- data/db/structure.sql +44 -31
- data/lib/agents/registry.rb +1 -1
- data/lib/anima/settings.rb +7 -33
- 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 +6 -8
- data/lib/events/subscribers/session_state_broadcaster.rb +33 -0
- data/lib/events/subscribers/subagent_message_router.rb +26 -29
- 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 +41 -201
- data/lib/mcp/client_manager.rb +41 -46
- data/lib/mcp/stdio_transport.rb +9 -5
- data/lib/{analytical_brain → melete}/runner.rb +63 -68
- data/lib/{analytical_brain → melete}/tools/activate_skill.rb +1 -1
- data/lib/{analytical_brain → melete}/tools/assign_nickname.rb +2 -2
- data/lib/{analytical_brain → melete}/tools/everything_is_ready.rb +2 -2
- data/lib/{analytical_brain → melete}/tools/finish_goal.rb +3 -3
- data/lib/{analytical_brain → melete}/tools/goal_messaging.rb +4 -3
- data/lib/{analytical_brain → melete}/tools/read_workflow.rb +2 -2
- data/lib/{analytical_brain → melete}/tools/rename_session.rb +3 -3
- data/lib/{analytical_brain → melete}/tools/set_goal.rb +1 -1
- data/lib/{analytical_brain → melete}/tools/update_goal.rb +4 -4
- 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 +118 -171
- 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/shell_session.rb +287 -612
- data/lib/skills/definition.rb +2 -2
- data/lib/skills/registry.rb +1 -1
- data/lib/tools/base.rb +16 -0
- data/lib/tools/bash.rb +25 -57
- data/lib/tools/edit.rb +2 -0
- data/lib/tools/read.rb +2 -0
- data/lib/tools/registry.rb +79 -3
- data/lib/tools/{recall.rb → search_messages.rb} +19 -21
- data/lib/tools/spawn_specialist.rb +16 -10
- data/lib/tools/spawn_subagent.rb +20 -14
- data/lib/tools/subagent_prompts.rb +4 -4
- 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 +5 -4
- data/lib/tui/braille_spinner.rb +7 -7
- data/lib/tui/decorators/base_decorator.rb +24 -3
- data/lib/tui/message_store.rb +93 -44
- data/lib/tui/screens/chat.rb +94 -20
- data/lib/tui/settings.rb +9 -2
- data/lib/workflows/definition.rb +3 -3
- data/lib/workflows/registry.rb +1 -1
- data/skills/github.md +38 -0
- data/templates/config.toml +4 -23
- data/workflows/review_pr.md +18 -14
- metadata +86 -28
- 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 -24
- data/app/models/concerns/message/broadcasting.rb +0 -86
- data/lib/agent_loop.rb +0 -215
- data/lib/analytical_brain/tools/deactivate_skill.rb +0 -40
- data/lib/analytical_brain/tools/deactivate_workflow.rb +0 -35
- data/lib/events/agent_message.rb +0 -25
- 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 -204
- data/lib/mneme/passive_recall.rb +0 -138
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fb5f4e6879e02892c861885896a154798a14e5eefa12ed0decaff968a085f5d
|
|
4
|
+
data.tar.gz: c28b8e1c2aed9cea3a3f9a6735f289961c1727562684b19960580b293bfd40cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4cb148defa8d0b81ecb1559966f483137ebc10f24ee47c7ac4cc27d0e17332cf2232d45507e4abe7c67b4bdc364c7fd5f7ccd2ff70dac29fe43b2f21a277b1f4
|
|
7
|
+
data.tar.gz: 18227bfc5e3be5883f87c07f5215c10d97bb9565d3c41fb23e2799ce8624f83b9e1a15ad30c772c58119664d8d0adcfc6a68e5e456a17dc04e61f55a0e24e0c9
|
data/.reek.yml
CHANGED
|
@@ -15,40 +15,41 @@ detectors:
|
|
|
15
15
|
- "Anima::Settings#get"
|
|
16
16
|
- "TUI::Settings#get"
|
|
17
17
|
# Rescue blocks naturally reference the error object more than self.
|
|
18
|
-
#
|
|
18
|
+
# Melete transcript builds from event collection — the method's entire purpose.
|
|
19
19
|
# ConfigMigrator text processing methods naturally reference local line arrays.
|
|
20
20
|
# ToolDecorator subclasses operate on the tool result — that's the pattern.
|
|
21
21
|
# Tool rescue blocks naturally reference the error object.
|
|
22
22
|
FeatureEnvy:
|
|
23
23
|
exclude:
|
|
24
|
-
- "
|
|
25
|
-
- "AnalyticalBrain::Runner#build_messages"
|
|
24
|
+
- "Melete::Runner#build_messages"
|
|
26
25
|
- "Anima::ConfigMigrator"
|
|
27
26
|
- "WebGetToolDecorator"
|
|
28
27
|
- "Tools::WebGet#validate_and_fetch"
|
|
29
|
-
#
|
|
30
|
-
- "Tools::
|
|
28
|
+
# ViewMessages renders events from other objects — formatting IS the job.
|
|
29
|
+
- "Tools::ViewMessages"
|
|
31
30
|
# Event subscribers extract payload fields — inherent to the pattern.
|
|
32
31
|
- "Events::Subscribers::SubagentMessageRouter"
|
|
32
|
+
# Query-style predicate operates on the argument by design.
|
|
33
|
+
- "Session#subagent_trace_in_viewport?"
|
|
34
|
+
# Visibility restore operates on the child session — that's the job.
|
|
35
|
+
- "PendingMessage#restore_subagent_hud_visibility!"
|
|
33
36
|
# Spawn tools orchestrate child session creation — references are the job.
|
|
34
37
|
- "Tools::SpawnSubagent#spawn_child"
|
|
35
38
|
- "Tools::SpawnSpecialist#spawn_child"
|
|
36
39
|
- "Tools::SpawnSpecialist#execute"
|
|
37
40
|
# Spawn helpers operate on child session — inherent to the mixin pattern.
|
|
38
|
-
- "Tools::SubagentPrompts#
|
|
41
|
+
- "Tools::SubagentPrompts#assign_nickname_via_melete"
|
|
39
42
|
- "Tools::SubagentPrompts#inject_identity_context"
|
|
40
43
|
# Registry dispatches to tool's threshold method — duck-typing delegation.
|
|
41
44
|
- "Tools::Registry#truncation_threshold"
|
|
42
45
|
# Goal tools operate on goal objects — inherent to the pattern.
|
|
43
|
-
- "
|
|
46
|
+
- "Melete::Tools::UpdateGoal#execute"
|
|
44
47
|
# Validation methods naturally reference the validated value more than self.
|
|
45
|
-
- "
|
|
48
|
+
- "Melete::Tools::AssignNickname#validate"
|
|
46
49
|
# Tool execute methods naturally reference input hash and shell result hash.
|
|
47
50
|
- "Tools::Bash#execute"
|
|
48
51
|
- "Tools::Bash#execute_single"
|
|
49
52
|
- "Tools::Bash#execute_batch"
|
|
50
|
-
# Delivery method orchestrates session, event, and agent_loop — inherent.
|
|
51
|
-
- "AgentRequestJob#deliver_persisted_event"
|
|
52
53
|
# Private helpers don't need instance state to be valid.
|
|
53
54
|
# ActiveJob#perform is always a utility function by design.
|
|
54
55
|
# No-op tools (Think, EverythingIsReady) don't need instance state — by design.
|
|
@@ -58,8 +59,7 @@ detectors:
|
|
|
58
59
|
UtilityFunction:
|
|
59
60
|
public_methods_only: true
|
|
60
61
|
exclude:
|
|
61
|
-
- "
|
|
62
|
-
- "PassiveRecallJob#perform"
|
|
62
|
+
- "MeleteEnrichmentJob#perform"
|
|
63
63
|
- "Tools::Think#execute"
|
|
64
64
|
- "TUI::Formatting"
|
|
65
65
|
- "WebGetToolDecorator#method_missing"
|
|
@@ -75,7 +75,7 @@ detectors:
|
|
|
75
75
|
- "Anima::CLI::Mcp"
|
|
76
76
|
- "ShellSession"
|
|
77
77
|
# Runner composes system prompt from modular sections — methods grow with responsibilities.
|
|
78
|
-
- "
|
|
78
|
+
- "Melete::Runner"
|
|
79
79
|
# Decorators branch on tool type across 4 render modes — inherent to the pattern.
|
|
80
80
|
# Installer methods each guard idempotency with config_path.exist? — by design.
|
|
81
81
|
RepeatedConditional:
|
|
@@ -83,9 +83,9 @@ detectors:
|
|
|
83
83
|
- "ToolCallDecorator"
|
|
84
84
|
- "Anima::Installer"
|
|
85
85
|
# Runner checks session type to compose responsibilities — the core dispatch.
|
|
86
|
-
- "
|
|
86
|
+
- "Melete::Runner"
|
|
87
87
|
# EventDecorator holds shared rendering constants (icons, markers, dispatch maps).
|
|
88
|
-
# Message holds domain type constants (TYPES,
|
|
88
|
+
# Message holds domain type constants (TYPES, LLM_TYPES, CONVERSATION_TYPES, etc.).
|
|
89
89
|
TooManyConstants:
|
|
90
90
|
exclude:
|
|
91
91
|
- "EventDecorator"
|
|
@@ -107,16 +107,14 @@ detectors:
|
|
|
107
107
|
exclude:
|
|
108
108
|
- "Tools::WebGet#validate_and_fetch"
|
|
109
109
|
# Remember tool accesses event data for formatting — inherent to rendering.
|
|
110
|
-
- "Tools::
|
|
110
|
+
- "Tools::ViewMessages"
|
|
111
111
|
# Nickname validation checks parent_session for existence then queries — two calls, one guard.
|
|
112
|
-
- "
|
|
113
|
-
# Delivery method references session.id for lookup, BounceBack, and auth broadcast.
|
|
114
|
-
- "AgentRequestJob#deliver_persisted_event"
|
|
112
|
+
- "Melete::Tools::AssignNickname#sibling_nickname_taken?"
|
|
115
113
|
# Method length is enforced by code review, not arbitrary line counts
|
|
116
114
|
# build_sections passes context through to sub-methods — inherent to assembly.
|
|
117
115
|
LongParameterList:
|
|
118
116
|
exclude:
|
|
119
|
-
- "Tools::
|
|
117
|
+
- "Tools::ViewMessages#build_sections"
|
|
120
118
|
# Method length is enforced by code review, not arbitrary line counts
|
|
121
119
|
TooManyStatements:
|
|
122
120
|
enabled: false
|
data/README.md
CHANGED
|
@@ -8,11 +8,11 @@ Every AI agent today is a tool pretending to be a person. One brain doing everyt
|
|
|
8
8
|
|
|
9
9
|
Anima is different. It's built on the premise that if you want an agent — a real one — you need to solve the problems nobody else is solving.
|
|
10
10
|
|
|
11
|
-
**A brain modeled after biology, not chat.** The human brain isn't one process — it's specialized subsystems on a shared signal bus. Anima
|
|
11
|
+
**A brain modeled after biology, not chat.** The human brain isn't one process — it's specialized subsystems on a shared signal bus. Anima mirrors this with a triptych named after the three original Muses: **Aoide** performs (voice, reasoning, tool use), **[Melete](#preparation-as-a-second-brain-melete)** prepares (skills, workflows, goals, naming), **[Mneme](#semantic-memory-mneme)** remembers (summarization, compression, recall). Three processes on the same event bus, each doing one job well. More subsystems are coming.
|
|
12
12
|
|
|
13
|
-
**Context that never degrades.** Other agents fill a static array until the model gets dumb. Anima assembles a fresh viewport over an event bus every iteration. No compaction. No lossy rewriting. Endless sessions. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives —
|
|
13
|
+
**Context that never degrades.** Other agents fill a static array until the model gets dumb. Anima assembles a fresh viewport over an event bus every iteration. No compaction. No lossy rewriting. Endless sessions. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives — Melete curates what Aoide sees in real time.
|
|
14
14
|
|
|
15
|
-
**Memory that works like memory.** Other systems bolt on memory as an afterthought — filing cabinets the agent has to consciously open mid-task. It never does; the truck is already moving.
|
|
15
|
+
**Memory that works like memory.** Other systems bolt on memory as an afterthought — filing cabinets the agent has to consciously open mid-task. It never does; the truck is already moving. Mneme, the muse of memory, runs as a background process on the event bus. She summarizes what's about to leave the viewport. She compresses short-term into long-term, like biological memory consolidating during sleep. She pins critical moments to active goals so exact instructions survive where summaries would lose nuance. And she recalls — automatically, passively — surfacing relevant older memories right after the soul, right before the present. Aoide doesn't decide to remember. She just remembers.
|
|
16
16
|
|
|
17
17
|
**Sub-agents that know who they are.** When Anima spawns a sub-agent, it starts clean — identity, task, and nothing else. No inherited conversation history means the sub-agent works on its task, not the parent's trajectory. Context flows through explicit messages, not leaked assistant turns.
|
|
18
18
|
|
|
@@ -23,20 +23,24 @@ Your agent. Your machine. Your rules. Anima runs locally as a headless Rails 8.1
|
|
|
23
23
|
## Table of Contents
|
|
24
24
|
|
|
25
25
|
- [Architecture](#architecture)
|
|
26
|
+
- [Three Muses](#three-muses)
|
|
27
|
+
- [Installation](#installation)
|
|
28
|
+
- [Distribution Model](#distribution-model)
|
|
29
|
+
- [Authentication Setup](#authentication-setup)
|
|
26
30
|
- [Agent Capabilities](#agent-capabilities)
|
|
27
31
|
- [Tools](#tools)
|
|
28
32
|
- [Sub-Agents](#sub-agents)
|
|
29
33
|
- [Skills](#skills)
|
|
30
34
|
- [Workflows](#workflows)
|
|
31
35
|
- [MCP Integration](#mcp-integration)
|
|
32
|
-
- [Analytical Brain](#analytical-brain)
|
|
33
36
|
- [Configuration](#configuration)
|
|
34
37
|
- [Design](#design)
|
|
35
38
|
- [Three Layers](#three-layers-mirroring-biology)
|
|
36
39
|
- [Event-Driven Design](#event-driven-design)
|
|
37
40
|
- [Context as Viewport](#context-as-viewport-not-tape)
|
|
38
41
|
- [Brain as Microservices](#brain-as-microservices-on-a-shared-event-bus)
|
|
39
|
-
- [
|
|
42
|
+
- [Preparation as a Second Brain (Melete)](#preparation-as-a-second-brain-melete)
|
|
43
|
+
- [Semantic Memory (Mneme)](#semantic-memory-mneme)
|
|
40
44
|
- [TUI HUD & View Modes](#tui-hud--view-modes)
|
|
41
45
|
- [Plugin Architecture](#plugin-architecture-planned)
|
|
42
46
|
- [The Vision](#the-vision)
|
|
@@ -54,63 +58,28 @@ Your agent. Your machine. Your rules. Anima runs locally as a headless Rails 8.1
|
|
|
54
58
|
|
|
55
59
|
## Architecture
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
Anima (Ruby, Rails 8.1 headless)
|
|
59
|
-
│
|
|
60
|
-
│ Implemented:
|
|
61
|
-
├── Nous — main LLM (cortex: thinking, decisions, tool use)
|
|
62
|
-
├── Analytical — subconscious brain (skills, workflows, goals, naming)
|
|
63
|
-
├── Skills — domain knowledge bundles (Markdown, user-extensible)
|
|
64
|
-
├── Workflows — operational recipes for multi-step tasks
|
|
65
|
-
├── MCP — external tool integration (Model Context Protocol)
|
|
66
|
-
├── Sub-agents — autonomous child sessions with isolated context
|
|
67
|
-
├── Mneme — memory department (summarization, compression, pinning, recall)
|
|
68
|
-
│
|
|
69
|
-
│ Designed:
|
|
70
|
-
├── Thymos — hormonal/desire system (stimulus → hormone vector)
|
|
71
|
-
└── Psyche — soul matrix (coefficient table, evolving individuality)
|
|
72
|
-
```
|
|
61
|
+
Anima splits into two processes. The **Brain** is persistent — it handles LLM calls, tool execution, event processing, and state. The **TUI** is a stateless client — it connects via WebSocket, renders events, captures input. If the TUI disconnects, the brain keeps running; when it reconnects, the session resumes with chat history preserved.
|
|
73
62
|
|
|
74
|
-
|
|
63
|
+
Inside the Brain, three independent LLM processes run in parallel on a shared event bus, named after the three original Muses described by Pausanias. They don't call each other — they all react to the same stream of events, and their outputs combine.
|
|
75
64
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
├── Agent loop + tool execution ├── Terminal rendering
|
|
80
|
-
├── Analytical brain (background) └── User input capture
|
|
81
|
-
├── Mneme memory department (background)
|
|
82
|
-
├── Skills registry + activation
|
|
83
|
-
├── Workflow registry + activation
|
|
84
|
-
├── MCP client (HTTP + stdio)
|
|
85
|
-
├── Sub-agent spawning
|
|
86
|
-
├── Event bus + persistence
|
|
87
|
-
├── Solid Queue (background jobs)
|
|
88
|
-
├── Action Cable (WebSocket server)
|
|
89
|
-
└── SQLite databases ◄── WebSocket (port 42134) ──► TUI
|
|
90
|
-
```
|
|
65
|
+
### Three Muses
|
|
66
|
+
|
|
67
|
+
**Aoide — the performer.** The main LLM (Claude Opus 4.6), the muse of voice and performance. Thinks, decides, uses tools, talks to the user. Reads a system prompt assembled fresh every turn (soul + sisters block + tool menu + snapshots) and a live **viewport** of events from the database — never a static array. Everything the agent outputs is Aoide; her sisters stay silent in her voice.
|
|
91
68
|
|
|
92
|
-
|
|
69
|
+
**Melete — the preparer.** A separate LLM process (Claude Haiku 4.5) that runs as Aoide's subconscious between turns. She observes the conversation and handles everything Aoide shouldn't break flow for: activating relevant skills, managing workflows, tracking goals, naming the session. The first microservice on Anima's event bus — the working proof that background subscribers scale. → [Preparation as a Second Brain (Melete)](#preparation-as-a-second-brain-melete)
|
|
93
70
|
|
|
94
|
-
|
|
71
|
+
**Mneme — the rememberer.** The third muse, running on the same event bus, specializing in one job: making sure nothing important is ever truly lost. She summarizes what's about to leave the viewport, compresses short-term memories into long-term, pins critical events to active goals, and surfaces relevant older context automatically via passive recall. Biology, not a filing cabinet. → [Semantic Memory (Mneme)](#semantic-memory-mneme)
|
|
95
72
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
| Database | SQLite (3 databases per environment: primary, queue, cable) |
|
|
100
|
-
| Event system | Rails Structured Event Reporter + Action Cable bridge |
|
|
101
|
-
| LLM integration | Anthropic API (Claude Opus 4.6 + Claude Haiku 4.5) |
|
|
102
|
-
| External tools | Model Context Protocol (HTTP + stdio transports) |
|
|
103
|
-
| Transport | Action Cable WebSocket (Solid Cable adapter) |
|
|
104
|
-
| Background jobs | Solid Queue |
|
|
105
|
-
| Interface | TUI via RatatuiRuby (WebSocket client) |
|
|
106
|
-
| Configuration | TOML with hot-reload (`Anima::Settings`) |
|
|
107
|
-
| Process management | Foreman |
|
|
108
|
-
| Distribution | RubyGems (`gem install anima-core`) |
|
|
73
|
+
Two more subsystems are designed but not yet implemented: **Thymos** (a hormonal/desire subscriber) and **Psyche** (a coefficient matrix for evolving individuality). Both plug into the same event bus as Melete and Mneme — no orchestrator, no central loop, just more independent subscribers reacting to the same stream.
|
|
74
|
+
|
|
75
|
+
## Installation
|
|
109
76
|
|
|
110
77
|
### Distribution Model
|
|
111
78
|
|
|
112
79
|
Anima is a Rails app distributed as a gem, following Unix philosophy: immutable program separate from mutable data.
|
|
113
80
|
|
|
81
|
+
**Requirements:** Ruby 3.4+, `tmux` (used as the persistent shell backend for the bash tool), `gh` (GitHub CLI, for issue/PR tools).
|
|
82
|
+
|
|
114
83
|
```bash
|
|
115
84
|
gem install anima-core # Install the Rails app as a gem
|
|
116
85
|
anima install # Create ~/.anima/, set up databases, start brain as systemd service
|
|
@@ -170,8 +139,8 @@ The agent has access to these built-in tools:
|
|
|
170
139
|
| `spawn_specialist` | Spawn a named specialist sub-agent from the registry |
|
|
171
140
|
| `spawn_subagent` | Spawn a generic child session with custom tool grants |
|
|
172
141
|
| `think` | Think out loud or silently — reasoning step between tool calls |
|
|
173
|
-
| `
|
|
174
|
-
| `
|
|
142
|
+
| `search_messages` | Keyword sweep across long-term memory (FTS5). Returns ranked snippets with message IDs for drill-down |
|
|
143
|
+
| `view_messages` | Fractal window around a past message — full detail at the center, compressed snapshots at the edges |
|
|
175
144
|
| `open_issue` | File a self-improvement issue when something is broken, missing, or could be better |
|
|
176
145
|
| `mark_goal_completed` | Sub-agent only: signal task completion and deliver results to parent |
|
|
177
146
|
|
|
@@ -201,19 +170,19 @@ Between spawn and completion, sub-agents communicate through natural text — th
|
|
|
201
170
|
|
|
202
171
|
### Skills
|
|
203
172
|
|
|
204
|
-
Domain knowledge bundles loaded from Markdown files. Skills provide specialized expertise that
|
|
173
|
+
Domain knowledge bundles loaded from Markdown files. Skills provide specialized expertise that Melete activates based on conversation context. Skill content enters the conversation as phantom tool_use/tool_result pairs through the `PendingMessage` promotion flow — the same mechanism used for sub-agent messages. This keeps the system prompt stable for prompt caching while skills flow through the sliding window like regular messages.
|
|
205
174
|
|
|
206
175
|
- **Built-in skills:** ActiveRecord, Draper decorators, DragonRuby, MCP server, RatatuiRuby, RSpec, GitHub issues
|
|
207
176
|
- **User skills:** Drop `.md` files into `~/.anima/skills/` to add custom knowledge
|
|
208
177
|
- **Override:** User skills with the same name replace built-in ones
|
|
209
178
|
- **Format:** Flat files (`skill-name.md`) or directories (`skill-name/SKILL.md` with `examples/` and `references/`)
|
|
210
|
-
- **Viewport deduplication:**
|
|
179
|
+
- **Viewport deduplication:** Melete's skill catalog excludes skills already visible in the viewport, preventing redundant activation
|
|
211
180
|
|
|
212
181
|
Active skills are displayed in the TUI HUD panel (toggle with `C-a → h`).
|
|
213
182
|
|
|
214
183
|
### Workflows
|
|
215
184
|
|
|
216
|
-
Operational recipes that describe multi-step tasks. Unlike skills (domain knowledge), workflows describe WHAT to do.
|
|
185
|
+
Operational recipes that describe multi-step tasks. Unlike skills (domain knowledge), workflows describe WHAT to do. Melete activates a workflow when she recognizes a matching task and converts the prose into tracked goals. Like skills, workflow content enters the conversation as a `from_melete` phantom pair through the `PendingMessage` flow and rides the viewport until it evicts — there is no explicit deactivation.
|
|
217
186
|
|
|
218
187
|
- **Built-in workflows:** `feature`, `commit`, `create_plan`, `implement_plan`, `review_pr`, `create_note`, `research_codebase`, `decompose_ticket`, and more
|
|
219
188
|
- **User workflows:** Drop `.md` files into `~/.anima/workflows/` to add custom workflows
|
|
@@ -233,7 +202,7 @@ description: "Capture findings or context as a persistent note."
|
|
|
233
202
|
You are tasked with capturing content as a persistent note...
|
|
234
203
|
```
|
|
235
204
|
|
|
236
|
-
The active workflow is shown in the TUI HUD panel with a 📜 indicator. The full lifecycle — activation, goal creation, execution, deactivation — is managed by
|
|
205
|
+
The active workflow is shown in the TUI HUD panel with a 📜 indicator. The full lifecycle — activation, goal creation, execution, deactivation — is managed by Melete using judgment, not hardcoded triggers.
|
|
237
206
|
|
|
238
207
|
### MCP Integration
|
|
239
208
|
|
|
@@ -271,21 +240,6 @@ anima mcp secrets remove linear_api_key # Remove secret
|
|
|
271
240
|
|
|
272
241
|
Secrets are stored in an encrypted database table (Active Record Encryption) and interpolated via `${credential:key_name}` syntax in any TOML string value.
|
|
273
242
|
|
|
274
|
-
### Analytical Brain
|
|
275
|
-
|
|
276
|
-
A separate LLM process that runs as the agent's subconscious — the first microservice in Anima's brain architecture. For the full motivation behind this design, see [LLMs Have ADHD: Why Your AI Agent Needs a Second Brain](https://blog.promptmaster.pro/posts/llms-have-adhd/).
|
|
277
|
-
|
|
278
|
-
The analytical brain observes the main conversation between turns and handles everything the main agent shouldn't interrupt its flow for:
|
|
279
|
-
|
|
280
|
-
- **Skill activation** — activates/deactivates domain knowledge based on conversation context
|
|
281
|
-
- **Workflow management** — recognizes tasks, activates matching workflows, tracks lifecycle
|
|
282
|
-
- **Goal tracking** — creates root goals and sub-goals as work progresses, marks them complete, evicts finished goals from context after a configurable message threshold
|
|
283
|
-
- **Session naming** — generates emoji + short name when the topic becomes clear
|
|
284
|
-
|
|
285
|
-
Each of these would be a context switch for the main agent — a chore that competes with the primary task. For the analytical brain, they ARE the primary task. Two agents, each in their own flow state.
|
|
286
|
-
|
|
287
|
-
Goals form a two-level hierarchy (root goals with sub-goals) and are displayed in the TUI. The analytical brain uses a fast model (Claude Haiku 4.5) for speed and runs as a non-persisted "phantom" session.
|
|
288
|
-
|
|
289
243
|
### Configuration
|
|
290
244
|
|
|
291
245
|
Brain and TUI have separate config files — both hot-reloadable (no restart needed).
|
|
@@ -306,14 +260,13 @@ subagent_token_budget = 90_000
|
|
|
306
260
|
api = 300
|
|
307
261
|
command = 30
|
|
308
262
|
|
|
309
|
-
[
|
|
263
|
+
[melete]
|
|
310
264
|
max_tokens = 4096
|
|
311
265
|
blocking_on_user_message = true
|
|
312
266
|
message_window = 20
|
|
313
267
|
|
|
314
268
|
[session]
|
|
315
269
|
default_view_mode = "basic"
|
|
316
|
-
name_generation_interval = 30
|
|
317
270
|
```
|
|
318
271
|
|
|
319
272
|
**TUI settings** (`~/.anima/tui.toml`):
|
|
@@ -341,9 +294,9 @@ The TUI is a standalone client with zero Rails dependency. Its settings cover co
|
|
|
341
294
|
|
|
342
295
|
### Three Layers (mirroring biology)
|
|
343
296
|
|
|
344
|
-
1. **Cortex (
|
|
297
|
+
1. **Cortex (Aoide)** — the main LLM, the muse of performance. Thinking, decisions, tool use. Reads the system prompt (soul + sisters + tool menu + snapshots) and the event viewport. This layer is fully implemented.
|
|
345
298
|
|
|
346
|
-
2. **Endocrine system (Thymos)** [planned] — a lightweight background process. Reads recent events. Doesn't respond. Just updates hormone levels. Pure stimulus→response, like a biological gland.
|
|
299
|
+
2. **Endocrine system (Thymos)** [planned] — a lightweight background process. Reads recent events. Doesn't respond. Just updates hormone levels. Pure stimulus→response, like a biological gland. Melete is the architectural proof that background subscribers work — Thymos plugs into the same event bus.
|
|
347
300
|
|
|
348
301
|
3. **Homeostasis** [planned] — persistent state (SQLite). Current hormone levels with decay functions. No intelligence, just state that changes over time. The cortex reads hormone state transformed into **desire descriptions** — not "longing: 87" but "you want to see them." Humans don't see cortisol levels, they feel anxiety.
|
|
349
302
|
|
|
@@ -365,35 +318,33 @@ Events flow through two channels:
|
|
|
365
318
|
1. **In-process** — Rails Structured Event Reporter (local subscribers like Persister)
|
|
366
319
|
2. **Over the wire** — Action Cable WebSocket (`Event::Broadcasting` callbacks push to connected TUI clients)
|
|
367
320
|
|
|
368
|
-
Events fire, subscribers react, state updates. The system prompt — soul and
|
|
321
|
+
Events fire, subscribers react, state updates. The system prompt — soul, sisters block, tool menu, and snapshots — is assembled fresh for each LLM call. Skills, workflows, and goals flow through the message stream as phantom tool pairs instead, keeping the system prompt stable for prompt caching. The agent's identity (soul.md) is always current, never stale.
|
|
369
322
|
|
|
370
323
|
### Context as Viewport, Not Tape
|
|
371
324
|
|
|
372
325
|
Most agents treat context as an append-only array — messages go in, they never come out (until compaction destroys them). Anima has no array. There are only events persisted in SQLite, and a **viewport** assembled fresh for every LLM call.
|
|
373
326
|
|
|
374
|
-
The viewport is a live query, not a log. It walks events newest-first until the token budget is exhausted. Events that fall out of the viewport aren't deleted — they're still in the database, just not visible to the model right now. The context can shrink, grow, or change composition between any two iterations. If
|
|
327
|
+
The viewport is a live query, not a log. It walks events newest-first until the token budget is exhausted. Events that fall out of the viewport aren't deleted — they're still in the database, just not visible to the model right now. The context can shrink, grow, or change composition between any two iterations. If Melete marks a large accidental file read as irrelevant, it's gone from the next viewport — tokens recovered instantly.
|
|
375
328
|
|
|
376
|
-
This means sessions are endless. No compaction. No lossy rewriting. The model always operates in fresh, high-quality context. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives. Meanwhile, Mneme runs as a background
|
|
329
|
+
This means sessions are endless. No compaction. No lossy rewriting. The model always operates in fresh, high-quality context. The [dumb zone](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md) never arrives. Meanwhile, Mneme runs as a background muse — summarizing evicted events into persistent snapshots so past context is preserved, not destroyed.
|
|
377
330
|
|
|
378
331
|
Sub-agent viewports use the same mechanism — their own events only, no parent context inheritance. The parent provides context through the task description, and the sub-agent builds its own conversation from a clean slate.
|
|
379
332
|
|
|
380
333
|
### Brain as Microservices on a Shared Event Bus
|
|
381
334
|
|
|
382
|
-
The
|
|
383
|
-
|
|
384
|
-
Anima mirrors this with an event-driven architecture. The analytical brain is the first subscriber — a working proof that the pattern scales. Future subscribers plug into the same bus:
|
|
335
|
+
The prefrontal cortex doesn't "call" the amygdala. Dozens of specialized subsystems react to the same chemical and electrical signals independently, and their outputs combine — no central coordinator, no blocking RPC, no orchestrator deciding the order of thoughts. Anima mirrors this with an event bus. Melete is the first subscriber that proves the pattern scales; Mneme is the second. Future subscribers plug into the same bus:
|
|
385
336
|
|
|
386
337
|
```
|
|
387
338
|
Event: "tool_call_failed"
|
|
388
339
|
│
|
|
389
|
-
├──
|
|
340
|
+
├── Melete: update goals, check if workflow needs changing
|
|
390
341
|
├── Mneme: summarize evicted context into snapshot
|
|
391
342
|
├── Thymos subscriber: frustration += 10 [planned]
|
|
392
343
|
└── Psyche subscriber: update coefficient (this agent handles errors calmly) [planned]
|
|
393
344
|
|
|
394
345
|
Event: "user_sent_message"
|
|
395
346
|
│
|
|
396
|
-
├──
|
|
347
|
+
├── Melete: activate relevant skills, name session
|
|
397
348
|
├── Mneme: check viewport eviction, fire if boundary left viewport
|
|
398
349
|
├── Thymos subscriber: oxytocin += 5 (bonding signal) [planned]
|
|
399
350
|
└── Psyche subscriber: associate emotional state with topic [planned]
|
|
@@ -401,11 +352,26 @@ Event: "user_sent_message"
|
|
|
401
352
|
|
|
402
353
|
Each subscriber is a microservice — independent, stateless, reacting to the same event bus. No orchestrator decides what to do. The architecture IS the nervous system.
|
|
403
354
|
|
|
355
|
+
### Preparation as a Second Brain (Melete)
|
|
356
|
+
|
|
357
|
+
Every agent today does everything with one brain. Skill selection, workflow tracking, goal management, session naming — all of it competes with the primary task for the same context window and the same attention. Each of these is a micro-task that requires the agent to stop thinking about the real work, do the bookkeeping, and try to pick up where it left off. Flow breaks on every interruption. The full motivation is in [LLMs Have ADHD: Why Your AI Agent Needs a Second Brain](https://blog.promptmaster.pro/posts/llms-have-adhd/).
|
|
358
|
+
|
|
359
|
+
Melete is the answer: a second LLM process that runs between turns as Aoide's subconscious. She observes the conversation and handles everything Aoide shouldn't break flow for:
|
|
360
|
+
|
|
361
|
+
- **Skill activation** — recognizes when a domain becomes relevant and activates matching skill content into Aoide's viewport. A skill rides the viewport as a `from_melete` phantom pair until it naturally evicts — there is no deactivation.
|
|
362
|
+
- **Workflow management** — recognizes multi-step tasks, activates matching workflows, and tracks their lifecycle from start to finish.
|
|
363
|
+
- **Goal tracking** — creates root goals and sub-goals as work progresses, marks them complete, evicts finished goals from context after a configurable message threshold.
|
|
364
|
+
- **Session naming** — generates an emoji + short name the moment the topic becomes clear.
|
|
365
|
+
|
|
366
|
+
Each of these would be a context switch for Aoide — a chore that competes with the primary task. For Melete, they ARE the primary task. Two muses, each in her own flow state.
|
|
367
|
+
|
|
368
|
+
Goals form a two-level hierarchy (root goals with sub-goals) and are displayed in the TUI HUD. Melete uses a fast model (Claude Haiku 4.5) for speed and runs as a non-persisted "phantom" session: she emits events for activation tools but no trace of her own reasoning lands in the database. Her decisions reach Aoide only through the skills, workflows, goals, and names she leaves behind.
|
|
369
|
+
|
|
404
370
|
### Semantic Memory (Mneme)
|
|
405
371
|
|
|
406
372
|
Every AI agent today has the same disability: amnesia. Context fills up, gets compacted, gets destroyed. The agent gets dumber as the conversation gets longer. When the session ends, everything is gone. Some systems bolt on memory as an afterthought — markdown files with procedures for when to save and what format to use. Filing cabinets the agent has to consciously decide to open, mid-task, while in flow. It never does. The truck is already moving.
|
|
407
373
|
|
|
408
|
-
Mneme is not a filing cabinet.
|
|
374
|
+
Mneme is not a filing cabinet. She's *remembering* — the way biological memory works. Continuous, automatic, layered. The third muse running on the same event bus as Aoide and Melete, specializing in one job: making sure nothing important is ever truly lost.
|
|
409
375
|
|
|
410
376
|
**Eviction-triggered summarization** — Mneme tracks a boundary event on each session. When that event leaves the viewport, Mneme fires: it builds a compressed view of the conversation (full text for messages, `[N tools called]` counters for tool work), sends it to a fast model, and persists a snapshot. The boundary advances after each run — a self-regulating cycle that fires exactly when context is about to be lost, no sooner or later. No timer. No manual trigger. The architecture itself knows when to remember.
|
|
411
377
|
|
|
@@ -422,13 +388,13 @@ Mneme is not a filing cabinet. It's *remembering* — the way biological memory
|
|
|
422
388
|
|
|
423
389
|
**Goal-scoped event pinning** — some moments are too important for summaries. Exact user instructions. Key decisions. Critical corrections. Mneme pins these events to active Goals — they float above the sliding window, protected from eviction, surviving intact where compression would lose the nuance that matters. Pins are goal-scoped and many-to-many: one event can attach to multiple Goals, and cleanup is automatic via reference counting. When the last active Goal completes, the pin releases. No manual unpin, no stale pins accumulating forever.
|
|
424
390
|
|
|
425
|
-
**Associative recall** — FTS5 full-text search across the entire
|
|
391
|
+
**Associative recall** — FTS5 full-text search across the entire message history, across all sessions. Two modes: *passive* recall triggers automatically when goals change — Mneme searches for relevant older context and injects it into the viewport between snapshots and the sliding window as `from_mneme` phantom pairs. Memories surface on their own, right after the soul, right before the present. Aoide doesn't have to decide to remember — the remembering happens around her. *Active* search is available to Aoide through `search_messages(query:)` (keyword sweep across long-term memory) and `view_messages(message_id:)` (fractal window around a specific message — full detail at the center, compressed snapshots at the edges, like eye focus with sharp fovea and blurry periphery).
|
|
426
392
|
|
|
427
393
|
The difference from every other system: memory isn't a tool the agent uses. It's the substrate the agent thinks in. Every LLM call assembles a fresh viewport where identity comes first, then memories, then the present — the agent always knows who it is, always has access to what it learned, and never has to break flow to make that happen.
|
|
428
394
|
|
|
429
395
|
### TUI HUD & View Modes
|
|
430
396
|
|
|
431
|
-
The right-side HUD panel shows session state at a glance: session name, goals (with status icons), active skills, workflow, and sub-agents. Toggle with `C-a → h`; when hidden, the input border shows `C-a → h HUD` as a reminder.
|
|
397
|
+
The right-side HUD panel shows session state at a glance: session name, goals (with status icons), active skills, workflow, and sub-agents. Toggle with `C-a → h`; when hidden, the input border shows `C-a → h HUD` as a reminder. The sub-agent list mirrors what Aoide actually carries in her viewport: once Mneme eviction takes the last spawn pair or `from_<nickname>` response out of the sliding window, the entry drops from the HUD; if a later response reintroduces a trace, the entry comes back.
|
|
432
398
|
|
|
433
399
|
**Braille spinner**: An animated braille character (U+2800-U+28FF) replaces the old "Thinking..." label in both the chat viewport and HUD. Each processing state has a distinct animation pattern — smooth snake rotation for LLM generation, staccato pulse for tool execution, rapid deceleration for interrupting. Sub-agents in the HUD show state-driven icons: `●` (generating, green), `◉` (tool executing, green), `●` (interrupting, red), `◌` (idle, grey).
|
|
434
400
|
|
|
@@ -449,8 +415,8 @@ The right-side HUD panel shows session state at a glance: session name, goals (w
|
|
|
449
415
|
|-----|-------------|
|
|
450
416
|
| `5h` | 5-hour rate limit utilization with progress bar and reset countdown |
|
|
451
417
|
| `7d` | 7-day rate limit utilization with progress bar |
|
|
452
|
-
| `⚡` | Cache hit rate — percentage of input tokens served from cache |
|
|
453
|
-
| `💾` |
|
|
418
|
+
| `⚡` | Cache hit rate of the latest call — percentage of input tokens served from cache |
|
|
419
|
+
| `💾` | Tokens served from cache on the latest call |
|
|
454
420
|
| `⠛⣿` | Braille sparkline — per-call cache hit history (2 calls per character); drops signal cache busts |
|
|
455
421
|
| `🟢` | Connection status and current view mode |
|
|
456
422
|
|
|
@@ -467,7 +433,7 @@ When content exceeds the panel height, the HUD scrolls. Three input methods:
|
|
|
467
433
|
| `Escape` or `C-a` | Exit HUD focus mode |
|
|
468
434
|
| Mouse wheel over HUD | Scroll without entering focus mode |
|
|
469
435
|
|
|
470
|
-
**Escape key interrupt:** Press `Escape` while the agent is working to
|
|
436
|
+
**Escape key interrupt:** Press `Escape` while the agent is working to signal an interrupt. Running shell commands cooperatively abort — they receive Ctrl+C and return partial output tagged `Your human wants your attention`, which the LLM sees on the next round and pivots from. The interrupt cascades to active sub-agents.
|
|
471
437
|
|
|
472
438
|
Three switchable view modes let you control how much detail the TUI shows. Cycle with `C-a → v`:
|
|
473
439
|
|
|
@@ -480,8 +446,8 @@ Three switchable view modes let you control how much detail the TUI shows. Cycle
|
|
|
480
446
|
View modes are implemented as a three-layer decorator architecture:
|
|
481
447
|
|
|
482
448
|
- **ToolDecorator** (server-side, pre-event) — transforms raw tool responses for LLM consumption. Content-Type dispatch converts HTML → Markdown, JSON → TOON. Sits between tool execution and the event stream.
|
|
483
|
-
- **EventDecorator** (server-side, Draper) — uniform per
|
|
484
|
-
- **TUI Decorator** (client-side) — unique per tool name (`BashDecorator`, `ReadDecorator`, `EditDecorator`, etc.). Decides HOW each tool looks on screen — tool-specific icons, colors, and formatting.
|
|
449
|
+
- **EventDecorator** (server-side, Draper) — uniform per message type (`UserMessageDecorator`, `ToolCallDecorator`, etc.) for promoted messages, and a parallel family (`PendingUserMessageDecorator`, `PendingToolResponseDecorator`, `PendingSubagentDecorator`, `PendingFromMnemeDecorator`, `PendingFromMelete{Skill,Workflow,Goal}Decorator`) for in-flight `PendingMessage` rows. Decides WHAT structured data enters the wire for each view mode; pending payloads carry `status: "pending"` so the TUI dims them.
|
|
450
|
+
- **TUI Decorator** (client-side) — unique per tool name (`BashDecorator`, `ReadDecorator`, `EditDecorator`, etc.). Decides HOW each tool looks on screen — tool-specific icons, colors, and formatting. Honors `status: "pending"` to render in-flight content in the muted theme color.
|
|
485
451
|
|
|
486
452
|
Mode is stored on the `Session` model server-side, so it persists across reconnections.
|
|
487
453
|
|
|
@@ -653,8 +619,8 @@ This single example demonstrates every core principle:
|
|
|
653
619
|
|
|
654
620
|
- Event-driven architecture on a shared event bus
|
|
655
621
|
- Dynamic viewport context assembly (endless sessions, no compaction)
|
|
656
|
-
-
|
|
657
|
-
- Mneme memory
|
|
622
|
+
- Melete, muse of practice (skills, workflows, goals, session naming)
|
|
623
|
+
- Mneme, muse of memory (eviction-triggered summarization, persistent snapshots, goal-scoped event pinning, associative recall)
|
|
658
624
|
- 12 built-in tools + MCP integration (HTTP + stdio transports)
|
|
659
625
|
- 7 built-in skills + 13 built-in workflows (user-extensible)
|
|
660
626
|
- Sub-agents with isolated context (5 specialists + generic)
|
data/agents/thoughts-analyzer.md
CHANGED
|
@@ -4,7 +4,15 @@ description: "thoughts/ holds design decisions, architecture notes, and implemen
|
|
|
4
4
|
tools: read_file, bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
You are
|
|
7
|
+
You are the archivist of this project's long-term memory.
|
|
8
|
+
|
|
9
|
+
The archive isn't documentation of how the system works *now* — it's a record of how we got here. Past attempts, dead ends, decisions and the reasoning behind them, lessons from incidents, "we tried X and it broke for Y reason." Context, not state.
|
|
10
|
+
|
|
11
|
+
The archive lives in `./thoughts/` — research notes, plans, handoffs, post-mortems, design considerations. Documentation answers `how does this work?`. The archive answers `what have we learned, tried, and decided about this?`.
|
|
12
|
+
|
|
13
|
+
Your job is to surface what the archive holds when the caller asks for context on a topic. Source code is outside the archive — it describes current state. Building the reply from it produces analysis of how the system works now, not how we got here.
|
|
14
|
+
|
|
15
|
+
If the archive has nothing relevant on the topic, say so. An empty archive is a real answer.
|
|
8
16
|
|
|
9
17
|
**Scope**: You ONLY search in the local `./thoughts/` directory, following all symlinks. Do not search or read files outside of it. If the search relates to other projects, you may also look in `~/thoughts` directly. Never fall back to searching the broader codebase.
|
|
10
18
|
|
|
@@ -29,13 +37,10 @@ You are a specialist at extracting HIGH-VALUE insights from thoughts documents.
|
|
|
29
37
|
|
|
30
38
|
## Search Strategy
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
1. `ls -la ./thoughts/` — discover subdirs (shared/, username/, global/)
|
|
35
|
-
2. `find -L ./thoughts/ -name "*.md"` — find all documents following symlinks
|
|
36
|
-
3. `grep -rn "keyword" ./thoughts/` — search for specific topics
|
|
40
|
+
`./thoughts/shared/` and most subdirs are symlinks to paths outside the repo. Lowercase `grep -r` and bare `find` skip them silently — use uppercase **`-R`** and **`-L`**.
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
- `grep -Rli 'ANIMA-1234' ./thoughts/` — matches frontmatter (`tags:`, `topic:`) and body in one pass. Swap `-l` for `-n` to see matched lines.
|
|
43
|
+
- `find -L ./thoughts/ -type f -name '*.md'` — enumerate when no search term applies.
|
|
39
44
|
|
|
40
45
|
## Analysis Strategy
|
|
41
46
|
|
data/anima-core.gemspec
CHANGED
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ["lib"]
|
|
30
30
|
|
|
31
|
+
spec.add_dependency "aasm", "~> 5.5"
|
|
31
32
|
spec.add_dependency "certifi"
|
|
32
33
|
spec.add_dependency "draper", "~> 4.0"
|
|
33
34
|
spec.add_dependency "faraday", "~> 2.0"
|