openclacky 1.2.12 → 1.2.14
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/.clacky/skills/gem-release/SKILL.md +5 -1
- data/.clacky/skills/gem-release/scripts/release.sh +4 -1
- data/CHANGELOG.md +39 -0
- data/lib/clacky/agent/llm_caller.rb +40 -25
- data/lib/clacky/agent/memory_updater.rb +12 -0
- data/lib/clacky/agent/session_serializer.rb +1 -0
- data/lib/clacky/agent/skill_auto_creator.rb +7 -4
- data/lib/clacky/agent/skill_evolution.rb +23 -5
- data/lib/clacky/agent/skill_manager.rb +86 -1
- data/lib/clacky/agent/skill_reflector.rb +18 -23
- data/lib/clacky/agent.rb +132 -15
- data/lib/clacky/agent_config.rb +183 -22
- data/lib/clacky/cli.rb +55 -0
- data/lib/clacky/client.rb +11 -1
- data/lib/clacky/default_parsers/pdf_parser.rb +70 -86
- data/lib/clacky/default_parsers/pdf_parser_vlm.py +136 -0
- data/lib/clacky/default_skills/persist-memory/SKILL.md +4 -3
- data/lib/clacky/default_skills/search-skills/SKILL.md +61 -0
- data/lib/clacky/idle_compression_timer.rb +1 -1
- data/lib/clacky/message_format/open_ai.rb +7 -1
- data/lib/clacky/openai_stream_aggregator.rb +4 -1
- data/lib/clacky/providers.rb +77 -12
- data/lib/clacky/server/http_server.rb +296 -7
- data/lib/clacky/server/session_registry.rb +30 -8
- data/lib/clacky/server/web_ui_controller.rb +24 -1
- data/lib/clacky/session_manager.rb +120 -0
- data/lib/clacky/tools/web_search.rb +59 -8
- data/lib/clacky/ui2/layout_manager.rb +15 -5
- data/lib/clacky/ui2/progress_handle.rb +18 -8
- data/lib/clacky/ui2/ui_controller.rb +27 -0
- data/lib/clacky/ui_interface.rb +22 -0
- data/lib/clacky/utils/model_pricing.rb +96 -0
- data/lib/clacky/version.rb +1 -1
- data/lib/clacky/vision/resolver.rb +157 -0
- data/lib/clacky/web/app.css +209 -4
- data/lib/clacky/web/app.js +6 -5
- data/lib/clacky/web/i18n.js +22 -6
- data/lib/clacky/web/index.html +2 -1
- data/lib/clacky/web/sessions.js +408 -80
- data/lib/clacky/web/settings.js +241 -60
- data/lib/clacky/web/skills.js +5 -14
- data/lib/clacky/web/utils.js +57 -0
- data/lib/clacky/web/ws-dispatcher.js +136 -0
- data/lib/clacky.rb +1 -0
- metadata +6 -2
data/lib/clacky/web/app.css
CHANGED
|
@@ -856,6 +856,43 @@ body {
|
|
|
856
856
|
opacity: 0.5;
|
|
857
857
|
}
|
|
858
858
|
|
|
859
|
+
.session-search-group {
|
|
860
|
+
padding: 0.5rem 0.75rem 0.25rem;
|
|
861
|
+
font-size: 0.6875rem;
|
|
862
|
+
font-weight: 600;
|
|
863
|
+
color: var(--color-text-muted);
|
|
864
|
+
text-transform: none;
|
|
865
|
+
letter-spacing: 0.02em;
|
|
866
|
+
}
|
|
867
|
+
.session-search-group + .session-search-group {
|
|
868
|
+
margin-top: 0.25rem;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.session-snippet {
|
|
872
|
+
white-space: nowrap;
|
|
873
|
+
overflow: hidden;
|
|
874
|
+
text-overflow: ellipsis;
|
|
875
|
+
font-size: 0.6875rem;
|
|
876
|
+
color: var(--color-text-muted);
|
|
877
|
+
margin-top: 2px;
|
|
878
|
+
line-height: 1.35;
|
|
879
|
+
opacity: 0.85;
|
|
880
|
+
}
|
|
881
|
+
.session-snippet mark {
|
|
882
|
+
background: var(--color-warning-bg, #fef3c7);
|
|
883
|
+
color: var(--color-text-primary);
|
|
884
|
+
padding: 0 2px;
|
|
885
|
+
border-radius: 2px;
|
|
886
|
+
font-weight: 600;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.session-name__text mark {
|
|
890
|
+
background: var(--color-warning-bg, #fef3c7);
|
|
891
|
+
color: var(--color-text-primary);
|
|
892
|
+
padding: 0 1px;
|
|
893
|
+
border-radius: 2px;
|
|
894
|
+
}
|
|
895
|
+
|
|
859
896
|
/* Legacy .btn-new-inline — kept for compat, can be removed after cleanup */
|
|
860
897
|
.btn-new-inline {
|
|
861
898
|
display: none;
|
|
@@ -984,9 +1021,22 @@ body {
|
|
|
984
1021
|
z-index: 1000;
|
|
985
1022
|
animation: fadeIn 0.15s ease;
|
|
986
1023
|
}
|
|
1024
|
+
.session-context-menu {
|
|
1025
|
+
background: var(--color-bg-secondary);
|
|
1026
|
+
border: 1px solid var(--color-border-primary);
|
|
1027
|
+
border-radius: 8px;
|
|
1028
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08), 0 2px 6px rgba(0, 0, 0, 0.04);
|
|
1029
|
+
padding: 0.25rem;
|
|
1030
|
+
min-width: 10rem;
|
|
1031
|
+
z-index: 1001;
|
|
1032
|
+
animation: fadeIn 0.15s ease;
|
|
1033
|
+
}
|
|
987
1034
|
[data-theme="dark"] .session-actions-menu {
|
|
988
1035
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
|
|
989
1036
|
}
|
|
1037
|
+
[data-theme="dark"] .session-context-menu {
|
|
1038
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
|
|
1039
|
+
}
|
|
990
1040
|
.session-actions-menu-item {
|
|
991
1041
|
display: flex;
|
|
992
1042
|
align-items: center;
|
|
@@ -1622,7 +1672,7 @@ body {
|
|
|
1622
1672
|
.sib-status-* classes instead. Legacy .status-* styles removed. */
|
|
1623
1673
|
|
|
1624
1674
|
/* ── Messages ────────────────────────────────────────────────────────────── */
|
|
1625
|
-
|
|
1675
|
+
.chat-messages-scroll {
|
|
1626
1676
|
flex: 1;
|
|
1627
1677
|
overflow-y: auto;
|
|
1628
1678
|
overflow-x: hidden;
|
|
@@ -2108,6 +2158,15 @@ body {
|
|
|
2108
2158
|
.tu-delta-ok { color: #34d399; } /* green — normal */
|
|
2109
2159
|
.tu-delta-mid { color: #f59e0b; } /* yellow — moderate */
|
|
2110
2160
|
.tu-delta-high { color: #f87171; } /* red — large */
|
|
2161
|
+
|
|
2162
|
+
.tool-item .token-usage-line.tu-attached {
|
|
2163
|
+
align-self: stretch;
|
|
2164
|
+
margin: 0.25rem 0 0;
|
|
2165
|
+
padding: 2px 0 0;
|
|
2166
|
+
opacity: 0.55;
|
|
2167
|
+
flex-wrap: wrap;
|
|
2168
|
+
}
|
|
2169
|
+
.tool-item .token-usage-line.tu-attached:hover { opacity: 0.95; }
|
|
2111
2170
|
.tu-delta-neg { color: var(--color-accent-primary); } /* cyan — compression */
|
|
2112
2171
|
|
|
2113
2172
|
/* Detail fields: hidden by default, revealed on hover */
|
|
@@ -2221,6 +2280,30 @@ body {
|
|
|
2221
2280
|
.tool-item-stdout .ansi-black { color: #5c6370; }
|
|
2222
2281
|
.tool-item-stdout .ansi-bold { font-weight: 700; }
|
|
2223
2282
|
|
|
2283
|
+
/* ── Diff block (rendered inline within edit/write tool-item) ─────────────── */
|
|
2284
|
+
.tool-item-diff {
|
|
2285
|
+
margin: 0.25rem 0 0.25rem 1.25rem;
|
|
2286
|
+
padding: 0.375rem 0.5rem;
|
|
2287
|
+
background: var(--color-bg-secondary);
|
|
2288
|
+
border: 1px solid var(--color-border-secondary);
|
|
2289
|
+
border-radius: 4px;
|
|
2290
|
+
font-size: 0.6875rem;
|
|
2291
|
+
font-family: monospace;
|
|
2292
|
+
line-height: 1.5;
|
|
2293
|
+
max-height: 20rem;
|
|
2294
|
+
overflow: auto;
|
|
2295
|
+
}
|
|
2296
|
+
.diff-line {
|
|
2297
|
+
white-space: pre;
|
|
2298
|
+
padding: 0 0.25rem;
|
|
2299
|
+
border-radius: 2px;
|
|
2300
|
+
}
|
|
2301
|
+
.diff-line.diff-add { background: rgba(46, 160, 67, 0.18); color: #98c379; }
|
|
2302
|
+
.diff-line.diff-del { background: rgba(248, 81, 73, 0.18); color: #e06c75; }
|
|
2303
|
+
.diff-line.diff-hunk { color: var(--color-text-tertiary); font-style: italic; }
|
|
2304
|
+
.diff-line.diff-ctx { color: var(--color-text-secondary); }
|
|
2305
|
+
.diff-line.diff-more { color: var(--color-text-tertiary); font-style: italic; margin-top: 0.25rem; }
|
|
2306
|
+
|
|
2224
2307
|
/* ── Thinking block (collapsible <think>...</think> sections) ─────────────── */
|
|
2225
2308
|
.thinking-block {
|
|
2226
2309
|
margin: 0 0 0.375rem 0;
|
|
@@ -9966,6 +10049,7 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9966
10049
|
background: var(--color-bg-secondary);
|
|
9967
10050
|
margin-bottom: 0.5rem;
|
|
9968
10051
|
overflow: hidden;
|
|
10052
|
+
max-width: 48rem;
|
|
9969
10053
|
}
|
|
9970
10054
|
.media-row.is-expanded {
|
|
9971
10055
|
background: var(--color-bg-secondary);
|
|
@@ -9988,25 +10072,28 @@ body.setup-mode[data-theme="dark"] {
|
|
|
9988
10072
|
background: var(--color-bg-primary);
|
|
9989
10073
|
border: 1px solid var(--color-border-primary);
|
|
9990
10074
|
border-radius: 6px;
|
|
9991
|
-
padding:
|
|
10075
|
+
padding: 2px;
|
|
9992
10076
|
}
|
|
9993
10077
|
.media-row-segmented button {
|
|
9994
10078
|
background: transparent;
|
|
9995
10079
|
border: none;
|
|
9996
|
-
padding: 0.
|
|
10080
|
+
padding: 0.3125rem 0.875rem;
|
|
9997
10081
|
font-size: 0.75rem;
|
|
10082
|
+
font-weight: 500;
|
|
9998
10083
|
color: var(--color-text-secondary);
|
|
9999
10084
|
border-radius: 5px;
|
|
10000
10085
|
cursor: pointer;
|
|
10001
|
-
transition: background-color 0.15s ease, color 0.15s ease;
|
|
10086
|
+
transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
|
|
10002
10087
|
font-family: inherit;
|
|
10003
10088
|
}
|
|
10004
10089
|
.media-row-segmented button:hover:not(.is-active):not(:disabled) {
|
|
10005
10090
|
color: var(--color-text-primary);
|
|
10091
|
+
background: var(--color-bg-secondary);
|
|
10006
10092
|
}
|
|
10007
10093
|
.media-row-segmented button.is-active {
|
|
10008
10094
|
background: var(--color-button-primary);
|
|
10009
10095
|
color: #fff;
|
|
10096
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
|
|
10010
10097
|
}
|
|
10011
10098
|
.media-row-segmented button:disabled {
|
|
10012
10099
|
opacity: 0.4;
|
|
@@ -10108,3 +10195,121 @@ body.setup-mode[data-theme="dark"] {
|
|
|
10108
10195
|
justify-content: flex-end;
|
|
10109
10196
|
margin-top: 0.25rem;
|
|
10110
10197
|
}
|
|
10198
|
+
|
|
10199
|
+
.media-auto-grid {
|
|
10200
|
+
display: grid;
|
|
10201
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
10202
|
+
gap: 0.625rem 1rem;
|
|
10203
|
+
}
|
|
10204
|
+
.media-provider-line {
|
|
10205
|
+
display: flex;
|
|
10206
|
+
align-items: baseline;
|
|
10207
|
+
gap: 0.5rem;
|
|
10208
|
+
font-size: 0.8125rem;
|
|
10209
|
+
margin-bottom: 0.625rem;
|
|
10210
|
+
}
|
|
10211
|
+
.media-provider-label {
|
|
10212
|
+
color: var(--color-text-secondary);
|
|
10213
|
+
}
|
|
10214
|
+
.media-provider-value {
|
|
10215
|
+
color: var(--color-text-primary);
|
|
10216
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
10217
|
+
}
|
|
10218
|
+
.media-auto-readonly {
|
|
10219
|
+
background: var(--color-bg-primary);
|
|
10220
|
+
border: 1px solid var(--color-border-primary);
|
|
10221
|
+
border-radius: 6px;
|
|
10222
|
+
padding: 0.4375rem 0.625rem;
|
|
10223
|
+
font-size: 0.8125rem;
|
|
10224
|
+
color: var(--color-text-primary);
|
|
10225
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
10226
|
+
word-break: break-all;
|
|
10227
|
+
min-height: 1.125rem;
|
|
10228
|
+
line-height: 1.4;
|
|
10229
|
+
}
|
|
10230
|
+
.media-custom-fields {
|
|
10231
|
+
display: grid;
|
|
10232
|
+
grid-template-columns: 1fr;
|
|
10233
|
+
gap: 0.625rem;
|
|
10234
|
+
}
|
|
10235
|
+
.media-custom-readonly-list {
|
|
10236
|
+
display: flex;
|
|
10237
|
+
flex-direction: column;
|
|
10238
|
+
gap: 0.375rem;
|
|
10239
|
+
}
|
|
10240
|
+
.media-custom-readonly-row {
|
|
10241
|
+
display: flex;
|
|
10242
|
+
align-items: baseline;
|
|
10243
|
+
gap: 0.5rem;
|
|
10244
|
+
font-size: 0.8125rem;
|
|
10245
|
+
line-height: 1.4;
|
|
10246
|
+
}
|
|
10247
|
+
.media-custom-readonly-label {
|
|
10248
|
+
flex: 0 0 auto;
|
|
10249
|
+
min-width: 4.5rem;
|
|
10250
|
+
color: var(--color-text-secondary);
|
|
10251
|
+
}
|
|
10252
|
+
.media-custom-readonly-value {
|
|
10253
|
+
flex: 1 1 auto;
|
|
10254
|
+
color: var(--color-text-primary);
|
|
10255
|
+
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
10256
|
+
word-break: break-all;
|
|
10257
|
+
}
|
|
10258
|
+
.media-row-btn-sm {
|
|
10259
|
+
font-size: 0.75rem;
|
|
10260
|
+
padding: 0.3125rem 0.875rem;
|
|
10261
|
+
}
|
|
10262
|
+
.media-row-detail .model-test-result {
|
|
10263
|
+
margin-top: 0.5rem;
|
|
10264
|
+
min-height: 1rem;
|
|
10265
|
+
}
|
|
10266
|
+
.media-row-detail .media-row-actions {
|
|
10267
|
+
margin-top: 0.625rem;
|
|
10268
|
+
}
|
|
10269
|
+
|
|
10270
|
+
/* ── Phase grouping (folded subagent runs like skill evolution) ────────── */
|
|
10271
|
+
.msg-phase {
|
|
10272
|
+
align-self: stretch;
|
|
10273
|
+
margin: 0.25rem 0;
|
|
10274
|
+
border: 1px dashed var(--color-border-primary);
|
|
10275
|
+
border-radius: 8px;
|
|
10276
|
+
background: var(--color-bg-secondary);
|
|
10277
|
+
font-size: 0.8125rem;
|
|
10278
|
+
}
|
|
10279
|
+
.msg-phase-summary {
|
|
10280
|
+
cursor: pointer;
|
|
10281
|
+
padding: 0.375rem 0.625rem;
|
|
10282
|
+
color: var(--color-text-secondary);
|
|
10283
|
+
list-style: none;
|
|
10284
|
+
user-select: none;
|
|
10285
|
+
display: flex;
|
|
10286
|
+
align-items: center;
|
|
10287
|
+
gap: 0.375rem;
|
|
10288
|
+
}
|
|
10289
|
+
.msg-phase-summary::-webkit-details-marker { display: none; }
|
|
10290
|
+
.msg-phase-summary::before {
|
|
10291
|
+
content: "\25B8";
|
|
10292
|
+
font-size: 0.6875rem;
|
|
10293
|
+
transition: transform 0.15s;
|
|
10294
|
+
}
|
|
10295
|
+
.msg-phase[open] .msg-phase-summary::before { transform: rotate(90deg); }
|
|
10296
|
+
.msg-phase-icon { font-size: 0.875rem; }
|
|
10297
|
+
.msg-phase-label { font-weight: 500; }
|
|
10298
|
+
.msg-phase-status { opacity: 0.7; font-size: 0.75rem; }
|
|
10299
|
+
.msg-phase-status-incomplete { color: var(--color-warning, #c97f00); }
|
|
10300
|
+
.msg-phase-body {
|
|
10301
|
+
padding: 0.625rem 0.75rem 0.75rem;
|
|
10302
|
+
border-top: 1px dashed var(--color-border-primary);
|
|
10303
|
+
display: flex;
|
|
10304
|
+
flex-direction: column;
|
|
10305
|
+
gap: 0.625rem;
|
|
10306
|
+
}
|
|
10307
|
+
.msg-phase-body .msg { opacity: 0.9; }
|
|
10308
|
+
|
|
10309
|
+
.msg-phase-empty {
|
|
10310
|
+
opacity: 0.55;
|
|
10311
|
+
border-style: dotted;
|
|
10312
|
+
}
|
|
10313
|
+
.msg-phase-empty .msg-phase-summary { cursor: default; }
|
|
10314
|
+
.msg-phase-empty .msg-phase-summary::before { visibility: hidden; }
|
|
10315
|
+
.msg-phase-empty .msg-phase-body { display: none; }
|
data/lib/clacky/web/app.js
CHANGED
|
@@ -335,15 +335,15 @@ const Modal = (() => {
|
|
|
335
335
|
$("prompt-modal-ok").onclick = null;
|
|
336
336
|
$("prompt-modal-cancel").onclick = null;
|
|
337
337
|
input.onkeydown = null;
|
|
338
|
+
unbindEnter();
|
|
338
339
|
resolve(result);
|
|
339
340
|
};
|
|
340
341
|
|
|
341
342
|
$("prompt-modal-ok").onclick = () => cleanup(input.value.trim() || null);
|
|
342
343
|
$("prompt-modal-cancel").onclick = () => cleanup(null);
|
|
343
|
-
|
|
344
|
-
|
|
344
|
+
|
|
345
|
+
const unbindEnter = IME.bindEnter(input, () => cleanup(input.value.trim() || null));
|
|
345
346
|
input.onkeydown = (e) => {
|
|
346
|
-
if (e.key === "Enter") cleanup(input.value.trim() || null);
|
|
347
347
|
if (e.key === "Escape") cleanup(null);
|
|
348
348
|
};
|
|
349
349
|
});
|
|
@@ -369,6 +369,7 @@ const Modal = (() => {
|
|
|
369
369
|
$("rename-modal-overlay").onclick = null;
|
|
370
370
|
input.onkeydown = null;
|
|
371
371
|
input.oninput = null;
|
|
372
|
+
unbindEnter();
|
|
372
373
|
resolve(result);
|
|
373
374
|
};
|
|
374
375
|
|
|
@@ -386,9 +387,9 @@ const Modal = (() => {
|
|
|
386
387
|
|
|
387
388
|
$("rename-modal-save").onclick = saveHandler;
|
|
388
389
|
$("rename-modal-cancel").onclick = () => cleanup(null);
|
|
389
|
-
|
|
390
|
+
|
|
391
|
+
const unbindEnter = IME.bindEnter(input, saveHandler);
|
|
390
392
|
input.onkeydown = (e) => {
|
|
391
|
-
if (e.key === "Enter") { e.preventDefault(); saveHandler(); }
|
|
392
393
|
if (e.key === "Escape") cleanup(null);
|
|
393
394
|
};
|
|
394
395
|
|
data/lib/clacky/web/i18n.js
CHANGED
|
@@ -69,6 +69,9 @@ const I18n = (() => {
|
|
|
69
69
|
// ── Session list ──
|
|
70
70
|
"sessions.empty": "No sessions yet",
|
|
71
71
|
"sessions.confirmDelete": "Delete session {{name}}? This cannot be undone.",
|
|
72
|
+
"sessions.search.byName": "Title matches ({{n}})",
|
|
73
|
+
"sessions.search.byContent": "Content matches ({{n}})",
|
|
74
|
+
"sessions.search.contentEmpty": "No content matches",
|
|
72
75
|
"sessions.meta": "{{tasks}} tasks · ${{cost}}",
|
|
73
76
|
"sessions.metaTasks": "{{n}} tasks",
|
|
74
77
|
"sessions.deleteTitle": "Delete session",
|
|
@@ -122,6 +125,7 @@ const I18n = (() => {
|
|
|
122
125
|
"sessions.newSession": "+ New Session",
|
|
123
126
|
"sessions.actions.pin": "Pin",
|
|
124
127
|
"sessions.actions.unpin": "Unpin",
|
|
128
|
+
"sessions.actions.fork": "Fork",
|
|
125
129
|
"sessions.actions.rename": "Rename",
|
|
126
130
|
"sessions.actions.delete": "Delete",
|
|
127
131
|
"sessions.newSessionAdvanced": "More Options",
|
|
@@ -501,12 +505,13 @@ const I18n = (() => {
|
|
|
501
505
|
"settings.models.badge.default": "Default",
|
|
502
506
|
"settings.models.badge.lite": "Lite",
|
|
503
507
|
"settings.media.title": "Media Generation",
|
|
504
|
-
"settings.media.desc": "Optional. Image / video / audio
|
|
508
|
+
"settings.media.desc": "Optional. Image / video / audio / OCR sidecar models.",
|
|
505
509
|
"settings.media.loading": "Loading…",
|
|
506
510
|
"settings.media.error": "Failed to load: {{msg}}",
|
|
507
511
|
"settings.media.kind.image": "Image",
|
|
508
512
|
"settings.media.kind.video": "Video",
|
|
509
513
|
"settings.media.kind.audio": "Audio",
|
|
514
|
+
"settings.media.kind.ocr": "OCR",
|
|
510
515
|
"settings.media.source.off": "Off",
|
|
511
516
|
"settings.media.source.auto": "Auto",
|
|
512
517
|
"settings.media.source.custom": "Custom",
|
|
@@ -515,16 +520,19 @@ const I18n = (() => {
|
|
|
515
520
|
"settings.media.field.apiKey": "API Key",
|
|
516
521
|
"settings.media.field.provider":"Provider",
|
|
517
522
|
"settings.media.off.hint": "Disabled.",
|
|
518
|
-
"settings.media.auto.followsDefault": "
|
|
523
|
+
"settings.media.auto.followsDefault": "Auto-enabled via your default provider",
|
|
524
|
+
"settings.media.auto.stale": "Selected model {{requested}} is unavailable on the current provider — using {{current}} instead.",
|
|
519
525
|
"settings.media.auto.noDefaultModel": "Set a default chat model first.",
|
|
520
526
|
"settings.media.auto.unsupported": "Current provider has no built-in model for this kind. Switch to Custom.",
|
|
521
527
|
"settings.media.auto.comingSoon": "Not available yet — no built-in providers.",
|
|
522
|
-
"settings.media.auto.disabledTitle": "
|
|
528
|
+
"settings.media.auto.disabledTitle": "Provider has no built-in model — use Custom.",
|
|
523
529
|
"settings.media.action.edit": "Edit",
|
|
524
530
|
"settings.media.action.save": "Save",
|
|
525
531
|
"settings.media.action.cancel": "Cancel",
|
|
526
532
|
"settings.media.action.saving": "Saving…",
|
|
527
533
|
"settings.media.action.saved": "Saved",
|
|
534
|
+
"settings.media.action.test": "Test",
|
|
535
|
+
"settings.media.testing": "Testing connection…",
|
|
528
536
|
"settings.media.apiKey.placeholder": "Enter API key",
|
|
529
537
|
"settings.media.apiKey.required": "API key required",
|
|
530
538
|
"settings.media.model.required": "Model name required",
|
|
@@ -803,6 +811,9 @@ const I18n = (() => {
|
|
|
803
811
|
// ── Session list ──
|
|
804
812
|
"sessions.empty": "暂无会话",
|
|
805
813
|
"sessions.confirmDelete": "删除会话 {{name}}?此操作不可撤销。",
|
|
814
|
+
"sessions.search.byName": "标题匹配 ({{n}})",
|
|
815
|
+
"sessions.search.byContent": "内容匹配 ({{n}})",
|
|
816
|
+
"sessions.search.contentEmpty": "没有内容匹配",
|
|
806
817
|
"sessions.meta": "{{tasks}} 个任务 · ${{cost}}",
|
|
807
818
|
"sessions.metaTasks": "{{n}} 个任务",
|
|
808
819
|
"sessions.deleteTitle": "删除会话",
|
|
@@ -858,6 +869,7 @@ const I18n = (() => {
|
|
|
858
869
|
"sessions.loadMore": "加载更多会话",
|
|
859
870
|
"sessions.actions.pin": "置顶",
|
|
860
871
|
"sessions.actions.unpin": "取消置顶",
|
|
872
|
+
"sessions.actions.fork": "复制会话",
|
|
861
873
|
"sessions.actions.rename": "重命名",
|
|
862
874
|
"sessions.actions.delete": "删除",
|
|
863
875
|
"sessions.loadingMore": "加载中…",
|
|
@@ -1234,12 +1246,13 @@ const I18n = (() => {
|
|
|
1234
1246
|
"settings.models.badge.default": "默认",
|
|
1235
1247
|
"settings.models.badge.lite": "轻量",
|
|
1236
1248
|
"settings.media.title": "媒体生成",
|
|
1237
|
-
"settings.media.desc": "可选。图片 / 视频 / 音频
|
|
1249
|
+
"settings.media.desc": "可选。图片 / 视频 / 音频 / 图片理解(OCR)副模型。",
|
|
1238
1250
|
"settings.media.loading": "加载中…",
|
|
1239
1251
|
"settings.media.error": "加载失败:{{msg}}",
|
|
1240
1252
|
"settings.media.kind.image": "图片",
|
|
1241
1253
|
"settings.media.kind.video": "视频",
|
|
1242
1254
|
"settings.media.kind.audio": "音频",
|
|
1255
|
+
"settings.media.kind.ocr": "OCR",
|
|
1243
1256
|
"settings.media.source.off": "关闭",
|
|
1244
1257
|
"settings.media.source.auto": "自动",
|
|
1245
1258
|
"settings.media.source.custom": "自定义",
|
|
@@ -1248,16 +1261,19 @@ const I18n = (() => {
|
|
|
1248
1261
|
"settings.media.field.apiKey": "API Key",
|
|
1249
1262
|
"settings.media.field.provider":"服务商",
|
|
1250
1263
|
"settings.media.off.hint": "已关闭。",
|
|
1251
|
-
"settings.media.auto.followsDefault": "
|
|
1264
|
+
"settings.media.auto.followsDefault": "该服务商已支持,已自动启用",
|
|
1265
|
+
"settings.media.auto.stale": "你选定的 {{requested}} 在当前服务商不可用,已临时使用 {{current}}。",
|
|
1252
1266
|
"settings.media.auto.noDefaultModel": "请先设置默认聊天模型。",
|
|
1253
1267
|
"settings.media.auto.unsupported": "当前服务商无内置模型,请切换到「自定义」。",
|
|
1254
1268
|
"settings.media.auto.comingSoon": "暂无内置服务商,敬请期待。",
|
|
1255
|
-
"settings.media.auto.disabledTitle": "
|
|
1269
|
+
"settings.media.auto.disabledTitle": "服务商尚未配置支持,请使用自定义",
|
|
1256
1270
|
"settings.media.action.edit": "编辑",
|
|
1257
1271
|
"settings.media.action.save": "保存",
|
|
1258
1272
|
"settings.media.action.cancel": "取消",
|
|
1259
1273
|
"settings.media.action.saving": "保存中…",
|
|
1260
1274
|
"settings.media.action.saved": "已保存",
|
|
1275
|
+
"settings.media.action.test": "测试",
|
|
1276
|
+
"settings.media.testing": "测试连接中…",
|
|
1261
1277
|
"settings.media.apiKey.placeholder": "请输入 API Key",
|
|
1262
1278
|
"settings.media.apiKey.required": "请填写 API Key",
|
|
1263
1279
|
"settings.media.model.required": "请填写模型名称",
|
data/lib/clacky/web/index.html
CHANGED
|
@@ -316,7 +316,7 @@
|
|
|
316
316
|
|
|
317
317
|
<!-- Chat column (messages + info bar + input) -->
|
|
318
318
|
<div id="chat-main">
|
|
319
|
-
<div id="messages"></div>
|
|
319
|
+
<div id="messages" class="chat-messages-scroll"></div>
|
|
320
320
|
<!-- New message notification banner -->
|
|
321
321
|
<div id="new-message-banner" class="new-message-banner" style="display:none">
|
|
322
322
|
<span data-i18n="chat.newMessageHint">New messages ↓</span>
|
|
@@ -1296,6 +1296,7 @@
|
|
|
1296
1296
|
<script src="/vendor/hljs/highlight.min.js"></script>
|
|
1297
1297
|
<script src="/vendor/katex/katex.min.js"></script>
|
|
1298
1298
|
<script src="/vendor/katex/auto-render.min.js"></script>
|
|
1299
|
+
<script src="/utils.js"></script>
|
|
1299
1300
|
<script src="/i18n.js"></script>
|
|
1300
1301
|
<script src="/auth.js"></script>
|
|
1301
1302
|
<script src="/theme.js"></script>
|