openclacky 1.2.9 → 1.2.10
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/CHANGELOG.md +23 -0
- data/lib/clacky/agent/llm_caller.rb +3 -0
- data/lib/clacky/agent/message_compressor_helper.rb +6 -5
- data/lib/clacky/agent/session_serializer.rb +4 -0
- data/lib/clacky/agent.rb +9 -0
- data/lib/clacky/agent_config.rb +20 -1
- data/lib/clacky/brand_config.rb +1 -0
- data/lib/clacky/cli.rb +49 -22
- data/lib/clacky/idle_compression_timer.rb +38 -15
- data/lib/clacky/providers.rb +7 -2
- data/lib/clacky/rich_ui_controller.rb +1549 -0
- data/lib/clacky/server/channel/adapters/weixin/adapter.rb +24 -2
- data/lib/clacky/server/channel/channel_manager.rb +89 -2
- data/lib/clacky/server/http_server.rb +124 -9
- data/lib/clacky/session_manager.rb +9 -8
- data/lib/clacky/telemetry.rb +16 -2
- data/lib/clacky/ui2/layout_manager.rb +11 -7
- data/lib/clacky/ui2/ui_controller.rb +2 -2
- data/lib/clacky/ui_interface.rb +1 -1
- data/lib/clacky/utils/model_pricing.rb +75 -53
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/web/app.css +221 -2
- data/lib/clacky/web/billing.js +1 -1
- data/lib/clacky/web/i18n.js +28 -4
- data/lib/clacky/web/index.html +9 -1
- data/lib/clacky/web/sessions.js +443 -2
- data/lib/clacky/web/settings.js +50 -0
- data/lib/clacky/web/workspace.js +9 -1
- data/scripts/build/lib/network.sh +3 -3
- data/scripts/install.ps1 +16 -4
- data/scripts/install.sh +3 -3
- data/scripts/install_browser.sh +3 -3
- data/scripts/install_full.sh +3 -3
- data/scripts/install_rails_deps.sh +3 -3
- data/scripts/install_system_deps.sh +3 -3
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0b32940868f1d61791afd615ff73dbaf72dc80c111f9f9435ef939ef39ae5dec
|
|
4
|
+
data.tar.gz: be8efa7ee318c3f174ddbbdf1f5b2754705eb6a5d3f263aa11cbe5539b198e8f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abcbed799ca8feed1a41e39a72bd8e6a5e9184c8e76a67bac79f9bee07f88ebf6b639102d6cfcd6527bf80b7b3c9bda5665f131bf81a164b9a14b963cad1ea47
|
|
7
|
+
data.tar.gz: 829bc77c06483853c1d568d04a528a9611c6e7f775b38b6c6fdebe04c5a5ae6974328bb1ac9c0f8cb1afe0765a60795061157b65860eaf26e8bb7368dadb2b8e
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.2.10] - 2026-06-03
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Compressor concurrency config and Ollama context size auto-detection
|
|
12
|
+
- Channel sessions auto-rebind on server restart
|
|
13
|
+
- Disk space check (4 GB minimum) on Windows install
|
|
14
|
+
- WSL network connectivity pre-check before installation
|
|
15
|
+
- MiniMax M3 provider with vision support and pricing
|
|
16
|
+
- One-click exchange rate update in settings
|
|
17
|
+
- Rich TUI controller for terminal interaction
|
|
18
|
+
|
|
19
|
+
### Improved
|
|
20
|
+
- WebUI working directory selector UX
|
|
21
|
+
- Qwen pricing table: official rates, promo discounts, clean up stale models
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
- Directory picker interaction and indentation issues
|
|
25
|
+
- File upload for PDF and Excel files
|
|
26
|
+
- Session soft-delete: count-based cleanup and never evict pinned sessions
|
|
27
|
+
- Usage tooltip total value showing unreadable blue background
|
|
28
|
+
- Workspace file list now collapses on session switch
|
|
29
|
+
- Install script network errors use exit code 2 for better error handling
|
|
30
|
+
|
|
8
31
|
## [1.2.9] - 2026-06-01
|
|
9
32
|
|
|
10
33
|
### Added
|
|
@@ -583,6 +583,9 @@ module Clacky
|
|
|
583
583
|
"exceeds the maximum context", # Portkey & generic gateways
|
|
584
584
|
"exceeds the model's context", # Generic
|
|
585
585
|
"exceeds the model's maximum", # Generic
|
|
586
|
+
"exceeds the available context", # llama.cpp / llama-server
|
|
587
|
+
"available context size", # llama.cpp / llama-server variant
|
|
588
|
+
"try increasing it", # llama.cpp action hint (server.cpp)
|
|
586
589
|
"reduce the length of the input", # Qwen action hint
|
|
587
590
|
"reduce the length of the messages", # OpenAI action hint
|
|
588
591
|
"reduce the length of your", # Generic action hint
|
|
@@ -5,9 +5,10 @@ module Clacky
|
|
|
5
5
|
# Message compression functionality for managing conversation history
|
|
6
6
|
# Handles automatic compression when token limits are exceeded
|
|
7
7
|
module MessageCompressorHelper
|
|
8
|
-
# Compression
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
# Compression behavior knobs.
|
|
9
|
+
# Token & message-count thresholds are owned by AgentConfig — see
|
|
10
|
+
# AgentConfig::DEFAULT_COMPRESSION_THRESHOLD / DEFAULT_MESSAGE_COUNT_THRESHOLD.
|
|
11
|
+
# The constants below are tuning parameters not currently exposed as user config.
|
|
11
12
|
MAX_RECENT_MESSAGES = 20 # Keep this many recent message pairs intact
|
|
12
13
|
TARGET_COMPRESSED_TOKENS = 10_000 # Target size after compression
|
|
13
14
|
IDLE_COMPRESSION_THRESHOLD = 20_000 # Minimum messages needed for idle compression
|
|
@@ -141,8 +142,8 @@ module Clacky
|
|
|
141
142
|
else
|
|
142
143
|
# Normal compression - check thresholds
|
|
143
144
|
# Either: token count exceeds threshold OR message count exceeds threshold
|
|
144
|
-
token_threshold_exceeded = total_tokens >=
|
|
145
|
-
message_count_exceeded = message_count >=
|
|
145
|
+
token_threshold_exceeded = total_tokens >= @config.compression_threshold
|
|
146
|
+
message_count_exceeded = message_count >= @config.message_count_threshold
|
|
146
147
|
|
|
147
148
|
# Only compress if we exceed at least one threshold
|
|
148
149
|
return nil unless token_threshold_exceeded || message_count_exceeded
|
|
@@ -25,6 +25,9 @@ module Clacky
|
|
|
25
25
|
# Restore source; fall back to :manual for sessions saved before this field existed
|
|
26
26
|
@source = (session_data[:source] || "manual").to_sym
|
|
27
27
|
|
|
28
|
+
# Restore channel info for IM platform sessions
|
|
29
|
+
@channel_info = session_data[:channel_info]
|
|
30
|
+
|
|
28
31
|
# Restore cache statistics if available
|
|
29
32
|
@cache_stats = session_data.dig(:stats, :cache_stats) || {
|
|
30
33
|
cache_creation_input_tokens: 0,
|
|
@@ -158,6 +161,7 @@ module Clacky
|
|
|
158
161
|
model_base_url: persisted_card_field("base_url"),
|
|
159
162
|
sub_model: @config.session_model_overlay_name
|
|
160
163
|
},
|
|
164
|
+
channel_info: @channel_info,
|
|
161
165
|
stats: stats_data,
|
|
162
166
|
messages: @history.to_a
|
|
163
167
|
}
|
data/lib/clacky/agent.rb
CHANGED
|
@@ -46,6 +46,7 @@ module Clacky
|
|
|
46
46
|
:latest_latency, # Hash of latency metrics from the most recent LLM call (see Client#send_messages_with_tools)
|
|
47
47
|
:reasoning_effort
|
|
48
48
|
attr_accessor :pinned
|
|
49
|
+
attr_accessor :channel_info
|
|
49
50
|
|
|
50
51
|
REASONING_EFFORTS = %w[low medium high].freeze
|
|
51
52
|
|
|
@@ -72,6 +73,7 @@ module Clacky
|
|
|
72
73
|
@config = config.is_a?(AgentConfig) ? config : AgentConfig.new(config)
|
|
73
74
|
@agent_profile = AgentProfile.load(profile)
|
|
74
75
|
@source = source.to_sym # :manual | :cron | :channel
|
|
76
|
+
@channel_info = nil # { platform:, user_id:, user_name:, chat_id: } set by ChannelManager
|
|
75
77
|
@tool_registry = ToolRegistry.new
|
|
76
78
|
@hooks = HookManager.new
|
|
77
79
|
@session_id = session_id
|
|
@@ -1593,6 +1595,13 @@ module Clacky
|
|
|
1593
1595
|
desktop ? "Desktop: #{desktop}" : nil,
|
|
1594
1596
|
"Working directory: #{@working_dir}"
|
|
1595
1597
|
].compact.join(". ")
|
|
1598
|
+
if @channel_info
|
|
1599
|
+
platform = @channel_info[:platform].to_s
|
|
1600
|
+
user_id = @channel_info[:user_id].to_s
|
|
1601
|
+
user_name = @channel_info[:user_name].to_s
|
|
1602
|
+
sender = user_name.empty? ? user_id : "@#{user_name}(#{user_id})"
|
|
1603
|
+
parts = "#{parts}. Channel: #{platform}, Sender: #{sender}"
|
|
1604
|
+
end
|
|
1596
1605
|
|
|
1597
1606
|
content = "[Session context: #{parts}]"
|
|
1598
1607
|
|
data/lib/clacky/agent_config.rb
CHANGED
|
@@ -151,8 +151,16 @@ module Clacky
|
|
|
151
151
|
|
|
152
152
|
PERMISSION_MODES = [:auto_approve, :confirm_safes, :confirm_all].freeze
|
|
153
153
|
|
|
154
|
+
# Conversation-history compression defaults. Both are user-configurable
|
|
155
|
+
# via `settings.compression_threshold` / `settings.message_count_threshold`
|
|
156
|
+
# in ~/.clacky/config.yml — local-model users (llama.cpp / ollama / vllm)
|
|
157
|
+
# typically lower compression_threshold to fit their server's context window.
|
|
158
|
+
DEFAULT_COMPRESSION_THRESHOLD = 150_000
|
|
159
|
+
DEFAULT_MESSAGE_COUNT_THRESHOLD = 200
|
|
160
|
+
|
|
154
161
|
attr_accessor :permission_mode, :max_tokens, :verbose,
|
|
155
162
|
:enable_compression, :enable_prompt_caching,
|
|
163
|
+
:compression_threshold, :message_count_threshold,
|
|
156
164
|
:models, :current_model_index, :current_model_id,
|
|
157
165
|
:memory_update_enabled, :skill_evolution,
|
|
158
166
|
:max_running_agents, :max_idle_agents,
|
|
@@ -165,6 +173,13 @@ module Clacky
|
|
|
165
173
|
@enable_compression = options[:enable_compression].nil? ? true : options[:enable_compression]
|
|
166
174
|
# Enable prompt caching by default for cost savings
|
|
167
175
|
@enable_prompt_caching = options[:enable_prompt_caching].nil? ? true : options[:enable_prompt_caching]
|
|
176
|
+
# Token threshold that triggers proactive history compression. Local models
|
|
177
|
+
# (llama.cpp, ollama, vllm) often have small context windows (e.g. 64k);
|
|
178
|
+
# users with such setups should lower this to avoid hitting the server-side ceiling.
|
|
179
|
+
@compression_threshold = options[:compression_threshold] || DEFAULT_COMPRESSION_THRESHOLD
|
|
180
|
+
# Message-count threshold that also triggers compression, independent of token count.
|
|
181
|
+
# Guards against pathological histories with many tiny messages.
|
|
182
|
+
@message_count_threshold = options[:message_count_threshold] || DEFAULT_MESSAGE_COUNT_THRESHOLD
|
|
168
183
|
|
|
169
184
|
# Models configuration
|
|
170
185
|
@models = options[:models] || []
|
|
@@ -387,7 +402,9 @@ module Clacky
|
|
|
387
402
|
# Settings keys that are persisted to config.yml.
|
|
388
403
|
# These map directly to AgentConfig accessors.
|
|
389
404
|
CONFIG_SETTINGS_KEYS = %w[
|
|
390
|
-
enable_compression enable_prompt_caching
|
|
405
|
+
enable_compression enable_prompt_caching
|
|
406
|
+
compression_threshold message_count_threshold
|
|
407
|
+
memory_update_enabled
|
|
391
408
|
skill_evolution max_running_agents max_idle_agents
|
|
392
409
|
default_working_dir
|
|
393
410
|
].freeze
|
|
@@ -402,6 +419,8 @@ module Clacky
|
|
|
402
419
|
settings = {
|
|
403
420
|
"enable_compression" => @enable_compression,
|
|
404
421
|
"enable_prompt_caching" => @enable_prompt_caching,
|
|
422
|
+
"compression_threshold" => @compression_threshold,
|
|
423
|
+
"message_count_threshold" => @message_count_threshold,
|
|
405
424
|
"memory_update_enabled" => @memory_update_enabled,
|
|
406
425
|
"skill_evolution" => @skill_evolution,
|
|
407
426
|
"max_running_agents" => @max_running_agents,
|
data/lib/clacky/brand_config.rb
CHANGED
data/lib/clacky/cli.rb
CHANGED
|
@@ -53,6 +53,7 @@ module Clacky
|
|
|
53
53
|
option :list, type: :boolean, aliases: "-l", desc: "List recent sessions"
|
|
54
54
|
option :attach, type: :string, aliases: "-a", desc: "Attach to session by number or keyword"
|
|
55
55
|
option :json, type: :boolean, default: false, desc: "Output NDJSON to stdout (for scripting/piping)"
|
|
56
|
+
option :ui, type: :string, default: nil, desc: "Interactive UI implementation: ui2, rich (default: ui2)"
|
|
56
57
|
option :message, type: :string, aliases: "-m", desc: "Run non-interactively with this message and exit"
|
|
57
58
|
option :file, type: :array, aliases: "-f", desc: "File path(s) to attach (use with -m; supports images and documents)"
|
|
58
59
|
option :image, type: :array, aliases: "-i", desc: "Image file path(s) to attach (alias for --file, kept for compatibility)"
|
|
@@ -725,27 +726,47 @@ module Clacky
|
|
|
725
726
|
# Brand license check — must happen before UI2 starts (raw terminal mode conflict)
|
|
726
727
|
check_brand_license_cli
|
|
727
728
|
|
|
728
|
-
|
|
729
|
-
is_dark_bg = UI2::TerminalDetector.detect_dark_background
|
|
729
|
+
ui_name = (options[:ui] || ENV["OPENCLACKY_UI"] || "ui2").to_s
|
|
730
730
|
|
|
731
|
-
|
|
732
|
-
|
|
731
|
+
ui_controller = if ui_name == "rich"
|
|
732
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.6.0")
|
|
733
|
+
say "Error: Rich UI requires Ruby >= 2.6. Use --ui ui2 on Ruby #{RUBY_VERSION}.", :red
|
|
734
|
+
exit 1
|
|
735
|
+
end
|
|
736
|
+
require_relative "rich_ui_controller"
|
|
737
|
+
RichUIController.new(
|
|
738
|
+
working_dir: working_dir,
|
|
739
|
+
mode: agent_config.permission_mode.to_s,
|
|
740
|
+
model: agent_config.model_name,
|
|
741
|
+
theme: options[:theme]
|
|
742
|
+
)
|
|
743
|
+
else
|
|
744
|
+
unless ui_name == "ui2"
|
|
745
|
+
say "Error: Unknown UI '#{ui_name}'. Available UIs: ui2, rich", :red
|
|
746
|
+
exit 1
|
|
747
|
+
end
|
|
748
|
+
# Detect terminal background BEFORE starting UI2 to avoid output interference
|
|
749
|
+
is_dark_bg = UI2::TerminalDetector.detect_dark_background
|
|
733
750
|
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
available_themes = UI2::ThemeManager.available_themes.map(&:to_s)
|
|
737
|
-
unless available_themes.include?(theme_name)
|
|
738
|
-
say "Error: Unknown theme '#{theme_name}'. Available themes: #{available_themes.join(', ')}", :red
|
|
739
|
-
exit 1
|
|
740
|
-
end
|
|
751
|
+
# Pass detected background mode to theme manager (singleton)
|
|
752
|
+
UI2::ThemeManager.instance.set_background_mode(is_dark_bg)
|
|
741
753
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
754
|
+
# Validate theme
|
|
755
|
+
theme_name = options[:theme] || "hacker"
|
|
756
|
+
available_themes = UI2::ThemeManager.available_themes.map(&:to_s)
|
|
757
|
+
unless available_themes.include?(theme_name)
|
|
758
|
+
say "Error: Unknown theme '#{theme_name}'. Available themes: #{available_themes.join(', ')}", :red
|
|
759
|
+
exit 1
|
|
760
|
+
end
|
|
761
|
+
|
|
762
|
+
# Create UI2 controller with configuration
|
|
763
|
+
UI2::UIController.new(
|
|
764
|
+
working_dir: working_dir,
|
|
765
|
+
mode: agent_config.permission_mode.to_s,
|
|
766
|
+
model: agent_config.model_name,
|
|
767
|
+
theme: theme_name
|
|
768
|
+
)
|
|
769
|
+
end
|
|
749
770
|
|
|
750
771
|
# Inject UI into agent
|
|
751
772
|
agent.instance_variable_set(:@ui, ui_controller)
|
|
@@ -758,6 +779,7 @@ module Clacky
|
|
|
758
779
|
|
|
759
780
|
# Track current working thread (agent or idle compression that can be interrupted)
|
|
760
781
|
current_task_thread = nil
|
|
782
|
+
shutting_down = false
|
|
761
783
|
|
|
762
784
|
# Idle compression timer - triggers compression after 180s of inactivity
|
|
763
785
|
idle_timer = Clacky::IdleCompressionTimer.new(
|
|
@@ -816,7 +838,9 @@ module Clacky
|
|
|
816
838
|
end
|
|
817
839
|
|
|
818
840
|
# Stop UI and exit
|
|
819
|
-
|
|
841
|
+
shutting_down = true
|
|
842
|
+
idle_timer.shutdown
|
|
843
|
+
ui_controller.stop(clear_screen: true)
|
|
820
844
|
exit(0)
|
|
821
845
|
end
|
|
822
846
|
|
|
@@ -867,7 +891,9 @@ module Clacky
|
|
|
867
891
|
ui_controller.update_todos([])
|
|
868
892
|
next
|
|
869
893
|
when "/exit", "/quit"
|
|
870
|
-
|
|
894
|
+
shutting_down = true
|
|
895
|
+
idle_timer.shutdown
|
|
896
|
+
ui_controller.stop(clear_screen: true)
|
|
871
897
|
exit(0)
|
|
872
898
|
when "/help"
|
|
873
899
|
sleep 0.1
|
|
@@ -909,7 +935,7 @@ module Clacky
|
|
|
909
935
|
ensure
|
|
910
936
|
current_task_thread = nil
|
|
911
937
|
# Start idle timer after agent completes
|
|
912
|
-
idle_timer.start
|
|
938
|
+
idle_timer.start unless shutting_down
|
|
913
939
|
end
|
|
914
940
|
end
|
|
915
941
|
end
|
|
@@ -928,7 +954,8 @@ module Clacky
|
|
|
928
954
|
ui_controller.start_input_loop
|
|
929
955
|
|
|
930
956
|
# Cleanup: kill any running threads
|
|
931
|
-
|
|
957
|
+
shutting_down = true
|
|
958
|
+
idle_timer.shutdown
|
|
932
959
|
current_task_thread&.kill
|
|
933
960
|
|
|
934
961
|
# Save final session state
|
|
@@ -32,6 +32,7 @@ module Clacky
|
|
|
32
32
|
@timer_thread = nil
|
|
33
33
|
@compress_thread = nil
|
|
34
34
|
@mutex = Mutex.new
|
|
35
|
+
@shutdown = false
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
# Start (or restart) the idle timer.
|
|
@@ -39,24 +40,35 @@ module Clacky
|
|
|
39
40
|
def start
|
|
40
41
|
cancel # reset any existing timer
|
|
41
42
|
|
|
42
|
-
@
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
compress_thread
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
@mutex.synchronize do
|
|
44
|
+
return false if @shutdown
|
|
45
|
+
|
|
46
|
+
@timer_thread = Thread.new do
|
|
47
|
+
Thread.current.name = "idle-compression-timer"
|
|
48
|
+
sleep IDLE_DELAY
|
|
49
|
+
next if shutdown?
|
|
50
|
+
|
|
51
|
+
# Register @compress_thread inside the mutex BEFORE the thread starts running,
|
|
52
|
+
# so cancel() can always find and interrupt it even if it fires immediately.
|
|
53
|
+
compress_thread = nil
|
|
54
|
+
@mutex.synchronize do
|
|
55
|
+
unless @shutdown
|
|
56
|
+
compress_thread = Thread.new do
|
|
57
|
+
Thread.current.name = "idle-compression-work"
|
|
58
|
+
run_compression
|
|
59
|
+
end
|
|
60
|
+
@compress_thread = compress_thread
|
|
61
|
+
end
|
|
53
62
|
end
|
|
54
|
-
@compress_thread = compress_thread
|
|
55
|
-
end
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
compress_thread&.join
|
|
65
|
+
@mutex.synchronize { @compress_thread = nil; @timer_thread = nil }
|
|
66
|
+
end
|
|
59
67
|
end
|
|
68
|
+
true
|
|
69
|
+
rescue ThreadError => e
|
|
70
|
+
log("Idle compression timer could not start: #{e.message}", level: :debug)
|
|
71
|
+
false
|
|
60
72
|
end
|
|
61
73
|
|
|
62
74
|
# Cancel the timer and any in-progress compression.
|
|
@@ -81,6 +93,13 @@ module Clacky
|
|
|
81
93
|
compress_thread_to_join&.join(5)
|
|
82
94
|
end
|
|
83
95
|
|
|
96
|
+
# Permanently stop this timer. Used during application shutdown so
|
|
97
|
+
# background agent-thread ensure blocks cannot create new timer threads.
|
|
98
|
+
def shutdown
|
|
99
|
+
@mutex.synchronize { @shutdown = true }
|
|
100
|
+
cancel
|
|
101
|
+
end
|
|
102
|
+
|
|
84
103
|
# True if the timer or compression is currently active.
|
|
85
104
|
def active?
|
|
86
105
|
@mutex.synchronize { @timer_thread&.alive? || @compress_thread&.alive? }
|
|
@@ -94,6 +113,10 @@ module Clacky
|
|
|
94
113
|
@mutex.synchronize { @compress_thread&.alive? || false }
|
|
95
114
|
end
|
|
96
115
|
|
|
116
|
+
def shutdown?
|
|
117
|
+
@mutex.synchronize { @shutdown }
|
|
118
|
+
end
|
|
119
|
+
|
|
97
120
|
private def run_compression
|
|
98
121
|
success = @agent.trigger_idle_compression
|
|
99
122
|
|
data/lib/clacky/providers.rb
CHANGED
|
@@ -170,8 +170,8 @@ module Clacky
|
|
|
170
170
|
"name" => "Minimax",
|
|
171
171
|
"base_url" => "https://api.minimaxi.com/v1",
|
|
172
172
|
"api" => "openai-completions",
|
|
173
|
-
"default_model" => "MiniMax-
|
|
174
|
-
"models" => ["MiniMax-M2.
|
|
173
|
+
"default_model" => "MiniMax-M3",
|
|
174
|
+
"models" => ["MiniMax-M3", "MiniMax-M2.7", "MiniMax-M2.5"],
|
|
175
175
|
# MiniMax operates two regional endpoints with identical APIs & model
|
|
176
176
|
# lineup — mainland China (.com) and international (.io). Listing both
|
|
177
177
|
# lets find_by_base_url identify either one as provider "minimax",
|
|
@@ -182,7 +182,12 @@ module Clacky
|
|
|
182
182
|
{ "label" => "International", "label_key" => "settings.models.baseurl.variant.international", "base_url" => "https://api.minimax.io/v1", "region" => "intl" }.freeze
|
|
183
183
|
].freeze,
|
|
184
184
|
# MiniMax M2.x does not support multimodal/vision input on this endpoint.
|
|
185
|
+
# M3 (released 2026-06-01) is natively multimodal and accepts image
|
|
186
|
+
# input, so it overrides the provider-level vision=false below.
|
|
185
187
|
"capabilities" => { "vision" => false }.freeze,
|
|
188
|
+
"model_capabilities" => {
|
|
189
|
+
"MiniMax-M3" => { "vision" => true }.freeze
|
|
190
|
+
}.freeze,
|
|
186
191
|
"website_url" => "https://www.minimaxi.com/user-center/basic-information/interface-key"
|
|
187
192
|
}.freeze,
|
|
188
193
|
|