anima-core 1.0.1 → 1.1.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/.gitattributes +1 -0
- data/.reek.yml +61 -0
- data/README.md +202 -116
- data/anima-core.gemspec +4 -1
- data/app/channels/session_channel.rb +44 -10
- data/app/decorators/agent_message_decorator.rb +6 -0
- data/app/decorators/event_decorator.rb +41 -7
- data/app/decorators/tool_call_decorator.rb +66 -5
- data/app/decorators/tool_decorator.rb +57 -0
- data/app/decorators/tool_response_decorator.rb +35 -5
- data/app/decorators/user_message_decorator.rb +6 -0
- data/app/decorators/web_get_tool_decorator.rb +102 -0
- data/app/jobs/agent_request_job.rb +95 -20
- data/app/jobs/mneme_job.rb +51 -0
- data/app/jobs/passive_recall_job.rb +29 -0
- data/app/models/concerns/event/broadcasting.rb +18 -0
- data/app/models/event.rb +10 -0
- data/app/models/goal.rb +27 -0
- data/app/models/goal_pinned_event.rb +11 -0
- data/app/models/pinned_event.rb +41 -0
- data/app/models/session.rb +335 -6
- data/app/models/snapshot.rb +76 -0
- data/config/initializers/event_subscribers.rb +14 -3
- data/config/initializers/fts5_schema_dump.rb +21 -0
- data/db/migrate/20260316094817_add_interrupt_requested_to_sessions.rb +5 -0
- data/db/migrate/20260321080000_create_mneme_schema.rb +32 -0
- data/db/migrate/20260321120000_create_pinned_events.rb +27 -0
- data/db/migrate/20260321140000_create_events_fts_index.rb +77 -0
- data/db/migrate/20260321140100_add_recalled_event_ids_to_sessions.rb +10 -0
- data/lib/agent_loop.rb +67 -18
- data/lib/analytical_brain/runner.rb +159 -84
- data/lib/analytical_brain/tools/assign_nickname.rb +76 -0
- data/lib/analytical_brain/tools/finish_goal.rb +6 -1
- data/lib/anima/cli.rb +34 -1
- data/lib/anima/config_migrator.rb +205 -0
- data/lib/anima/installer.rb +13 -130
- data/lib/anima/settings.rb +42 -1
- data/lib/anima/version.rb +1 -1
- data/lib/events/bounce_back.rb +37 -0
- data/lib/events/subscribers/agent_dispatcher.rb +29 -0
- data/lib/events/subscribers/persister.rb +17 -0
- data/lib/events/subscribers/subagent_message_router.rb +102 -0
- data/lib/events/subscribers/transient_broadcaster.rb +36 -0
- data/lib/llm/client.rb +99 -14
- data/lib/mneme/compressed_viewport.rb +200 -0
- data/lib/mneme/l2_runner.rb +138 -0
- data/lib/mneme/passive_recall.rb +69 -0
- data/lib/mneme/runner.rb +254 -0
- data/lib/mneme/search.rb +150 -0
- data/lib/mneme/tools/attach_events_to_goals.rb +107 -0
- data/lib/mneme/tools/everything_ok.rb +24 -0
- data/lib/mneme/tools/save_snapshot.rb +68 -0
- data/lib/mneme.rb +29 -0
- data/lib/providers/anthropic.rb +57 -13
- data/lib/shell_session.rb +188 -59
- data/lib/tasks/fts5.rake +6 -0
- data/lib/tools/remember.rb +179 -0
- data/lib/tools/spawn_specialist.rb +21 -9
- data/lib/tools/spawn_subagent.rb +22 -11
- data/lib/tools/subagent_prompts.rb +20 -3
- data/lib/tools/think.rb +57 -0
- data/lib/tools/web_get.rb +15 -6
- data/lib/tui/app.rb +230 -127
- data/lib/tui/cable_client.rb +8 -0
- data/lib/tui/decorators/base_decorator.rb +165 -0
- data/lib/tui/decorators/bash_decorator.rb +20 -0
- data/lib/tui/decorators/edit_decorator.rb +19 -0
- data/lib/tui/decorators/read_decorator.rb +24 -0
- data/lib/tui/decorators/think_decorator.rb +36 -0
- data/lib/tui/decorators/web_get_decorator.rb +19 -0
- data/lib/tui/decorators/write_decorator.rb +19 -0
- data/lib/tui/flash.rb +139 -0
- data/lib/tui/formatting.rb +28 -0
- data/lib/tui/height_map.rb +93 -0
- data/lib/tui/message_store.rb +25 -1
- data/lib/tui/performance_logger.rb +90 -0
- data/lib/tui/screens/chat.rb +374 -109
- data/templates/config.toml +156 -0
- metadata +87 -4
- data/CHANGELOG.md +0 -79
- data/Gemfile +0 -17
- data/lib/tools/return_result.rb +0 -81
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "logger"
|
|
4
|
+
|
|
5
|
+
module TUI
|
|
6
|
+
# Frame-level performance logger for TUI render profiling.
|
|
7
|
+
#
|
|
8
|
+
# When enabled via `--debug`, logs timing data for each render phase
|
|
9
|
+
# to `log/tui_performance.log`. Each frame produces one log line with
|
|
10
|
+
# phase durations in milliseconds, enabling bottleneck identification.
|
|
11
|
+
#
|
|
12
|
+
# Uses monotonic clock to avoid wall-clock jitter.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# logger = PerformanceLogger.new(enabled: true)
|
|
16
|
+
# logger.start_frame
|
|
17
|
+
# logger.measure(:build_lines) { build_message_lines(tui) }
|
|
18
|
+
# logger.measure(:line_count) { widget.line_count(width) }
|
|
19
|
+
# logger.end_frame
|
|
20
|
+
class PerformanceLogger
|
|
21
|
+
LOG_PATH = "log/tui_performance.log"
|
|
22
|
+
|
|
23
|
+
# @param enabled [Boolean] whether to actually log (no-op when false)
|
|
24
|
+
def initialize(enabled: false)
|
|
25
|
+
@enabled = enabled
|
|
26
|
+
@phases = {}
|
|
27
|
+
@frame_start = nil
|
|
28
|
+
@frame_count = 0
|
|
29
|
+
@logger = nil
|
|
30
|
+
|
|
31
|
+
return unless @enabled
|
|
32
|
+
|
|
33
|
+
@logger = Logger.new(LOG_PATH, 1, 5 * 1024 * 1024) # 5MB rotation
|
|
34
|
+
@logger.formatter = proc { |_sev, time, _prog, msg| "#{time.strftime("%H:%M:%S.%L")} #{msg}\n" }
|
|
35
|
+
@logger.info("TUI Performance Logger started — pid=#{Process.pid}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Boolean] true when logging is active
|
|
39
|
+
def enabled?
|
|
40
|
+
@enabled
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Marks the beginning of a render frame.
|
|
44
|
+
def start_frame
|
|
45
|
+
return unless @enabled
|
|
46
|
+
|
|
47
|
+
@frame_start = monotonic_now
|
|
48
|
+
@phases = {}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Measures a named phase within the current frame.
|
|
52
|
+
# Returns the block's result so it can be used inline.
|
|
53
|
+
#
|
|
54
|
+
# @param name [Symbol] phase name (e.g. :build_lines, :line_count)
|
|
55
|
+
# @yield the code to measure
|
|
56
|
+
# @return [Object] the block's return value
|
|
57
|
+
def measure(name)
|
|
58
|
+
return yield unless @enabled
|
|
59
|
+
|
|
60
|
+
start = monotonic_now
|
|
61
|
+
result = yield
|
|
62
|
+
@phases[name] = ((monotonic_now - start) * 1000).round(2)
|
|
63
|
+
result
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Logs the completed frame with all phase timings.
|
|
67
|
+
def end_frame
|
|
68
|
+
return unless @enabled
|
|
69
|
+
|
|
70
|
+
total = ((monotonic_now - @frame_start) * 1000).round(2)
|
|
71
|
+
@frame_count += 1
|
|
72
|
+
|
|
73
|
+
parts = @phases.map { |name, ms| "#{name}=#{ms}ms" }
|
|
74
|
+
@logger.info("frame=#{@frame_count} total=#{total}ms #{parts.join(" ")}")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Logs a one-off informational message (e.g. cache hit/miss).
|
|
78
|
+
#
|
|
79
|
+
# @param message [String]
|
|
80
|
+
def info(message)
|
|
81
|
+
@logger&.info(message)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def monotonic_now
|
|
87
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|