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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -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 +111 -8
- data/lib/clacky/brand_config.rb +1 -0
- data/lib/clacky/cli.rb +49 -22
- data/lib/clacky/client.rb +6 -2
- data/lib/clacky/default_skills/channel-manager/SKILL.md +33 -110
- data/lib/clacky/default_skills/media-gen/SKILL.md +128 -0
- data/lib/clacky/idle_compression_timer.rb +38 -15
- data/lib/clacky/media/base.rb +68 -0
- data/lib/clacky/media/gemini.rb +36 -0
- data/lib/clacky/media/generator.rb +78 -0
- data/lib/clacky/media/openai_compat.rb +168 -0
- data/lib/clacky/providers.rb +89 -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 +334 -29
- data/lib/clacky/session_manager.rb +9 -8
- data/lib/clacky/telemetry.rb +26 -6
- 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 +393 -14
- data/lib/clacky/web/billing.js +1 -1
- data/lib/clacky/web/i18n.js +86 -4
- data/lib/clacky/web/index.html +23 -3
- data/lib/clacky/web/model-tester.js +58 -0
- data/lib/clacky/web/onboard.js +17 -30
- data/lib/clacky/web/sessions.js +443 -2
- data/lib/clacky/web/settings.js +372 -97
- data/lib/clacky/web/workspace.js +9 -1
- data/lib/clacky.rb +3 -0
- data/scripts/build/lib/network.sh +61 -30
- data/scripts/install.ps1 +16 -4
- data/scripts/install.sh +61 -30
- data/scripts/install_browser.sh +61 -30
- data/scripts/install_full.sh +61 -30
- data/scripts/install_rails_deps.sh +61 -30
- data/scripts/install_system_deps.sh +61 -30
- metadata +12 -3
- data/lib/clacky/default_skills/channel-manager/feishu_setup.rb +0 -574
data/lib/clacky/web/app.css
CHANGED
|
@@ -3858,6 +3858,7 @@ body {
|
|
|
3858
3858
|
.model-card-grid-actions {
|
|
3859
3859
|
display: flex;
|
|
3860
3860
|
flex-direction: row;
|
|
3861
|
+
align-items: center;
|
|
3861
3862
|
flex-wrap: wrap;
|
|
3862
3863
|
gap: 0.5rem;
|
|
3863
3864
|
padding-top: 0.625rem;
|
|
@@ -3867,7 +3868,7 @@ body {
|
|
|
3867
3868
|
display: inline-flex;
|
|
3868
3869
|
align-items: center;
|
|
3869
3870
|
justify-content: center;
|
|
3870
|
-
gap: 0.
|
|
3871
|
+
gap: 0.3125rem;
|
|
3871
3872
|
padding: 0.375rem 0.5rem;
|
|
3872
3873
|
border: 1px solid var(--color-border-primary);
|
|
3873
3874
|
border-radius: 6px;
|
|
@@ -3877,15 +3878,9 @@ body {
|
|
|
3877
3878
|
cursor: pointer;
|
|
3878
3879
|
transition: all 0.15s;
|
|
3879
3880
|
white-space: nowrap;
|
|
3881
|
+
min-width: 0;
|
|
3880
3882
|
}
|
|
3881
|
-
.btn-card-grid-action svg {
|
|
3882
|
-
flex-shrink: 0;
|
|
3883
|
-
}
|
|
3884
|
-
.btn-card-grid-action span {
|
|
3885
|
-
overflow: hidden;
|
|
3886
|
-
text-overflow: ellipsis;
|
|
3887
|
-
white-space: nowrap;
|
|
3888
|
-
}
|
|
3883
|
+
.btn-card-grid-action svg { flex-shrink: 0; }
|
|
3889
3884
|
.btn-card-grid-action:hover:not(:disabled) {
|
|
3890
3885
|
border-color: var(--color-accent-primary);
|
|
3891
3886
|
color: var(--color-accent-primary);
|
|
@@ -3895,13 +3890,22 @@ body {
|
|
|
3895
3890
|
opacity: 0.5;
|
|
3896
3891
|
cursor: not-allowed;
|
|
3897
3892
|
}
|
|
3893
|
+
.btn-card-grid-action-primary {
|
|
3894
|
+
background: var(--color-bg-secondary);
|
|
3895
|
+
color: var(--color-text-primary);
|
|
3896
|
+
font-weight: 500;
|
|
3897
|
+
}
|
|
3898
3898
|
.btn-card-grid-action-danger:hover:not(:disabled) {
|
|
3899
3899
|
border-color: var(--color-error);
|
|
3900
3900
|
color: var(--color-error);
|
|
3901
3901
|
background: color-mix(in srgb, var(--color-error) 8%, transparent);
|
|
3902
3902
|
}
|
|
3903
|
-
|
|
3904
|
-
|
|
3903
|
+
.model-card-grid-toolbar {
|
|
3904
|
+
display: flex;
|
|
3905
|
+
flex-wrap: wrap;
|
|
3906
|
+
gap: 0.375rem;
|
|
3907
|
+
margin-left: auto;
|
|
3908
|
+
justify-content: flex-end;
|
|
3905
3909
|
}
|
|
3906
3910
|
.model-card-grid-footer {
|
|
3907
3911
|
display: flex;
|
|
@@ -4104,6 +4108,175 @@ a.btn-card-grid-action {
|
|
|
4104
4108
|
border-color: var(--color-border-secondary);
|
|
4105
4109
|
}
|
|
4106
4110
|
|
|
4111
|
+
/* ── Directory Picker Modal (tree-based) ─────────────────────────────────── */
|
|
4112
|
+
.modal-title {
|
|
4113
|
+
padding: 1rem 1.25rem;
|
|
4114
|
+
border-bottom: 1px solid var(--color-border-primary);
|
|
4115
|
+
font-size: 1.0625rem;
|
|
4116
|
+
font-weight: 600;
|
|
4117
|
+
color: var(--color-text-primary);
|
|
4118
|
+
}
|
|
4119
|
+
.modal-buttons {
|
|
4120
|
+
display: flex;
|
|
4121
|
+
align-items: center;
|
|
4122
|
+
justify-content: flex-end;
|
|
4123
|
+
gap: 0.625rem;
|
|
4124
|
+
padding: 1rem 1.25rem;
|
|
4125
|
+
border-top: 1px solid var(--color-border-primary);
|
|
4126
|
+
}
|
|
4127
|
+
.dir-picker-input {
|
|
4128
|
+
width: 100%;
|
|
4129
|
+
padding: 0.5rem 0.75rem;
|
|
4130
|
+
border: 1px solid var(--color-border-primary);
|
|
4131
|
+
border-radius: 6px;
|
|
4132
|
+
background: var(--color-bg-primary);
|
|
4133
|
+
color: var(--color-text-primary);
|
|
4134
|
+
font-size: 0.875rem;
|
|
4135
|
+
font-family: var(--font-mono, monospace);
|
|
4136
|
+
transition: border-color 0.15s;
|
|
4137
|
+
box-sizing: border-box;
|
|
4138
|
+
}.dir-picker-input:focus {
|
|
4139
|
+
outline: none;
|
|
4140
|
+
border-color: var(--color-accent);
|
|
4141
|
+
}
|
|
4142
|
+
.dir-picker-input::placeholder {
|
|
4143
|
+
color: var(--color-text-tertiary);
|
|
4144
|
+
}
|
|
4145
|
+
/* Preset buttons row */
|
|
4146
|
+
.dp-presets {
|
|
4147
|
+
display: flex;
|
|
4148
|
+
gap: 0.5rem;
|
|
4149
|
+
flex-wrap: wrap;
|
|
4150
|
+
}
|
|
4151
|
+
.dp-presets .btn-sm {
|
|
4152
|
+
padding: 0.25rem 0.625rem;
|
|
4153
|
+
font-size: 0.75rem;
|
|
4154
|
+
}
|
|
4155
|
+
/* Path input container */
|
|
4156
|
+
.dp-path-container {
|
|
4157
|
+
flex-shrink: 0;
|
|
4158
|
+
position: relative;
|
|
4159
|
+
}/* Autocomplete dropdown */
|
|
4160
|
+
.dp-autocomplete {
|
|
4161
|
+
position: absolute;
|
|
4162
|
+
top: 100%;
|
|
4163
|
+
left: 0;
|
|
4164
|
+
right: 0;
|
|
4165
|
+
z-index: 10;
|
|
4166
|
+
max-height: 200px;
|
|
4167
|
+
overflow-y: auto;
|
|
4168
|
+
background: var(--color-bg-primary);
|
|
4169
|
+
border: 1px solid var(--color-border-primary);
|
|
4170
|
+
border-top: none;
|
|
4171
|
+
border-radius: 0 0 6px 6px;
|
|
4172
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
4173
|
+
}
|
|
4174
|
+
.dp-ac-item {
|
|
4175
|
+
display: flex;
|
|
4176
|
+
align-items: center;
|
|
4177
|
+
gap: 0.5rem;
|
|
4178
|
+
padding: 0.4rem 0.75rem;
|
|
4179
|
+
cursor: pointer;
|
|
4180
|
+
font-size: 0.8125rem;
|
|
4181
|
+
color: var(--color-text-primary);
|
|
4182
|
+
transition: background 0.1s;
|
|
4183
|
+
}
|
|
4184
|
+
.dp-ac-item:hover,
|
|
4185
|
+
.dp-ac-item.active {
|
|
4186
|
+
background: var(--color-bg-hover);
|
|
4187
|
+
}
|
|
4188
|
+
.dp-ac-icon {
|
|
4189
|
+
display: inline-flex;
|
|
4190
|
+
align-items: center;
|
|
4191
|
+
flex-shrink: 0;
|
|
4192
|
+
color: var(--color-text-secondary);
|
|
4193
|
+
}
|
|
4194
|
+
.dp-ac-name {
|
|
4195
|
+
overflow: hidden;
|
|
4196
|
+
text-overflow: ellipsis;
|
|
4197
|
+
white-space: nowrap;
|
|
4198
|
+
}
|
|
4199
|
+
/* Tree container */
|
|
4200
|
+
.dp-tree {
|
|
4201
|
+
border: 1px solid var(--color-border-primary);
|
|
4202
|
+
border-radius: 6px;
|
|
4203
|
+
background: var(--color-bg-secondary);
|
|
4204
|
+
min-height: 200px;
|
|
4205
|
+
max-height: 340px;
|
|
4206
|
+
overflow: auto;
|
|
4207
|
+
font-size: 0.8125rem;
|
|
4208
|
+
}
|
|
4209
|
+
/* Tree node */
|
|
4210
|
+
.dp-node {
|
|
4211
|
+
user-select: none;
|
|
4212
|
+
}
|
|
4213
|
+
.dp-row {
|
|
4214
|
+
display: flex;
|
|
4215
|
+
align-items: center;
|
|
4216
|
+
gap: 0.375rem;
|
|
4217
|
+
padding: 0.375rem 0.5rem;
|
|
4218
|
+
cursor: pointer;
|
|
4219
|
+
border-radius: 4px;
|
|
4220
|
+
transition: background 0.1s;
|
|
4221
|
+
}
|
|
4222
|
+
.dp-row:hover {
|
|
4223
|
+
background: var(--color-bg-hover);
|
|
4224
|
+
}
|
|
4225
|
+
.dp-row.selected {
|
|
4226
|
+
background: var(--color-accent-subtle, rgba(59, 130, 246, 0.12));
|
|
4227
|
+
}
|
|
4228
|
+
.dp-row.selected .dp-name {
|
|
4229
|
+
color: var(--color-accent);
|
|
4230
|
+
font-weight: 500;
|
|
4231
|
+
}
|
|
4232
|
+
/* Caret */
|
|
4233
|
+
.dp-caret {
|
|
4234
|
+
display: inline-flex;
|
|
4235
|
+
align-items: center;
|
|
4236
|
+
justify-content: center;
|
|
4237
|
+
width: 16px;
|
|
4238
|
+
height: 16px;
|
|
4239
|
+
flex-shrink: 0;
|
|
4240
|
+
color: var(--color-text-tertiary);
|
|
4241
|
+
transition: transform 0.15s;
|
|
4242
|
+
}
|
|
4243
|
+
.dp-caret.open {
|
|
4244
|
+
transform: rotate(90deg);
|
|
4245
|
+
}
|
|
4246
|
+
/* Folder icon */
|
|
4247
|
+
.dp-icon {
|
|
4248
|
+
display: inline-flex;
|
|
4249
|
+
align-items: center;
|
|
4250
|
+
flex-shrink: 0;
|
|
4251
|
+
color: var(--color-text-secondary);
|
|
4252
|
+
}
|
|
4253
|
+
.dp-row.selected .dp-icon {
|
|
4254
|
+
color: var(--color-accent);
|
|
4255
|
+
}
|
|
4256
|
+
/* Name */
|
|
4257
|
+
.dp-name {
|
|
4258
|
+
flex: 1;
|
|
4259
|
+
overflow: hidden;
|
|
4260
|
+
text-overflow: ellipsis;
|
|
4261
|
+
white-space: nowrap;
|
|
4262
|
+
color: var(--color-text-primary);
|
|
4263
|
+
}
|
|
4264
|
+
/* Children container */
|
|
4265
|
+
.dp-children {
|
|
4266
|
+
display: flex;
|
|
4267
|
+
flex-direction: column;
|
|
4268
|
+
}/* Loading / empty / error states */
|
|
4269
|
+
.dp-loading,
|
|
4270
|
+
.dp-empty,
|
|
4271
|
+
.dp-error {
|
|
4272
|
+
padding: 0.5rem 1rem;
|
|
4273
|
+
color: var(--color-text-tertiary);
|
|
4274
|
+
font-size: 0.75rem;
|
|
4275
|
+
font-style: italic;
|
|
4276
|
+
}
|
|
4277
|
+
.dp-error {
|
|
4278
|
+
color: var(--color-text-danger, #ef4444);
|
|
4279
|
+
}
|
|
4107
4280
|
/* Model name combobox */
|
|
4108
4281
|
.model-name-combobox {
|
|
4109
4282
|
position: relative;
|
|
@@ -9065,11 +9238,14 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9065
9238
|
.tooltip-date {
|
|
9066
9239
|
font-weight: 600;
|
|
9067
9240
|
color: var(--color-text-primary);
|
|
9241
|
+
white-space: nowrap;
|
|
9068
9242
|
}
|
|
9069
|
-
.tooltip-total {
|
|
9243
|
+
.tooltip-total-value {
|
|
9070
9244
|
font-size: 0.875rem;
|
|
9071
9245
|
color: var(--color-accent);
|
|
9072
|
-
font-weight:
|
|
9246
|
+
font-weight: 600;
|
|
9247
|
+
white-space: nowrap;
|
|
9248
|
+
margin-left: 0.75rem;
|
|
9073
9249
|
}
|
|
9074
9250
|
.tooltip-row {
|
|
9075
9251
|
display: flex;
|
|
@@ -9567,6 +9743,53 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9567
9743
|
color: var(--color-text-secondary);
|
|
9568
9744
|
font-weight: 500;
|
|
9569
9745
|
}
|
|
9746
|
+
.settings-exchange-rate-refresh {
|
|
9747
|
+
display: inline-flex;
|
|
9748
|
+
align-items: center;
|
|
9749
|
+
justify-content: center;
|
|
9750
|
+
gap: 0.35rem;
|
|
9751
|
+
min-height: 34px;
|
|
9752
|
+
padding: 0.45rem 0.8rem;
|
|
9753
|
+
border: 1px solid color-mix(in srgb, var(--color-accent-primary) 28%, var(--color-border));
|
|
9754
|
+
border-radius: 999px;
|
|
9755
|
+
background: color-mix(in srgb, var(--color-accent-primary) 8%, var(--color-bg-secondary));
|
|
9756
|
+
color: var(--color-accent-primary);
|
|
9757
|
+
font-size: 0.8125rem;
|
|
9758
|
+
font-weight: 600;
|
|
9759
|
+
line-height: 1;
|
|
9760
|
+
white-space: nowrap;
|
|
9761
|
+
cursor: pointer;
|
|
9762
|
+
transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
|
|
9763
|
+
}
|
|
9764
|
+
.settings-exchange-rate-refresh svg {
|
|
9765
|
+
flex: 0 0 auto;
|
|
9766
|
+
}
|
|
9767
|
+
.settings-exchange-rate-refresh:hover:not(:disabled) {
|
|
9768
|
+
border-color: color-mix(in srgb, var(--color-accent-primary) 52%, var(--color-border));
|
|
9769
|
+
background: color-mix(in srgb, var(--color-accent-primary) 12%, var(--color-bg-secondary));
|
|
9770
|
+
box-shadow: 0 4px 12px color-mix(in srgb, var(--color-accent-primary) 16%, transparent);
|
|
9771
|
+
transform: translateY(-1px);
|
|
9772
|
+
}
|
|
9773
|
+
.settings-exchange-rate-refresh:active:not(:disabled) {
|
|
9774
|
+
transform: translateY(0);
|
|
9775
|
+
}
|
|
9776
|
+
.settings-exchange-rate-refresh:disabled {
|
|
9777
|
+
opacity: 0.6;
|
|
9778
|
+
cursor: not-allowed;
|
|
9779
|
+
transform: none;
|
|
9780
|
+
}
|
|
9781
|
+
.settings-exchange-rate-status {
|
|
9782
|
+
min-height: 1.1rem;
|
|
9783
|
+
margin-top: 0.4rem;
|
|
9784
|
+
font-size: 0.8125rem;
|
|
9785
|
+
color: var(--color-text-secondary);
|
|
9786
|
+
}
|
|
9787
|
+
.settings-exchange-rate-status.success {
|
|
9788
|
+
color: var(--color-success, #2e7d32);
|
|
9789
|
+
}
|
|
9790
|
+
.settings-exchange-rate-status.error {
|
|
9791
|
+
color: var(--color-error, #d33);
|
|
9792
|
+
}
|
|
9570
9793
|
|
|
9571
9794
|
/* ── Sessions List ───────────────────────────────────────────────────── */
|
|
9572
9795
|
.billing-sessions-row {
|
|
@@ -9710,4 +9933,160 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9710
9933
|
grid-column: 1 / -1;
|
|
9711
9934
|
text-align: right;
|
|
9712
9935
|
}
|
|
9713
|
-
}
|
|
9936
|
+
}
|
|
9937
|
+
|
|
9938
|
+
/* ════ Media generation (Settings → Models tab) ════ */
|
|
9939
|
+
.settings-section-desc {
|
|
9940
|
+
font-size: 0.8125rem;
|
|
9941
|
+
color: var(--color-text-secondary);
|
|
9942
|
+
line-height: 1.5;
|
|
9943
|
+
margin: -0.25rem 0 0.5rem;
|
|
9944
|
+
}
|
|
9945
|
+
.media-row {
|
|
9946
|
+
border: 1px solid var(--color-border-primary);
|
|
9947
|
+
border-radius: 8px;
|
|
9948
|
+
background: var(--color-bg-secondary);
|
|
9949
|
+
margin-bottom: 0.5rem;
|
|
9950
|
+
overflow: hidden;
|
|
9951
|
+
}
|
|
9952
|
+
.media-row.is-expanded {
|
|
9953
|
+
background: var(--color-bg-secondary);
|
|
9954
|
+
}
|
|
9955
|
+
.media-row-head {
|
|
9956
|
+
display: flex;
|
|
9957
|
+
align-items: center;
|
|
9958
|
+
gap: 0.75rem;
|
|
9959
|
+
padding: 0.5rem 0.75rem;
|
|
9960
|
+
min-height: 2.25rem;
|
|
9961
|
+
}
|
|
9962
|
+
.media-row-title {
|
|
9963
|
+
font-size: 0.875rem;
|
|
9964
|
+
font-weight: 600;
|
|
9965
|
+
color: var(--color-text-primary);
|
|
9966
|
+
min-width: 3rem;
|
|
9967
|
+
}
|
|
9968
|
+
.media-row-segmented {
|
|
9969
|
+
display: inline-flex;
|
|
9970
|
+
background: var(--color-bg-primary);
|
|
9971
|
+
border: 1px solid var(--color-border-primary);
|
|
9972
|
+
border-radius: 6px;
|
|
9973
|
+
padding: 1px;
|
|
9974
|
+
}
|
|
9975
|
+
.media-row-segmented button {
|
|
9976
|
+
background: transparent;
|
|
9977
|
+
border: none;
|
|
9978
|
+
padding: 0.25rem 0.625rem;
|
|
9979
|
+
font-size: 0.75rem;
|
|
9980
|
+
color: var(--color-text-secondary);
|
|
9981
|
+
border-radius: 5px;
|
|
9982
|
+
cursor: pointer;
|
|
9983
|
+
transition: background-color 0.15s ease, color 0.15s ease;
|
|
9984
|
+
font-family: inherit;
|
|
9985
|
+
}
|
|
9986
|
+
.media-row-segmented button:hover:not(.is-active):not(:disabled) {
|
|
9987
|
+
color: var(--color-text-primary);
|
|
9988
|
+
}
|
|
9989
|
+
.media-row-segmented button.is-active {
|
|
9990
|
+
background: var(--color-button-primary);
|
|
9991
|
+
color: #fff;
|
|
9992
|
+
}
|
|
9993
|
+
.media-row-segmented button:disabled {
|
|
9994
|
+
opacity: 0.4;
|
|
9995
|
+
cursor: not-allowed;
|
|
9996
|
+
}
|
|
9997
|
+
.media-row-status {
|
|
9998
|
+
margin-left: auto;
|
|
9999
|
+
font-size: 0.75rem;
|
|
10000
|
+
color: var(--color-text-secondary);
|
|
10001
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
10002
|
+
white-space: nowrap;
|
|
10003
|
+
overflow: hidden;
|
|
10004
|
+
text-overflow: ellipsis;
|
|
10005
|
+
max-width: 16rem;
|
|
10006
|
+
}
|
|
10007
|
+
.media-row-detail {
|
|
10008
|
+
border-top: 1px solid var(--color-border-primary);
|
|
10009
|
+
padding: 0.625rem 0.75rem;
|
|
10010
|
+
font-size: 0.8125rem;
|
|
10011
|
+
color: var(--color-text-secondary);
|
|
10012
|
+
line-height: 1.5;
|
|
10013
|
+
background: var(--color-bg-primary);
|
|
10014
|
+
}
|
|
10015
|
+
.media-row-detail.is-warning {
|
|
10016
|
+
color: var(--color-warning, #d97706);
|
|
10017
|
+
}
|
|
10018
|
+
.media-row-hint {
|
|
10019
|
+
margin-top: 0.375rem;
|
|
10020
|
+
font-size: 0.75rem;
|
|
10021
|
+
color: var(--color-text-tertiary, var(--color-text-secondary));
|
|
10022
|
+
}
|
|
10023
|
+
.media-row-detail .media-kv {
|
|
10024
|
+
display: grid;
|
|
10025
|
+
grid-template-columns: max-content 1fr;
|
|
10026
|
+
gap: 0.25rem 0.75rem;
|
|
10027
|
+
font-size: 0.8125rem;
|
|
10028
|
+
}
|
|
10029
|
+
.media-row-detail .media-kv-key {
|
|
10030
|
+
color: var(--color-text-secondary);
|
|
10031
|
+
}
|
|
10032
|
+
.media-row-detail .media-kv-val {
|
|
10033
|
+
color: var(--color-text-primary);
|
|
10034
|
+
font-weight: 500;
|
|
10035
|
+
word-break: break-all;
|
|
10036
|
+
}
|
|
10037
|
+
.media-row-actions {
|
|
10038
|
+
display: flex;
|
|
10039
|
+
gap: 0.5rem;
|
|
10040
|
+
margin-top: 0.5rem;
|
|
10041
|
+
justify-content: flex-end;
|
|
10042
|
+
}
|
|
10043
|
+
.media-row-btn {
|
|
10044
|
+
background: transparent;
|
|
10045
|
+
border: 1px solid var(--color-border-primary);
|
|
10046
|
+
color: var(--color-text-primary);
|
|
10047
|
+
border-radius: 6px;
|
|
10048
|
+
padding: 0.3125rem 0.75rem;
|
|
10049
|
+
font-size: 0.75rem;
|
|
10050
|
+
cursor: pointer;
|
|
10051
|
+
transition: background-color 0.15s ease;
|
|
10052
|
+
font-family: inherit;
|
|
10053
|
+
}
|
|
10054
|
+
.media-row-btn:hover {
|
|
10055
|
+
background: var(--color-bg-secondary);
|
|
10056
|
+
}
|
|
10057
|
+
.media-row-btn.is-primary {
|
|
10058
|
+
background: var(--color-button-primary);
|
|
10059
|
+
color: #fff;
|
|
10060
|
+
border-color: transparent;
|
|
10061
|
+
}
|
|
10062
|
+
.media-row-btn.is-primary:hover {
|
|
10063
|
+
background: var(--color-button-primary-hover);
|
|
10064
|
+
}
|
|
10065
|
+
.media-custom-form {
|
|
10066
|
+
display: grid;
|
|
10067
|
+
grid-template-columns: max-content 1fr;
|
|
10068
|
+
gap: 0.4375rem 0.625rem;
|
|
10069
|
+
align-items: center;
|
|
10070
|
+
}
|
|
10071
|
+
.media-custom-form label {
|
|
10072
|
+
font-size: 0.75rem;
|
|
10073
|
+
color: var(--color-text-secondary);
|
|
10074
|
+
}
|
|
10075
|
+
.media-custom-form input {
|
|
10076
|
+
width: 100%;
|
|
10077
|
+
background: var(--color-bg-secondary);
|
|
10078
|
+
border: 1px solid var(--color-border-primary);
|
|
10079
|
+
color: var(--color-text-primary);
|
|
10080
|
+
border-radius: 6px;
|
|
10081
|
+
padding: 0.375rem 0.5rem;
|
|
10082
|
+
font-size: 0.8125rem;
|
|
10083
|
+
font-family: inherit;
|
|
10084
|
+
box-sizing: border-box;
|
|
10085
|
+
}
|
|
10086
|
+
.media-custom-form .media-form-actions {
|
|
10087
|
+
grid-column: 1 / -1;
|
|
10088
|
+
display: flex;
|
|
10089
|
+
gap: 0.5rem;
|
|
10090
|
+
justify-content: flex-end;
|
|
10091
|
+
margin-top: 0.25rem;
|
|
10092
|
+
}
|
data/lib/clacky/web/billing.js
CHANGED
|
@@ -226,7 +226,7 @@ const Billing = (() => {
|
|
|
226
226
|
tooltip.innerHTML = `
|
|
227
227
|
<div class="tooltip-header">
|
|
228
228
|
<span class="tooltip-date">${date}</span>
|
|
229
|
-
<span class="tooltip-total">${total} tokens</span>
|
|
229
|
+
<span class="tooltip-total-value">${total} tokens</span>
|
|
230
230
|
</div>
|
|
231
231
|
<div class="tooltip-row">
|
|
232
232
|
<span class="tooltip-dot tooltip-total"></span>
|
data/lib/clacky/web/i18n.js
CHANGED
|
@@ -80,8 +80,16 @@ const I18n = (() => {
|
|
|
80
80
|
"sessions.actions.download": "Download session files",
|
|
81
81
|
"sessions.actions.downloadHint": "for debugging",
|
|
82
82
|
"sib.dir.tooltip": "Click to change directory",
|
|
83
|
-
"sib.dir.changePrompt": "Change working directory
|
|
84
|
-
"
|
|
83
|
+
"sib.dir.changePrompt": "Change working directory",
|
|
84
|
+
"sib.dir.home": "Home",
|
|
85
|
+
"sib.dir.root": "Root",
|
|
86
|
+
"sib.dir.default": "Default workspace",
|
|
87
|
+
"sib.dir.current": "Current workspace", "sib.dir.inputPlaceholder": "Type or select a directory path",
|
|
88
|
+
"sib.dir.loading": "Loading…",
|
|
89
|
+
"sib.dir.empty": "Empty directory",
|
|
90
|
+
"sib.dir.loadError": "Failed to load",
|
|
91
|
+
"sib.dir.confirm": "Confirm",
|
|
92
|
+
"sib.dir.cancel": "Cancel", "workspace.title": "Workspace",
|
|
85
93
|
"workspace.expand": "Open workspace",
|
|
86
94
|
"workspace.collapse": "Collapse workspace",
|
|
87
95
|
"workspace.refresh": "Refresh",
|
|
@@ -490,6 +498,35 @@ const I18n = (() => {
|
|
|
490
498
|
"settings.models.empty": "No models configured. Click \"+ Add Model\" to add one.",
|
|
491
499
|
"settings.models.badge.default": "Default",
|
|
492
500
|
"settings.models.badge.lite": "Lite",
|
|
501
|
+
"settings.media.title": "Media Generation",
|
|
502
|
+
"settings.media.desc": "Optional. Image / video / audio generation models.",
|
|
503
|
+
"settings.media.loading": "Loading…",
|
|
504
|
+
"settings.media.error": "Failed to load: {{msg}}",
|
|
505
|
+
"settings.media.kind.image": "Image",
|
|
506
|
+
"settings.media.kind.video": "Video",
|
|
507
|
+
"settings.media.kind.audio": "Audio",
|
|
508
|
+
"settings.media.source.off": "Off",
|
|
509
|
+
"settings.media.source.auto": "Auto",
|
|
510
|
+
"settings.media.source.custom": "Custom",
|
|
511
|
+
"settings.media.field.model": "Model",
|
|
512
|
+
"settings.media.field.baseUrl": "Base URL",
|
|
513
|
+
"settings.media.field.apiKey": "API Key",
|
|
514
|
+
"settings.media.field.provider":"Provider",
|
|
515
|
+
"settings.media.off.hint": "Disabled.",
|
|
516
|
+
"settings.media.auto.followsDefault": "Follows default chat model",
|
|
517
|
+
"settings.media.auto.noDefaultModel": "Set a default chat model first.",
|
|
518
|
+
"settings.media.auto.unsupported": "Current provider has no built-in model for this kind. Switch to Custom.",
|
|
519
|
+
"settings.media.auto.comingSoon": "Not available yet — no built-in providers.",
|
|
520
|
+
"settings.media.auto.disabledTitle": "No built-in provider available — use Custom.",
|
|
521
|
+
"settings.media.action.edit": "Edit",
|
|
522
|
+
"settings.media.action.save": "Save",
|
|
523
|
+
"settings.media.action.cancel": "Cancel",
|
|
524
|
+
"settings.media.action.saving": "Saving…",
|
|
525
|
+
"settings.media.action.saved": "Saved",
|
|
526
|
+
"settings.media.apiKey.placeholder": "Enter API key",
|
|
527
|
+
"settings.media.apiKey.required": "API key required",
|
|
528
|
+
"settings.media.model.required": "Model name required",
|
|
529
|
+
"settings.media.baseUrl.required": "Base URL required",
|
|
493
530
|
"settings.models.field.quicksetup": "Quick Setup",
|
|
494
531
|
"settings.models.field.model": "Model",
|
|
495
532
|
"settings.models.field.baseurl": "Base URL",
|
|
@@ -595,6 +632,10 @@ const I18n = (() => {
|
|
|
595
632
|
"settings.currency.usd": "$ USD",
|
|
596
633
|
"settings.currency.cny": "¥ CNY",
|
|
597
634
|
"settings.currency.exchangeRate": "Exchange Rate (1 USD =)",
|
|
635
|
+
"settings.currency.updateLatest": "Update latest",
|
|
636
|
+
"settings.currency.updating": "Updating…",
|
|
637
|
+
"settings.currency.updated": "Updated from {{source}} on {{date}}",
|
|
638
|
+
"settings.currency.updateFailed": "Failed to fetch the latest rate. You can still enter it manually.",
|
|
598
639
|
|
|
599
640
|
// ── Onboard ──
|
|
600
641
|
"onboard.title": "Welcome to {{brand}}",
|
|
@@ -771,8 +812,16 @@ const I18n = (() => {
|
|
|
771
812
|
"sessions.actions.download": "下载会话文件",
|
|
772
813
|
"sessions.actions.downloadHint": "用于调试",
|
|
773
814
|
"sib.dir.tooltip": "点击切换工作目录",
|
|
774
|
-
"sib.dir.changePrompt": "
|
|
775
|
-
"
|
|
815
|
+
"sib.dir.changePrompt": "切换工作目录",
|
|
816
|
+
"sib.dir.home": "主目录",
|
|
817
|
+
"sib.dir.root": "根目录",
|
|
818
|
+
"sib.dir.default": "默认工作目录",
|
|
819
|
+
"sib.dir.current": "当前工作目录", "sib.dir.inputPlaceholder": "输入或选择目录路径",
|
|
820
|
+
"sib.dir.loading": "加载中…",
|
|
821
|
+
"sib.dir.empty": "空目录",
|
|
822
|
+
"sib.dir.loadError": "加载失败",
|
|
823
|
+
"sib.dir.confirm": "确认",
|
|
824
|
+
"sib.dir.cancel": "取消", "workspace.title": "工作区",
|
|
776
825
|
"workspace.expand": "打开工作区",
|
|
777
826
|
"workspace.collapse": "收起工作区",
|
|
778
827
|
"workspace.refresh": "刷新",
|
|
@@ -1180,6 +1229,35 @@ const I18n = (() => {
|
|
|
1180
1229
|
"settings.models.empty": "暂未配置模型,点击「+ 添加模型」添加。",
|
|
1181
1230
|
"settings.models.badge.default": "默认",
|
|
1182
1231
|
"settings.models.badge.lite": "轻量",
|
|
1232
|
+
"settings.media.title": "媒体生成",
|
|
1233
|
+
"settings.media.desc": "可选。图片 / 视频 / 音频 生成模型。",
|
|
1234
|
+
"settings.media.loading": "加载中…",
|
|
1235
|
+
"settings.media.error": "加载失败:{{msg}}",
|
|
1236
|
+
"settings.media.kind.image": "图片",
|
|
1237
|
+
"settings.media.kind.video": "视频",
|
|
1238
|
+
"settings.media.kind.audio": "音频",
|
|
1239
|
+
"settings.media.source.off": "关闭",
|
|
1240
|
+
"settings.media.source.auto": "自动",
|
|
1241
|
+
"settings.media.source.custom": "自定义",
|
|
1242
|
+
"settings.media.field.model": "模型",
|
|
1243
|
+
"settings.media.field.baseUrl": "Base URL",
|
|
1244
|
+
"settings.media.field.apiKey": "API Key",
|
|
1245
|
+
"settings.media.field.provider":"服务商",
|
|
1246
|
+
"settings.media.off.hint": "已关闭。",
|
|
1247
|
+
"settings.media.auto.followsDefault": "跟随默认聊天模型",
|
|
1248
|
+
"settings.media.auto.noDefaultModel": "请先设置默认聊天模型。",
|
|
1249
|
+
"settings.media.auto.unsupported": "当前服务商无内置模型,请切换到「自定义」。",
|
|
1250
|
+
"settings.media.auto.comingSoon": "暂无内置服务商,敬请期待。",
|
|
1251
|
+
"settings.media.auto.disabledTitle": "暂无内置服务商,请使用自定义。",
|
|
1252
|
+
"settings.media.action.edit": "编辑",
|
|
1253
|
+
"settings.media.action.save": "保存",
|
|
1254
|
+
"settings.media.action.cancel": "取消",
|
|
1255
|
+
"settings.media.action.saving": "保存中…",
|
|
1256
|
+
"settings.media.action.saved": "已保存",
|
|
1257
|
+
"settings.media.apiKey.placeholder": "请输入 API Key",
|
|
1258
|
+
"settings.media.apiKey.required": "请填写 API Key",
|
|
1259
|
+
"settings.media.model.required": "请填写模型名称",
|
|
1260
|
+
"settings.media.baseUrl.required": "请填写 Base URL",
|
|
1183
1261
|
"settings.models.field.quicksetup": "快速配置",
|
|
1184
1262
|
"settings.models.field.model": "Model",
|
|
1185
1263
|
"settings.models.field.baseurl": "Base URL",
|
|
@@ -1285,6 +1363,10 @@ const I18n = (() => {
|
|
|
1285
1363
|
"settings.currency.usd": "$ 美元",
|
|
1286
1364
|
"settings.currency.cny": "¥ 人民币",
|
|
1287
1365
|
"settings.currency.exchangeRate": "汇率 (1 美元 =)",
|
|
1366
|
+
"settings.currency.updateLatest": "获取最新汇率",
|
|
1367
|
+
"settings.currency.updating": "获取中…",
|
|
1368
|
+
"settings.currency.updated": "已从 {{source}} 更新,日期 {{date}}",
|
|
1369
|
+
"settings.currency.updateFailed": "获取最新汇率失败,仍可手动输入。",
|
|
1288
1370
|
|
|
1289
1371
|
// ── Onboard ──
|
|
1290
1372
|
"onboard.title": "欢迎使用 {{brand}}",
|
data/lib/clacky/web/index.html
CHANGED
|
@@ -384,7 +384,7 @@
|
|
|
384
384
|
<div id="image-preview-strip" style="display:none"></div>
|
|
385
385
|
<div id="input-bar">
|
|
386
386
|
<!-- Hidden file picker -->
|
|
387
|
-
<input type="file" id="image-file-input" accept="
|
|
387
|
+
<input type="file" id="image-file-input" accept="*/*" multiple style="display:none">
|
|
388
388
|
<button id="btn-attach" title="Attach file (image, pdf, docx, md, tar.gz…) — drag & drop / Ctrl+V also work">
|
|
389
389
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
390
390
|
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66L9.41 17.41a2 2 0 0 1-2.83-2.83l8.49-8.48"/>
|
|
@@ -771,6 +771,17 @@
|
|
|
771
771
|
</div>
|
|
772
772
|
<div id="model-cards"></div>
|
|
773
773
|
</section>
|
|
774
|
+
|
|
775
|
+
<!-- Media generation section -->
|
|
776
|
+
<section class="settings-section" id="media-section">
|
|
777
|
+
<div class="settings-section-title">
|
|
778
|
+
<span data-i18n="settings.media.title">Media Generation</span>
|
|
779
|
+
</div>
|
|
780
|
+
<div class="settings-section-desc" data-i18n="settings.media.desc">
|
|
781
|
+
Generate images, video, and audio using your configured providers. "Auto" follows your default chat model.
|
|
782
|
+
</div>
|
|
783
|
+
<div id="media-rows"></div>
|
|
784
|
+
</section>
|
|
774
785
|
</div>
|
|
775
786
|
|
|
776
787
|
<!-- ══ Tab: UI ══ -->
|
|
@@ -813,7 +824,15 @@
|
|
|
813
824
|
<div class="settings-exchange-rate-input-wrapper">
|
|
814
825
|
<input type="number" id="settings-exchange-rate" class="settings-exchange-rate-input" step="0.0001" min="0.0001" placeholder="6.7944">
|
|
815
826
|
<span class="settings-exchange-rate-unit">CNY</span>
|
|
827
|
+
<button type="button" id="btn-update-exchange-rate" class="settings-exchange-rate-refresh">
|
|
828
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
829
|
+
<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/>
|
|
830
|
+
<path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>
|
|
831
|
+
</svg>
|
|
832
|
+
<span data-i18n="settings.currency.updateLatest">Update latest</span>
|
|
833
|
+
</button>
|
|
816
834
|
</div>
|
|
835
|
+
<div id="settings-exchange-rate-status" class="settings-exchange-rate-status"></div>
|
|
817
836
|
</label>
|
|
818
837
|
</div>
|
|
819
838
|
</section>
|
|
@@ -1052,8 +1071,8 @@
|
|
|
1052
1071
|
<div id="model-modal-test-result" class="model-test-result"></div>
|
|
1053
1072
|
|
|
1054
1073
|
<label class="model-field model-field-checkbox" id="model-modal-default-field">
|
|
1055
|
-
<input type="checkbox" id="model-modal-set-default">
|
|
1056
|
-
<span data-i18n="settings.models.field.setDefault">Set as default model</span>
|
|
1074
|
+
<input type="checkbox" id="model-modal-set-default" class="field-checkbox">
|
|
1075
|
+
<span class="field-label" data-i18n="settings.models.field.setDefault">Set as default model</span>
|
|
1057
1076
|
</label>
|
|
1058
1077
|
</div>
|
|
1059
1078
|
<div class="modal-footer">
|
|
@@ -1288,6 +1307,7 @@
|
|
|
1288
1307
|
<script src="/skills.js"></script>
|
|
1289
1308
|
<script src="/channels.js"></script>
|
|
1290
1309
|
<script src="/mcp.js"></script>
|
|
1310
|
+
<script src="/model-tester.js"></script>
|
|
1291
1311
|
<script src="/settings.js"></script>
|
|
1292
1312
|
<script src="/billing.js"></script>
|
|
1293
1313
|
<script src="/onboard.js"></script>
|