openclacky 1.2.8 → 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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/lib/clacky/agent/llm_caller.rb +3 -0
  4. data/lib/clacky/agent/message_compressor_helper.rb +6 -5
  5. data/lib/clacky/agent/session_serializer.rb +4 -0
  6. data/lib/clacky/agent.rb +9 -0
  7. data/lib/clacky/agent_config.rb +111 -8
  8. data/lib/clacky/brand_config.rb +1 -0
  9. data/lib/clacky/cli.rb +49 -22
  10. data/lib/clacky/client.rb +6 -2
  11. data/lib/clacky/default_skills/channel-manager/SKILL.md +33 -110
  12. data/lib/clacky/default_skills/media-gen/SKILL.md +128 -0
  13. data/lib/clacky/idle_compression_timer.rb +38 -15
  14. data/lib/clacky/media/base.rb +68 -0
  15. data/lib/clacky/media/gemini.rb +36 -0
  16. data/lib/clacky/media/generator.rb +78 -0
  17. data/lib/clacky/media/openai_compat.rb +168 -0
  18. data/lib/clacky/providers.rb +89 -2
  19. data/lib/clacky/rich_ui_controller.rb +1549 -0
  20. data/lib/clacky/server/channel/adapters/weixin/adapter.rb +24 -2
  21. data/lib/clacky/server/channel/channel_manager.rb +89 -2
  22. data/lib/clacky/server/http_server.rb +334 -29
  23. data/lib/clacky/session_manager.rb +9 -8
  24. data/lib/clacky/telemetry.rb +26 -6
  25. data/lib/clacky/ui2/layout_manager.rb +11 -7
  26. data/lib/clacky/ui2/ui_controller.rb +2 -2
  27. data/lib/clacky/ui_interface.rb +1 -1
  28. data/lib/clacky/utils/model_pricing.rb +75 -53
  29. data/lib/clacky/version.rb +1 -1
  30. data/lib/clacky/web/app.css +393 -14
  31. data/lib/clacky/web/billing.js +1 -1
  32. data/lib/clacky/web/i18n.js +86 -4
  33. data/lib/clacky/web/index.html +23 -3
  34. data/lib/clacky/web/model-tester.js +58 -0
  35. data/lib/clacky/web/onboard.js +17 -30
  36. data/lib/clacky/web/sessions.js +443 -2
  37. data/lib/clacky/web/settings.js +372 -97
  38. data/lib/clacky/web/workspace.js +9 -1
  39. data/lib/clacky.rb +3 -0
  40. data/scripts/build/lib/network.sh +61 -30
  41. data/scripts/install.ps1 +16 -4
  42. data/scripts/install.sh +61 -30
  43. data/scripts/install_browser.sh +61 -30
  44. data/scripts/install_full.sh +61 -30
  45. data/scripts/install_rails_deps.sh +61 -30
  46. data/scripts/install_system_deps.sh +61 -30
  47. metadata +12 -3
  48. data/lib/clacky/default_skills/channel-manager/feishu_setup.rb +0 -574
@@ -41,6 +41,17 @@ module Clacky
41
41
  "dsk-deepseek-v4-flash",
42
42
  "or-gemini-3-1-pro"
43
43
  ],
44
+ # Image generation models served by the openclacky platform
45
+ # gateway. The gateway exposes a standard OpenAI-compatible
46
+ # /v1/images/generations endpoint, so the same OpenAICompat
47
+ # provider class handles them. `or-` prefix mirrors the chat
48
+ # model naming — these are routed through the OpenRouter
49
+ # backend by the platform.
50
+ "image_models" => [
51
+ "or-gemini-3-pro-image",
52
+ "or-gpt-image-2"
53
+ ],
54
+ "default_image_model" => "or-gpt-image-2",
44
55
  # Provider-level default: the Claude family served here is vision-capable.
45
56
  "capabilities" => { "vision" => true }.freeze,
46
57
  # Model-level overrides: DeepSeek models routed through this provider
@@ -123,6 +134,13 @@ module Clacky
123
134
  /\Aanthropic\// => "anthropic-messages",
124
135
  /\Aclaude[-.]/ => "anthropic-messages"
125
136
  }.freeze,
137
+ # Image generation via OpenRouter is currently routed through the
138
+ # openclacky platform gateway (see "openclacky" provider above) which
139
+ # handles the OpenRouter chat-completions + modalities translation.
140
+ # Direct OpenRouter image config is not exposed here — leave empty
141
+ # until we ship a dedicated client-side adapter for that protocol.
142
+ "image_models" => [],
143
+ "default_image_model" => nil,
126
144
  "website_url" => "https://openrouter.ai/keys"
127
145
  }.freeze,
128
146
 
@@ -152,8 +170,8 @@ module Clacky
152
170
  "name" => "Minimax",
153
171
  "base_url" => "https://api.minimaxi.com/v1",
154
172
  "api" => "openai-completions",
155
- "default_model" => "MiniMax-M2.7",
156
- "models" => ["MiniMax-M2.5", "MiniMax-M2.7"],
173
+ "default_model" => "MiniMax-M3",
174
+ "models" => ["MiniMax-M3", "MiniMax-M2.7", "MiniMax-M2.5"],
157
175
  # MiniMax operates two regional endpoints with identical APIs & model
158
176
  # lineup — mainland China (.com) and international (.io). Listing both
159
177
  # lets find_by_base_url identify either one as provider "minimax",
@@ -164,7 +182,12 @@ module Clacky
164
182
  { "label" => "International", "label_key" => "settings.models.baseurl.variant.international", "base_url" => "https://api.minimax.io/v1", "region" => "intl" }.freeze
165
183
  ].freeze,
166
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.
167
187
  "capabilities" => { "vision" => false }.freeze,
188
+ "model_capabilities" => {
189
+ "MiniMax-M3" => { "vision" => true }.freeze
190
+ }.freeze,
168
191
  "website_url" => "https://www.minimaxi.com/user-center/basic-information/interface-key"
169
192
  }.freeze,
170
193
 
@@ -305,6 +328,12 @@ module Clacky
305
328
  "gpt-5.5" => "gpt-5.4-mini",
306
329
  "gpt-5.4" => "gpt-5.4-mini"
307
330
  },
331
+ # OpenAI's image generation model — same /v1/images/generations
332
+ # endpoint, so the OpenAICompat image provider handles it.
333
+ "image_models" => [
334
+ "gpt-image-2"
335
+ ],
336
+ "default_image_model" => "gpt-image-2",
308
337
  "website_url" => "https://platform.openai.com/api-keys"
309
338
  }.freeze,
310
339
 
@@ -342,6 +371,8 @@ module Clacky
342
371
 
343
372
  }.freeze
344
373
 
374
+ MEDIA_KINDS = %w[image video audio].freeze
375
+
345
376
  class << self
346
377
  # Check if a provider preset exists
347
378
  # @param provider_id [String] The provider identifier (e.g., "anthropic", "openrouter")
@@ -446,6 +477,62 @@ module Clacky
446
477
  preset&.dig("models") || []
447
478
  end
448
479
 
480
+ # Get available image generation models for a provider.
481
+ # Returns an empty array when the provider doesn't declare any —
482
+ # callers should treat that as "image generation not supported by this provider".
483
+ # @param provider_id [String] The provider identifier
484
+ # @return [Array<String>] List of image model names
485
+ def image_models(provider_id)
486
+ preset = PRESETS[provider_id]
487
+ preset&.dig("image_models") || []
488
+ end
489
+
490
+ # Video generation models — placeholder. No provider supports video
491
+ # via Clacky yet; once they do, declare "video_models" alongside
492
+ # "image_models" in the relevant PRESETS entry and this returns it.
493
+ def video_models(provider_id)
494
+ preset = PRESETS[provider_id]
495
+ preset&.dig("video_models") || []
496
+ end
497
+
498
+ # Audio generation models — same placeholder pattern as video_models.
499
+ def audio_models(provider_id)
500
+ preset = PRESETS[provider_id]
501
+ preset&.dig("audio_models") || []
502
+ end
503
+
504
+ # Unified entry for media model lookup by kind.
505
+ # @param provider_id [String]
506
+ # @param kind [String] one of "image" / "video" / "audio"
507
+ # @return [Array<String>]
508
+ def media_models(provider_id, kind)
509
+ case kind.to_s
510
+ when "image" then image_models(provider_id)
511
+ when "video" then video_models(provider_id)
512
+ when "audio" then audio_models(provider_id)
513
+ else []
514
+ end
515
+ end
516
+
517
+ # Default media model for a kind under a provider. Falls back to the
518
+ # first declared model when no explicit default is set in the preset.
519
+ # Used by AgentConfig#derive_media_models! to pick which model to
520
+ # surface when the user is on "auto" mode.
521
+ def default_media_model(provider_id, kind)
522
+ preset = PRESETS[provider_id]
523
+ return nil unless preset
524
+ explicit = preset["default_#{kind}_model"]
525
+ return explicit if explicit
526
+ media_models(provider_id, kind).first
527
+ end
528
+
529
+ # The set of media kinds Clacky knows about. Drives UI rendering and
530
+ # derivation loops — adding a new modality means listing it here plus
531
+ # adding the corresponding generator class.
532
+ def media_kinds
533
+ MEDIA_KINDS
534
+ end
535
+
449
536
  # Get the lite model for a provider.
450
537
  # @param provider_id [String] The provider identifier
451
538
  # @param primary_model [String, nil] The currently-selected primary model name.