newmark-agent 0.6.1 → 0.6.3
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.
- package/dist/conversation-utility-host.bundle.cjs +2028 -479
- package/dist/core/agent.d.ts +18 -0
- package/dist/core/agent.js +76 -7
- package/dist/core/agentKernelRunner.js +25 -2
- package/dist/core/browserPdf.d.ts +10 -0
- package/dist/core/browserPdf.js +56 -0
- package/dist/core/browserUse.d.ts +27 -0
- package/dist/core/browserUse.js +33 -5
- package/dist/core/browserUsePageAdapter.d.ts +13 -0
- package/dist/core/browserUsePageAdapter.js +45 -9
- package/dist/core/continuation/contracts.d.ts +197 -0
- package/dist/core/continuation/contracts.js +72 -0
- package/dist/core/continuation/store.d.ts +178 -0
- package/dist/core/continuation/store.js +989 -0
- package/dist/core/conversationKernel.d.ts +80 -1
- package/dist/core/conversationKernel.js +586 -36
- package/dist/core/electronBrowserUseHost.d.ts +4 -0
- package/dist/core/electronBrowserUseHost.js +104 -15
- package/dist/core/requestContextEstimate.d.ts +5 -1
- package/dist/core/searchMcpPool.d.ts +1 -0
- package/dist/core/searchMcpPool.js +20 -7
- package/dist/llm/provider.js +9 -2
- package/dist/main.js +58 -8
- package/dist/providers/chat-completions.adapter.js +6 -1
- package/dist/providers/responses.adapter.js +4 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +25 -2
- package/dist/ui/index.html +244 -84
- package/dist/wsl-agent-host.bundle.cjs +2031 -482
- package/package.json +4 -2
package/dist/ui/index.html
CHANGED
|
@@ -212,6 +212,10 @@ try {
|
|
|
212
212
|
|
|
213
213
|
/* Light theme */
|
|
214
214
|
[data-theme="light"] {
|
|
215
|
+
--accent: #405bd2;
|
|
216
|
+
--accent2: #147d59;
|
|
217
|
+
--nm-state-warning: #8a5b00;
|
|
218
|
+
--nm-state-danger: #c73545;
|
|
215
219
|
--bg: #f0f2f8;
|
|
216
220
|
--bg2: #e4e8f0;
|
|
217
221
|
--bg3: #d8dce8;
|
|
@@ -367,7 +371,7 @@ html, body {
|
|
|
367
371
|
50% { transform: scale(1.04); filter: saturate(1.25); }
|
|
368
372
|
}
|
|
369
373
|
|
|
370
|
-
::selection { background: rgba(91,120,255,0.35); color:
|
|
374
|
+
::selection { background: rgba(91,120,255,0.35); color: var(--text-bright); }
|
|
371
375
|
|
|
372
376
|
/* Open-source icon system: lucide-static sprite is copied into dist/ui at build time. */
|
|
373
377
|
.nm-icon {
|
|
@@ -515,9 +519,9 @@ button { border-radius: var(--radius-full) !important; }
|
|
|
515
519
|
transition: background var(--duration-fast) var(--ease-out-expo), color var(--duration-fast) var(--ease-out-expo);
|
|
516
520
|
}
|
|
517
521
|
|
|
518
|
-
.top-btn:hover { background:
|
|
522
|
+
.top-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
519
523
|
.top-btn:active { transform: scale(0.92) translateZ(0); }
|
|
520
|
-
.top-btn.close-btn:hover { background: rgba(255,68,68,0.2); color:
|
|
524
|
+
.top-btn.close-btn:hover { background: rgba(255,68,68,0.2); color: var(--nm-state-danger); }
|
|
521
525
|
|
|
522
526
|
/* ============================================================
|
|
523
527
|
LAYER 3 - Main Layout
|
|
@@ -724,7 +728,7 @@ button.left-nav-icon { width: calc(100% - 12px); }
|
|
|
724
728
|
white-space: nowrap;
|
|
725
729
|
}
|
|
726
730
|
|
|
727
|
-
.left-nav-icon:hover { background:
|
|
731
|
+
.left-nav-icon:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
728
732
|
.left-nav-icon:active { transform: scale(0.96) translateZ(0); }
|
|
729
733
|
.left-nav-icon .icon { width: 24px; height: 20px; text-align: center; flex-shrink: 0; font-size: 0; }
|
|
730
734
|
.left-nav-icon span:not(.icon) {
|
|
@@ -917,7 +921,7 @@ button.left-ws-item {
|
|
|
917
921
|
|
|
918
922
|
.ws-pin-btn:hover,
|
|
919
923
|
.ws-pin-btn.active {
|
|
920
|
-
background:
|
|
924
|
+
background: var(--control-hover-bg);
|
|
921
925
|
color: var(--text-bright);
|
|
922
926
|
border-color: var(--accent);
|
|
923
927
|
}
|
|
@@ -985,7 +989,7 @@ button.left-ws-item {
|
|
|
985
989
|
border-top: 1px solid var(--glass-border-1);
|
|
986
990
|
}
|
|
987
991
|
|
|
988
|
-
.left-collapse-btn:hover { background:
|
|
992
|
+
.left-collapse-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
989
993
|
.left-collapse-btn:active { transform: scale(0.92) translateZ(0); }
|
|
990
994
|
|
|
991
995
|
/* ============================================================
|
|
@@ -1102,7 +1106,7 @@ button.left-ws-item {
|
|
|
1102
1106
|
}
|
|
1103
1107
|
|
|
1104
1108
|
.conv-archive-btn:hover,
|
|
1105
|
-
.conv-rename-btn:hover { background:
|
|
1109
|
+
.conv-rename-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
1106
1110
|
|
|
1107
1111
|
.conv-archive-btn.archiving { cursor: default; border-color: var(--accent); }
|
|
1108
1112
|
.conv-archive-spinner {
|
|
@@ -1198,7 +1202,7 @@ button.left-ws-item {
|
|
|
1198
1202
|
|
|
1199
1203
|
.conv-pin-btn:hover,
|
|
1200
1204
|
.conv-pin-btn.active {
|
|
1201
|
-
background:
|
|
1205
|
+
background: var(--control-hover-bg);
|
|
1202
1206
|
color: var(--text-bright);
|
|
1203
1207
|
border-color: var(--accent);
|
|
1204
1208
|
}
|
|
@@ -1378,7 +1382,7 @@ button.left-ws-item {
|
|
|
1378
1382
|
position: relative;
|
|
1379
1383
|
}
|
|
1380
1384
|
|
|
1381
|
-
.tab-btn:hover { background:
|
|
1385
|
+
.tab-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
1382
1386
|
.tab-btn.active { background: rgba(91,120,255,0.12); color: var(--accent); border-color: rgba(91,120,255,0.2); }
|
|
1383
1387
|
.tab-btn:active { transform: scale(0.92) translateZ(0); }
|
|
1384
1388
|
.tab-btn .label { display: none; }
|
|
@@ -1474,7 +1478,7 @@ button.left-ws-item {
|
|
|
1474
1478
|
transition: background var(--duration-fast) var(--ease-out-expo);
|
|
1475
1479
|
}
|
|
1476
1480
|
|
|
1477
|
-
.et-btn:hover { background:
|
|
1481
|
+
.et-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
1478
1482
|
.et-btn.active { background:rgba(91,120,255,.16); color:var(--accent2); border-color:rgba(91,120,255,.55); }
|
|
1479
1483
|
.et-btn .nm-icon { width:15px; height:15px; }
|
|
1480
1484
|
.et-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
|
|
@@ -1518,6 +1522,7 @@ button.left-ws-item {
|
|
|
1518
1522
|
|
|
1519
1523
|
.browser-url-input {
|
|
1520
1524
|
flex: 1;
|
|
1525
|
+
min-width: 0;
|
|
1521
1526
|
padding: 5px 10px;
|
|
1522
1527
|
border: 1px solid var(--border);
|
|
1523
1528
|
border-radius: var(--radius-md);
|
|
@@ -1535,7 +1540,7 @@ button.left-ws-item {
|
|
|
1535
1540
|
min-height: 280px;
|
|
1536
1541
|
border: 1px solid var(--border);
|
|
1537
1542
|
border-radius: var(--radius-md);
|
|
1538
|
-
background:
|
|
1543
|
+
background: var(--bg);
|
|
1539
1544
|
overflow: hidden;
|
|
1540
1545
|
}
|
|
1541
1546
|
|
|
@@ -1578,15 +1583,21 @@ button.left-ws-item {
|
|
|
1578
1583
|
.md-rendered pre {
|
|
1579
1584
|
position: relative;
|
|
1580
1585
|
margin: 8px 0;
|
|
1581
|
-
padding:
|
|
1582
|
-
|
|
1586
|
+
padding: 0;
|
|
1587
|
+
max-width: 100%;
|
|
1588
|
+
min-width: 0;
|
|
1589
|
+
overflow: hidden;
|
|
1590
|
+
text-align: left;
|
|
1591
|
+
white-space: normal;
|
|
1583
1592
|
border: 1px solid var(--glass-border-1);
|
|
1584
1593
|
border-radius: var(--radius-sm);
|
|
1585
|
-
background:
|
|
1594
|
+
background: var(--glass-bg-3);
|
|
1586
1595
|
}
|
|
1587
1596
|
.md-rendered pre code {
|
|
1588
1597
|
display: block;
|
|
1589
|
-
padding:
|
|
1598
|
+
padding: 10px 12px;
|
|
1599
|
+
max-width: 100%;
|
|
1600
|
+
overflow-x: auto;
|
|
1590
1601
|
border: 0;
|
|
1591
1602
|
background: transparent;
|
|
1592
1603
|
white-space: pre;
|
|
@@ -1847,7 +1858,7 @@ button.left-ws-item {
|
|
|
1847
1858
|
|
|
1848
1859
|
.plan-status-btn.in-progress {
|
|
1849
1860
|
border-color: rgba(240,173,78,0.7);
|
|
1850
|
-
color:
|
|
1861
|
+
color: var(--nm-state-warning);
|
|
1851
1862
|
}
|
|
1852
1863
|
|
|
1853
1864
|
.plan-status-btn.done {
|
|
@@ -1978,7 +1989,7 @@ button.left-ws-item {
|
|
|
1978
1989
|
line-height: 1;
|
|
1979
1990
|
}
|
|
1980
1991
|
|
|
1981
|
-
.terminal-tab .close-tab:hover { background: rgba(255,80,80,0.3); color:
|
|
1992
|
+
.terminal-tab .close-tab:hover { background: rgba(255,80,80,0.3); color: var(--nm-state-danger); }
|
|
1982
1993
|
|
|
1983
1994
|
#terminal-body {
|
|
1984
1995
|
flex: 1;
|
|
@@ -2105,7 +2116,7 @@ button.left-ws-item {
|
|
|
2105
2116
|
transition: background var(--duration-fast) var(--ease-out-expo), color var(--duration-fast) var(--ease-out-expo);
|
|
2106
2117
|
}
|
|
2107
2118
|
|
|
2108
|
-
.shell-btn:hover { background:
|
|
2119
|
+
.shell-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
2109
2120
|
.shell-btn:active { transform: scale(0.95) translateZ(0); }
|
|
2110
2121
|
|
|
2111
2122
|
.shell-toggle-btn {
|
|
@@ -2171,9 +2182,7 @@ button.left-ws-item {
|
|
|
2171
2182
|
background-color: var(--chat-canvas);
|
|
2172
2183
|
}
|
|
2173
2184
|
.md-code-copy {
|
|
2174
|
-
|
|
2175
|
-
top: 6px;
|
|
2176
|
-
right: 7px;
|
|
2185
|
+
flex-shrink: 0;
|
|
2177
2186
|
border: 1px solid var(--glass-border-1);
|
|
2178
2187
|
border-radius: 4px;
|
|
2179
2188
|
background: var(--glass-bg-2);
|
|
@@ -2183,6 +2192,10 @@ button.left-ws-item {
|
|
|
2183
2192
|
cursor: pointer;
|
|
2184
2193
|
}
|
|
2185
2194
|
.md-code-copy:hover { color: var(--text); }
|
|
2195
|
+
.md-code-toolbar { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:6px 10px; border-bottom:1px solid var(--glass-border-1); color:var(--text-dim); font:11px var(--font-ui); }
|
|
2196
|
+
.md-code-toolbar > span { min-width:0; overflow:hidden; text-overflow:ellipsis; }
|
|
2197
|
+
.chat-msg.assistant > .msg-body { padding-right:28px; min-width:0; }
|
|
2198
|
+
.chat-msg.user > .msg-body { padding-left:28px; min-width:0; }
|
|
2186
2199
|
|
|
2187
2200
|
#chat-area {
|
|
2188
2201
|
flex: 1;
|
|
@@ -2372,10 +2385,10 @@ button.left-ws-item {
|
|
|
2372
2385
|
}
|
|
2373
2386
|
|
|
2374
2387
|
.chat-msg.error {
|
|
2375
|
-
color:
|
|
2388
|
+
color: var(--nm-state-danger);
|
|
2376
2389
|
}
|
|
2377
2390
|
|
|
2378
|
-
.chat-msg.guide-rejected::after { border-color:
|
|
2391
|
+
.chat-msg.guide-rejected::after { border-color: var(--nm-state-danger); }
|
|
2379
2392
|
|
|
2380
2393
|
.guide-receipt-status {
|
|
2381
2394
|
display: inline-flex;
|
|
@@ -2390,9 +2403,9 @@ button.left-ws-item {
|
|
|
2390
2403
|
opacity: 0.86;
|
|
2391
2404
|
}
|
|
2392
2405
|
|
|
2393
|
-
.guide-receipt-status.deferred { color:
|
|
2406
|
+
.guide-receipt-status.deferred { color: var(--nm-state-warning); border-color: rgba(255, 210, 122, 0.28); }
|
|
2394
2407
|
.guide-receipt-status.applied { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 30%, transparent); }
|
|
2395
|
-
.guide-receipt-status.rejected { color:
|
|
2408
|
+
.guide-receipt-status.rejected { color: var(--nm-state-danger); border-color: rgba(255, 136, 136, 0.34); }
|
|
2396
2409
|
|
|
2397
2410
|
.chat-msg .meta {
|
|
2398
2411
|
display: flex;
|
|
@@ -2413,7 +2426,7 @@ button.left-ws-item {
|
|
|
2413
2426
|
.chat-msg.user .msg-role { color: var(--accent); }
|
|
2414
2427
|
.chat-msg.assistant .msg-role { color: var(--accent2); }
|
|
2415
2428
|
.chat-msg.workflow .msg-role { color: var(--accent); }
|
|
2416
|
-
.chat-msg.error .msg-role { color:
|
|
2429
|
+
.chat-msg.error .msg-role { color: var(--nm-state-danger); }
|
|
2417
2430
|
.chat-msg.user .meta { justify-content: flex-end; text-align: right; }
|
|
2418
2431
|
.chat-msg.user .msg-body { text-align: right; }
|
|
2419
2432
|
.chat-msg.user .msg-actions { margin-left: 4px; }
|
|
@@ -2473,7 +2486,7 @@ button.left-ws-item {
|
|
|
2473
2486
|
.message-edit-submit { border-color: color-mix(in srgb, var(--accent) 55%, var(--glass-border-2)); color: var(--accent); }
|
|
2474
2487
|
.conversation-branch-pager { display:flex; justify-content:flex-end; align-items:center; gap:0; margin-top:7px; color:var(--text-dim); font-size:11px; }
|
|
2475
2488
|
.branch-page-arrow { cursor:pointer; color:var(--text-dim); padding:1px 3px; transition:color var(--duration-fast) var(--ease-out-expo), background var(--duration-fast) var(--ease-out-expo); border-radius:var(--radius-sm); }
|
|
2476
|
-
.branch-page-arrow:hover { color:var(--text-bright); background:
|
|
2489
|
+
.branch-page-arrow:hover { color:var(--text-bright); background:var(--control-hover-bg); }
|
|
2477
2490
|
.branch-page-arrow:active { transform:scale(0.92) translateZ(0); }
|
|
2478
2491
|
|
|
2479
2492
|
.chat-msg .msg-body .md-rendered {
|
|
@@ -2633,8 +2646,8 @@ button.left-ws-item {
|
|
|
2633
2646
|
.conversation-work-run-title { flex: 1; min-width: 0; }
|
|
2634
2647
|
.conversation-work-run-status { color: var(--text-dim); font: 10px var(--font-mono); }
|
|
2635
2648
|
.conversation-work-change-badge { display:inline-flex; align-items:center; gap:8px; margin-left:auto; padding:5px 10px; border:1px solid var(--border); border-radius:999px; background:var(--panel); color:var(--text-dim); font-size:11px; white-space:nowrap; }
|
|
2636
|
-
.conversation-work-change-badge .add { color
|
|
2637
|
-
.conversation-work-change-badge .del { color
|
|
2649
|
+
.conversation-work-change-badge .add { color:var(--nm-state-success); }
|
|
2650
|
+
.conversation-work-change-badge .del { color:var(--nm-state-danger); }
|
|
2638
2651
|
.conversation-work-run-body { border: 0; padding: 4px var(--work-run-right-safe) 8px 0; }
|
|
2639
2652
|
.conversation-work-run.collapsed .conversation-work-run-body { display: none; }
|
|
2640
2653
|
.work-run-collapsed-guides { display: none; }
|
|
@@ -2646,7 +2659,7 @@ button.left-ws-item {
|
|
|
2646
2659
|
.conversation-work-event { display: grid; grid-template-columns: 17px minmax(0,1fr); gap: 7px; align-items: start; color: var(--text-dim); font-size: 11px; line-height: 1.5; }
|
|
2647
2660
|
.conversation-work-event .nm-icon { margin-top: 1px; color: var(--text-dim); }
|
|
2648
2661
|
.conversation-work-event.guide { color: var(--text); padding: 3px 0; }
|
|
2649
|
-
.conversation-work-event.error { color:
|
|
2662
|
+
.conversation-work-event.error { color: var(--nm-state-danger); }
|
|
2650
2663
|
.conversation-work-event-content { min-width: 0; white-space: pre-wrap; word-break: break-word; }
|
|
2651
2664
|
.conversation-work-event.narrative { display: block; color: var(--text); font-size: 13px; line-height: 1.65; padding: 3px 1px 7px; }
|
|
2652
2665
|
.conversation-work-event.activity-summary { font-size: 11px; font-weight: 400; color: var(--text-dim); padding: 2px 0; }
|
|
@@ -2708,7 +2721,7 @@ button.left-ws-item {
|
|
|
2708
2721
|
.conversation-work-file-inline { margin: 1px 0; border: none; border-radius: 0; background: transparent; }
|
|
2709
2722
|
.conversation-work-file.conversation-work-file-inline > summary { display: grid; grid-template-columns: 17px minmax(0,max-content) auto 10px; gap: 7px; align-items: center; justify-content: start; width: fit-content; max-width: 100%; min-height: 24px; padding: 0; border-radius: var(--radius-sm); color: var(--text-dim); font: 400 11px/1.5 var(--font-ui); transition: background var(--duration-fast) var(--ease-out-expo); list-style: none; cursor: pointer; }
|
|
2710
2723
|
.conversation-work-file-inline > summary::-webkit-details-marker { display: none; }
|
|
2711
|
-
.conversation-work-file-inline > summary:hover { background:
|
|
2724
|
+
.conversation-work-file-inline > summary:hover { background: var(--control-hover-bg); }
|
|
2712
2725
|
.conversation-work-file-inline > summary .nm-icon { margin-top: 2px; color: var(--text-dim); }
|
|
2713
2726
|
.conversation-work-file-inline .conversation-work-file-name { font: inherit; }
|
|
2714
2727
|
.conversation-work-file-inline .conversation-work-file-stats { font: 10px/1.5 var(--font-mono); }
|
|
@@ -2717,13 +2730,13 @@ button.left-ws-item {
|
|
|
2717
2730
|
.conversation-work-file-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 12px var(--font-mono); }
|
|
2718
2731
|
.conversation-work-file-stats { display: inline-flex; gap: 7px; font: 11px var(--font-mono); }
|
|
2719
2732
|
.conversation-work-file-add { color: var(--accent2); }
|
|
2720
|
-
.conversation-work-file-del { color:
|
|
2733
|
+
.conversation-work-file-del { color: var(--nm-state-danger); }
|
|
2721
2734
|
.conversation-work-file-diff { max-height: 340px; overflow: auto; border-top: 1px solid var(--glass-border-1); background: rgba(0,0,0,.14); font: 11px/1.55 var(--font-mono); }
|
|
2722
2735
|
.conversation-work-file-line { display: grid; grid-template-columns: 42px minmax(0,1fr); min-height: 22px; white-space: pre; }
|
|
2723
2736
|
.conversation-work-file-line-number { padding: 2px 8px; color: var(--text-dim); text-align: right; user-select: none; border-right: 1px solid var(--glass-border-1); }
|
|
2724
2737
|
.conversation-work-file-line-code { padding: 2px 10px; overflow-wrap: normal; }
|
|
2725
|
-
.conversation-work-file-line.del { color:
|
|
2726
|
-
.conversation-work-file-line.add { color:
|
|
2738
|
+
.conversation-work-file-line.del { color: var(--nm-state-danger); background: rgba(255,68,68,.14); }
|
|
2739
|
+
.conversation-work-file-line.add { color: var(--nm-state-success); background: rgba(56,212,160,.13); }
|
|
2727
2740
|
.conversation-work-file-line.empty { color: var(--text-dim); }
|
|
2728
2741
|
.conversation-work-empty { color: var(--text-dim); font-size: 11px; }
|
|
2729
2742
|
|
|
@@ -2822,7 +2835,7 @@ button.left-ws-item {
|
|
|
2822
2835
|
transition: background var(--duration-fast) var(--ease-out-expo);
|
|
2823
2836
|
}
|
|
2824
2837
|
|
|
2825
|
-
.shell-block-header:hover { background:
|
|
2838
|
+
.shell-block-header:hover { background: var(--control-hover-bg); }
|
|
2826
2839
|
.shell-block-header .arrow { transition: transform var(--duration-fast) var(--ease-out-expo); font-size: 9px; }
|
|
2827
2840
|
.shell-block.collapsed .shell-block-header .arrow { transform: rotate(-90deg); }
|
|
2828
2841
|
.shell-block-body {
|
|
@@ -2858,7 +2871,7 @@ button.left-ws-item {
|
|
|
2858
2871
|
transition: background var(--duration-fast) var(--ease-out-expo);
|
|
2859
2872
|
}
|
|
2860
2873
|
|
|
2861
|
-
.diff-block-header:hover { background:
|
|
2874
|
+
.diff-block-header:hover { background: var(--control-hover-bg); }
|
|
2862
2875
|
.diff-block.collapsed .diff-block-body { display: none; }
|
|
2863
2876
|
.diff-block-header .arrow { transition: transform var(--duration-fast) var(--ease-out-expo); font-size: 9px; }
|
|
2864
2877
|
.diff-block.collapsed .diff-block-header .arrow { transform: rotate(-90deg); }
|
|
@@ -2882,7 +2895,7 @@ button.todo-item { background: transparent; }
|
|
|
2882
2895
|
|
|
2883
2896
|
.diff-stat { display: flex; gap: 8px; margin-left: auto; }
|
|
2884
2897
|
.diff-add { color: var(--accent2); font-size: 11px; }
|
|
2885
|
-
.diff-del { color:
|
|
2898
|
+
.diff-del { color: var(--nm-state-danger); font-size: 11px; }
|
|
2886
2899
|
.diff-block-body {
|
|
2887
2900
|
padding: 0;
|
|
2888
2901
|
font-family: var(--font-mono);
|
|
@@ -2898,7 +2911,7 @@ button.todo-item { background: transparent; }
|
|
|
2898
2911
|
}
|
|
2899
2912
|
|
|
2900
2913
|
.diff-line.add { background: rgba(56,212,160,0.1); color: var(--accent2); }
|
|
2901
|
-
.diff-line.del { background: rgba(255,68,68,0.1); color:
|
|
2914
|
+
.diff-line.del { background: rgba(255,68,68,0.1); color: var(--nm-state-danger); }
|
|
2902
2915
|
.diff-line.ctx { color: var(--text-dim); }
|
|
2903
2916
|
|
|
2904
2917
|
/* Option feedback */
|
|
@@ -3089,7 +3102,7 @@ button.todo-item { background: transparent; }
|
|
|
3089
3102
|
}
|
|
3090
3103
|
|
|
3091
3104
|
.stack-icon-btn:hover {
|
|
3092
|
-
background:
|
|
3105
|
+
background: var(--control-hover-bg);
|
|
3093
3106
|
color: var(--text-bright);
|
|
3094
3107
|
border-color: var(--glass-border-1);
|
|
3095
3108
|
}
|
|
@@ -3099,8 +3112,8 @@ button.todo-item { background: transparent; }
|
|
|
3099
3112
|
}
|
|
3100
3113
|
|
|
3101
3114
|
.stack-icon-btn:active { transform: scale(0.94); }
|
|
3102
|
-
.stack-icon-btn.warn { color:
|
|
3103
|
-
.stack-icon-btn.danger { color:
|
|
3115
|
+
.stack-icon-btn.warn { color: var(--nm-state-warning); }
|
|
3116
|
+
.stack-icon-btn.danger { color: var(--nm-state-danger); }
|
|
3104
3117
|
.stack-icon-btn:focus-visible {
|
|
3105
3118
|
border-color: var(--accent);
|
|
3106
3119
|
box-shadow: 0 0 0 3px var(--accent-glow);
|
|
@@ -3415,9 +3428,9 @@ button.todo-item { background: transparent; }
|
|
|
3415
3428
|
|
|
3416
3429
|
.conv-runtime-badge.running { color: var(--accent2); }
|
|
3417
3430
|
.conv-runtime-badge.stopping,
|
|
3418
|
-
.conv-runtime-badge.force_restarting { color:
|
|
3431
|
+
.conv-runtime-badge.force_restarting { color: var(--nm-state-warning); }
|
|
3419
3432
|
.conv-runtime-badge.error,
|
|
3420
|
-
.conv-runtime-badge.force_interrupted { color:
|
|
3433
|
+
.conv-runtime-badge.force_interrupted { color: var(--nm-state-danger); }
|
|
3421
3434
|
|
|
3422
3435
|
.queue-edit:focus {
|
|
3423
3436
|
color: var(--text-bright);
|
|
@@ -4109,7 +4122,7 @@ button.todo-item { background: transparent; }
|
|
|
4109
4122
|
}
|
|
4110
4123
|
|
|
4111
4124
|
#scroll-bottom-btn.visible { display: flex; }
|
|
4112
|
-
#scroll-bottom-btn:hover { background:
|
|
4125
|
+
#scroll-bottom-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); box-shadow: var(--shadow-lg); }
|
|
4113
4126
|
|
|
4114
4127
|
/* ============================================================
|
|
4115
4128
|
MARQUEE BORDER
|
|
@@ -4390,8 +4403,8 @@ button.todo-item { background: transparent; }
|
|
|
4390
4403
|
transition: background var(--duration-fast) var(--ease-out-expo), color var(--duration-fast) var(--ease-out-expo);
|
|
4391
4404
|
}
|
|
4392
4405
|
|
|
4393
|
-
.sub-win-close:hover { background: rgba(255,68,68,0.15); color:
|
|
4394
|
-
.sub-win-close:focus-visible { outline:none; color
|
|
4406
|
+
.sub-win-close:hover { background: rgba(255,68,68,0.15); color: var(--nm-state-danger); }
|
|
4407
|
+
.sub-win-close:focus-visible { outline:none; color:var(--nm-state-danger); box-shadow:inset 0 0 0 2px currentColor; }
|
|
4395
4408
|
|
|
4396
4409
|
.sub-win-body {
|
|
4397
4410
|
flex: 1;
|
|
@@ -4596,7 +4609,7 @@ textarea.mcp-input { min-height:76px; resize:vertical; font-family:var(--font-mo
|
|
|
4596
4609
|
.remote-touch-status:hover { background: transparent !important; }
|
|
4597
4610
|
.remote-touch-status.listening { color: var(--accent2); }
|
|
4598
4611
|
.remote-touch-status.error,
|
|
4599
|
-
.remote-touch-status.checking { color:
|
|
4612
|
+
.remote-touch-status.checking { color: var(--nm-state-warning); }
|
|
4600
4613
|
.remote-touch-status.off { color: var(--notice-error-text); }
|
|
4601
4614
|
.remote-touch-status[aria-busy="true"] { cursor: wait; }
|
|
4602
4615
|
|
|
@@ -4825,8 +4838,8 @@ textarea.mcp-input { min-height:76px; resize:vertical; font-family:var(--font-mo
|
|
|
4825
4838
|
.github-repo-select-icon { position:absolute; right:11px; top:50%; width:14px; height:14px; transform:translateY(-50%); color:var(--text-dim); pointer-events:none; display:inline-flex; align-items:center; justify-content:center; }
|
|
4826
4839
|
.model-eval-line { display:block; margin-top:4px; font-size:10px; color:var(--text-dim); }
|
|
4827
4840
|
.model-eval-ok { color: var(--accent2); }
|
|
4828
|
-
.model-eval-bad { color:
|
|
4829
|
-
.model-eval-pending { color:
|
|
4841
|
+
.model-eval-bad { color: var(--nm-state-danger); }
|
|
4842
|
+
.model-eval-pending { color: var(--nm-state-warning); }
|
|
4830
4843
|
|
|
4831
4844
|
/* Memory Lab tag graph */
|
|
4832
4845
|
.memory-lab-panel {
|
|
@@ -5436,7 +5449,7 @@ html.newmark-memory-overview-viewer body {
|
|
|
5436
5449
|
transition: color var(--duration-fast) var(--ease-out-expo);
|
|
5437
5450
|
}
|
|
5438
5451
|
|
|
5439
|
-
.model-chip .remove:hover { color:
|
|
5452
|
+
.model-chip .remove:hover { color: var(--nm-state-danger); }
|
|
5440
5453
|
|
|
5441
5454
|
.model-eval-results {
|
|
5442
5455
|
margin-top: 10px;
|
|
@@ -5534,8 +5547,8 @@ html.newmark-memory-overview-viewer body {
|
|
|
5534
5547
|
transition: background var(--duration-fast) var(--ease-out-expo);
|
|
5535
5548
|
}
|
|
5536
5549
|
|
|
5537
|
-
.archive-action-btn:hover { background:
|
|
5538
|
-
.archive-action-btn.danger:hover { background: rgba(255,68,68,0.15); color:
|
|
5550
|
+
.archive-action-btn:hover { background: var(--control-hover-bg); color: var(--text-bright); }
|
|
5551
|
+
.archive-action-btn.danger:hover { background: rgba(255,68,68,0.15); color: var(--nm-state-danger); }
|
|
5539
5552
|
|
|
5540
5553
|
/* ============================================================
|
|
5541
5554
|
AUTOMATION WINDOW
|
|
@@ -6243,11 +6256,12 @@ input[type="checkbox"]::before {
|
|
|
6243
6256
|
width: 18px;
|
|
6244
6257
|
height: 18px;
|
|
6245
6258
|
border-radius: 50%;
|
|
6246
|
-
background: var(--text
|
|
6259
|
+
background: var(--text);
|
|
6247
6260
|
box-shadow: 0 2px 5px rgba(0,0,0,.28);
|
|
6248
6261
|
transform: translateX(var(--liquid-switch-x)) scale(1);
|
|
6249
6262
|
transition: transform 160ms var(--ease-out-expo), box-shadow 100ms var(--ease-out-expo), background 100ms var(--ease-out-expo);
|
|
6250
6263
|
}
|
|
6264
|
+
input[type="checkbox"]:checked::before { background: #fff; }
|
|
6251
6265
|
input[type="checkbox"].liquid-switch-dragging::before {
|
|
6252
6266
|
left: 1px;
|
|
6253
6267
|
width: 22px;
|
|
@@ -7129,6 +7143,10 @@ var state = {
|
|
|
7129
7143
|
_conversationLoadingMsgEl: null,
|
|
7130
7144
|
_syncedMode: null,
|
|
7131
7145
|
_syncedModel: null,
|
|
7146
|
+
// Monotonic revision for explicit renderer model changes. Activation
|
|
7147
|
+
// snapshots may restore the conversation's remembered model only when no
|
|
7148
|
+
// newer local selection was made while the snapshot was in flight.
|
|
7149
|
+
modelSelectionRevision: 0,
|
|
7132
7150
|
_syncedInputMode: null,
|
|
7133
7151
|
_editingQueueIndex: -1,
|
|
7134
7152
|
_editingGoalText: '',
|
|
@@ -9207,7 +9225,7 @@ function renderMarkdownBlocks(text) {
|
|
|
9207
9225
|
var code = codeLines.join('\n');
|
|
9208
9226
|
var normalizedLanguage = lang ? normalizeCodeLanguage(lang) : 'text';
|
|
9209
9227
|
var highlighted = normalizedLanguage === 'text' ? esc(code) : highlightCodeByLanguage(code, normalizedLanguage);
|
|
9210
|
-
html += '<pre><button class="md-code-copy" type="button" title="' + escAttr(t('common.copy')) + '" data-code="' + escAttr(code) + '" onclick="window.copyMarkdownCode(this)">' + esc(t('common.copy')) + '</button><code' + (lang ? ' data-lang="' + escAttr(lang) + '"' : '') + ' class="md-code-block language-' + escAttr(normalizedLanguage) + '">' + highlighted + '</code></pre>';
|
|
9228
|
+
html += '<pre><div class="md-code-toolbar"><span>' + esc(lang || 'text') + '</span><button class="md-code-copy" type="button" aria-label="' + escAttr(currentLang() === 'zh' ? '复制代码' : 'Copy code') + '" title="' + escAttr(t('common.copy')) + '" data-code="' + escAttr(code) + '" onclick="window.copyMarkdownCode(this)">' + esc(t('common.copy')) + '</button></div><code' + (lang ? ' data-lang="' + escAttr(lang) + '"' : '') + ' class="md-code-block language-' + escAttr(normalizedLanguage) + '">' + highlighted + '</code></pre>';
|
|
9211
9229
|
continue;
|
|
9212
9230
|
}
|
|
9213
9231
|
if (trimmed === '$$' || trimmed === '\\[') {
|
|
@@ -9339,7 +9357,7 @@ var api = window.api || {
|
|
|
9339
9357
|
conversationId: target.conversationId,
|
|
9340
9358
|
action: action
|
|
9341
9359
|
};
|
|
9342
|
-
['id', 'text', 'value', 'requestedMode', 'goalObjective', 'createdAt', 'images', 'paused', 'orderedIds'].forEach(function(field) {
|
|
9360
|
+
['id', 'text', 'value', 'requestedMode', 'goalObjective', 'createdAt', 'images', 'paused', 'orderedIds', 'branchNodeId', 'branchPath'].forEach(function(field) {
|
|
9343
9361
|
if (input && Object.prototype.hasOwnProperty.call(input, field)) body[field] = input[field];
|
|
9344
9362
|
});
|
|
9345
9363
|
var r = await fetch('/api/queue-action', {
|
|
@@ -11924,9 +11942,11 @@ function updateConversationWorkRunElement(run, element) {
|
|
|
11924
11942
|
}
|
|
11925
11943
|
var running = ['running', 'stopping', 'force_restarting'].indexOf(String(run.status || '')) >= 0;
|
|
11926
11944
|
var expanded = !!run.expanded;
|
|
11927
|
-
|
|
11928
|
-
element.
|
|
11929
|
-
element.
|
|
11945
|
+
var nextClassName = 'conversation-work-run ' + (running ? 'running ' : '') + (expanded ? 'expanded' : 'collapsed');
|
|
11946
|
+
if (element.className !== nextClassName) element.className = nextClassName;
|
|
11947
|
+
if (element.getAttribute('data-run-id') !== String(run.runId)) element.setAttribute('data-run-id', run.runId);
|
|
11948
|
+
var nextRuntimeKey = runtimeKeyFor(run.target && run.target.workspaceId, run.target && run.target.conversationId);
|
|
11949
|
+
if (element.getAttribute('data-runtime-key') !== nextRuntimeKey) element.setAttribute('data-runtime-key', nextRuntimeKey);
|
|
11930
11950
|
var head = element.querySelector ? element.querySelector('.conversation-work-run-head') : null;
|
|
11931
11951
|
if (!head) {
|
|
11932
11952
|
element.innerHTML = '<button class="conversation-work-run-head" type="button" onclick="window.toggleConversationWorkRun(this)">' +
|
|
@@ -12004,7 +12024,9 @@ function updateConversationWorkRunElement(run, element) {
|
|
|
12004
12024
|
var refreshedParentKey = String(refreshedParent && refreshedParent.getAttribute('data-activity-key') || '');
|
|
12005
12025
|
var refreshedDetailKey = String(refreshedActivities[refreshedIndex].getAttribute('data-work-detail-key') || 'activity');
|
|
12006
12026
|
var refreshedKey = refreshedParentKey ? refreshedParentKey + '::' + refreshedDetailKey : '';
|
|
12007
|
-
if (activityOpenStates[refreshedKey] !== undefined
|
|
12027
|
+
if (activityOpenStates[refreshedKey] !== undefined && refreshedActivities[refreshedIndex].open !== activityOpenStates[refreshedKey]) {
|
|
12028
|
+
refreshedActivities[refreshedIndex].open = activityOpenStates[refreshedKey];
|
|
12029
|
+
}
|
|
12008
12030
|
}
|
|
12009
12031
|
if (chatEl) {
|
|
12010
12032
|
if (wasAtBottom) {
|
|
@@ -13269,6 +13291,35 @@ function hydrateConversationBranchState(snapshot) {
|
|
|
13269
13291
|
rememberRuntimeConversationBranchPath(currentConversationTarget(s.conversationId || activeConversationId()));
|
|
13270
13292
|
}
|
|
13271
13293
|
|
|
13294
|
+
// Apply the conversation's remembered provider-qualified model to the
|
|
13295
|
+
// composer selector. The backend snapshot is authoritative; a newer explicit
|
|
13296
|
+
// user selection made while the snapshot was in flight wins via the revision
|
|
13297
|
+
// guard passed by the activation caller.
|
|
13298
|
+
function applyConversationModelSelection(snapshot) {
|
|
13299
|
+
var nextModel = String(snapshot && snapshot.model || '').trim();
|
|
13300
|
+
if (!nextModel) return;
|
|
13301
|
+
state.model = nextModel;
|
|
13302
|
+
if (typeof snapshot.modelLabel === 'string' && snapshot.modelLabel) state.modelLabel = snapshot.modelLabel;
|
|
13303
|
+
state._syncedModel = nextModel;
|
|
13304
|
+
var sel = els['model-select'] || document.getElementById('model-select');
|
|
13305
|
+
if (!sel) {
|
|
13306
|
+
if (window.syncModelSelectSurface) window.syncModelSelectSurface();
|
|
13307
|
+
return;
|
|
13308
|
+
}
|
|
13309
|
+
var hasOption = Array.prototype.some.call(sel.options, function(option) {
|
|
13310
|
+
return String(option.value || '') === nextModel;
|
|
13311
|
+
});
|
|
13312
|
+
if (hasOption) {
|
|
13313
|
+
sel.value = nextModel;
|
|
13314
|
+
window.syncModelSelectSurface();
|
|
13315
|
+
} else if (window.refreshModelSelect) {
|
|
13316
|
+
// The remembered deployment is not in the current enabled catalog (for
|
|
13317
|
+
// example its provider was explicitly disabled). Reuse the existing
|
|
13318
|
+
// visibility fallback instead of displaying a model that cannot run.
|
|
13319
|
+
window.refreshModelSelect();
|
|
13320
|
+
}
|
|
13321
|
+
}
|
|
13322
|
+
|
|
13272
13323
|
function applyConversationSnapshot(s, requestedConversationId, options) {
|
|
13273
13324
|
if (!s) return;
|
|
13274
13325
|
if (s.computerUse) {
|
|
@@ -13291,6 +13342,11 @@ function applyConversationSnapshot(s, requestedConversationId, options) {
|
|
|
13291
13342
|
if (s && s.runtimeKey) registerRuntimeKey(snapshotTarget, s.runtimeKey);
|
|
13292
13343
|
hydrateConversationDraftSnapshot(s, snapshotTarget);
|
|
13293
13344
|
hydrateConversationBranchState(s);
|
|
13345
|
+
var modelRevisionMatches = !options || options.modelRevision === undefined
|
|
13346
|
+
|| Number(state.modelSelectionRevision || 0) === Number(options.modelRevision || 0);
|
|
13347
|
+
if (modelRevisionMatches && isActiveConversationTarget(snapshotTarget)) {
|
|
13348
|
+
applyConversationModelSelection(s);
|
|
13349
|
+
}
|
|
13294
13350
|
rebindQueueToRuntimeBranch(snapshotTarget);
|
|
13295
13351
|
if (s && Array.isArray(s.workRuns) && !preserveReadableHistory) {
|
|
13296
13352
|
var viewedBranchIdForSync = Array.isArray(s.viewedBranchNodePath) && s.viewedBranchNodePath.length
|
|
@@ -14009,6 +14065,19 @@ function positionContextInspector() {
|
|
|
14009
14065
|
panel.style.maxHeight = Math.max(0, Math.floor(ring.getBoundingClientRect().top - visibleTop - 20)) + 'px';
|
|
14010
14066
|
panel.style.overflowY = 'auto';
|
|
14011
14067
|
panel.style.overscrollBehavior = 'contain';
|
|
14068
|
+
// The chat column clips its descendants. Clamp to that column rather than
|
|
14069
|
+
// the desktop viewport so a narrow composer cannot hide half the inspector.
|
|
14070
|
+
var column = document.getElementById('center');
|
|
14071
|
+
var parent = panel.offsetParent;
|
|
14072
|
+
if (column && parent) {
|
|
14073
|
+
var bounds = column.getBoundingClientRect();
|
|
14074
|
+
var origin = parent.getBoundingClientRect();
|
|
14075
|
+
var width = Math.min(320, Math.max(0, bounds.width - 24));
|
|
14076
|
+
var left = Math.max(bounds.left + 12, Math.min(origin.right + 8 - width, bounds.right - 12 - width));
|
|
14077
|
+
panel.style.width = width + 'px';
|
|
14078
|
+
panel.style.left = (left - origin.left) + 'px';
|
|
14079
|
+
panel.style.right = 'auto';
|
|
14080
|
+
}
|
|
14012
14081
|
}
|
|
14013
14082
|
|
|
14014
14083
|
window.renderContextInspector = function() {
|
|
@@ -14109,6 +14178,10 @@ window.closeContextInspector = function() {
|
|
|
14109
14178
|
|
|
14110
14179
|
(function() {
|
|
14111
14180
|
window.addEventListener('resize', positionContextInspector);
|
|
14181
|
+
if (typeof ResizeObserver === 'function') {
|
|
14182
|
+
var contextColumn = document.getElementById('center');
|
|
14183
|
+
if (contextColumn) new ResizeObserver(positionContextInspector).observe(contextColumn);
|
|
14184
|
+
}
|
|
14112
14185
|
document.addEventListener('click', function(event) {
|
|
14113
14186
|
if (!state.contextInspectorOpen) return;
|
|
14114
14187
|
var ring = document.getElementById('context-token-ring');
|
|
@@ -14408,6 +14481,7 @@ function applyModelFallbackToInputSurface(event) {
|
|
|
14408
14481
|
var nextValue = modelDeploymentValueForName(f.to, f.providerId || '');
|
|
14409
14482
|
if (!nextValue || String(state.model || '') === nextValue) return;
|
|
14410
14483
|
state.model = nextValue;
|
|
14484
|
+
state.modelSelectionRevision = Number(state.modelSelectionRevision || 0) + 1;
|
|
14411
14485
|
state.modelLabel = '';
|
|
14412
14486
|
// 不预置 _syncedModel:下一次发送前的 syncConversationExecutionState 会把
|
|
14413
14487
|
// 回退模型正式同步到后端 host agent(并持久化为该对话的首选模型)。
|
|
@@ -15829,6 +15903,15 @@ function wireDirectLiquidMenuInteractionsV2(menu) {
|
|
|
15829
15903
|
ensureBlock();
|
|
15830
15904
|
}
|
|
15831
15905
|
|
|
15906
|
+
function cancelLiquidPopupExit(popup) {
|
|
15907
|
+
if (!popup) return;
|
|
15908
|
+
if (popup._liquidExitTimer) clearTimeout(popup._liquidExitTimer);
|
|
15909
|
+
popup._liquidExitTimer = 0;
|
|
15910
|
+
popup.classList.remove('liquid-popup-exit');
|
|
15911
|
+
popup.style.removeProperty('--liquid-popup-origin-x');
|
|
15912
|
+
popup.style.removeProperty('--liquid-popup-origin-y');
|
|
15913
|
+
}
|
|
15914
|
+
|
|
15832
15915
|
window.animateLiquidPopupExit = function(popup, anchor, done) {
|
|
15833
15916
|
if (!popup) { if (done) done(); return; }
|
|
15834
15917
|
clearLiquidPopupOutset(popup, true);
|
|
@@ -17164,6 +17247,11 @@ function bindBackendQueuedRequestToTarget(text, target, occurrence) {
|
|
|
17164
17247
|
request.createdAt = queueItem.createdAt;
|
|
17165
17248
|
request.runId = queueItem.runId;
|
|
17166
17249
|
request.images = (queueItem.images || []).map(function(image) { return Object.assign({}, image); });
|
|
17250
|
+
if (Array.isArray(queueItem.branchPath) && queueItem.branchPath.length) {
|
|
17251
|
+
request.branchPath = queueItem.branchPath.join('>');
|
|
17252
|
+
} else if (queueItem.branchNodeId) {
|
|
17253
|
+
request.branchPath = String(queueItem.branchNodeId);
|
|
17254
|
+
}
|
|
17167
17255
|
}
|
|
17168
17256
|
return request;
|
|
17169
17257
|
}
|
|
@@ -17876,7 +17964,15 @@ window.sendMessage = async function(modeOverride, queuedText, opts) {
|
|
|
17876
17964
|
queuedModeRequest.goalDeclaration = true;
|
|
17877
17965
|
queuedModeRequest.goalObjective = rawText;
|
|
17878
17966
|
}
|
|
17879
|
-
var
|
|
17967
|
+
var queuedBranchPath = Array.isArray(queuedModeRequest.branchPath)
|
|
17968
|
+
? queuedModeRequest.branchPath
|
|
17969
|
+
: String(queuedModeRequest.branchPath || '').split('>').filter(Boolean);
|
|
17970
|
+
var queueResult = await api.sendMessage({
|
|
17971
|
+
text: rawText,
|
|
17972
|
+
images: queuedModeRequest.images,
|
|
17973
|
+
branchPath: queuedBranchPath,
|
|
17974
|
+
branchNodeId: String(queuedBranchPath[queuedBranchPath.length - 1] || '')
|
|
17975
|
+
}, lockedTarget, {
|
|
17880
17976
|
clientMessageId: queuedModeRequest.clientMessageId,
|
|
17881
17977
|
inputMode: 'next',
|
|
17882
17978
|
requestedMode: requestedMode,
|
|
@@ -18073,12 +18169,6 @@ window.sendMessage = async function(modeOverride, queuedText, opts) {
|
|
|
18073
18169
|
updateSubmitButtonState();
|
|
18074
18170
|
var executionMode = opts.goalDeclaration || requestedMode === 'goal' ? 'build'
|
|
18075
18171
|
: ((opts.forceBuild || idleBuildNextImmediate) && requestedMode === 'build' ? 'build' : requestedMode);
|
|
18076
|
-
// The command freezes its mode and delivery policy; selector persistence
|
|
18077
|
-
// must not rewrite the mode of an already running target before acceptance.
|
|
18078
|
-
if (api.setModel && state.model !== state._syncedModel) {
|
|
18079
|
-
var selectedModelResult = await api.setModel(state.model);
|
|
18080
|
-
if (selectedModelResult != null) state._syncedModel = state.model;
|
|
18081
|
-
}
|
|
18082
18172
|
if (consumeProvisionalStop(lockedTarget, localRunId)) {
|
|
18083
18173
|
// Stop/Escape won before the backend accepted the prompt. Do not send the
|
|
18084
18174
|
// provider request after the user has already cancelled it.
|
|
@@ -18122,10 +18212,20 @@ window.sendMessage = async function(modeOverride, queuedText, opts) {
|
|
|
18122
18212
|
try {
|
|
18123
18213
|
var activationBeforeSend = pendingConversationActivation(lockedTarget);
|
|
18124
18214
|
if (activationBeforeSend) await activationBeforeSend;
|
|
18215
|
+
// Bind the model actually shown in the composer to the exact target
|
|
18216
|
+
// conversation after its activation snapshot restored the remembered
|
|
18217
|
+
// selection. This makes the visible provider/model authoritative for the
|
|
18218
|
+
// send and prevents a stale renderer selection from reaching another
|
|
18219
|
+
// conversation's remembered deployment.
|
|
18220
|
+
if (api.setModel && state.model && state.model !== state._syncedModel) {
|
|
18221
|
+
var selectedModelResult = await api.setModel(state.model);
|
|
18222
|
+
if (selectedModelResult != null) state._syncedModel = state.model;
|
|
18223
|
+
}
|
|
18125
18224
|
var sendPromise = api.sendMessage(requestMessage, lockedTarget, {
|
|
18126
18225
|
requestedMode: requestedMode, inputMode: effectiveInputMode,
|
|
18127
18226
|
goalObjective: opts.goalObjective || '',
|
|
18128
|
-
clientMessageId: String(requestMessage && requestMessage.clientMessageId || localRunId)
|
|
18227
|
+
clientMessageId: String(requestMessage && requestMessage.clientMessageId || localRunId),
|
|
18228
|
+
model: state.model
|
|
18129
18229
|
});
|
|
18130
18230
|
if (requestedMode === 'goal') activateSubmittedGoal(opts.goalObjective || rawText);
|
|
18131
18231
|
var r = await sendPromise;
|
|
@@ -19843,9 +19943,13 @@ function trapNewmarkDialogFocus(event, container) {
|
|
|
19843
19943
|
}
|
|
19844
19944
|
|
|
19845
19945
|
window.openSubWin = function(title, html) {
|
|
19946
|
+
// A replacement can open during the outgoing glass's 210ms exit. Retire
|
|
19947
|
+
// that exit before it can hide the newly mounted content or restore focus.
|
|
19948
|
+
var replacingExitingWindow = !!els['sub-win']._liquidExitTimer;
|
|
19949
|
+
cancelLiquidPopupExit(els['sub-win']);
|
|
19846
19950
|
var overlayOpen = els['sub-win-overlay'].classList.contains('open');
|
|
19847
19951
|
if (!overlayOpen && document.activeElement && typeof document.activeElement.focus === 'function') subWindowOriginFocus = document.activeElement;
|
|
19848
|
-
if (overlayOpen && !state.restoringSubWindow && state.activeSubWindowView) {
|
|
19952
|
+
if (overlayOpen && !replacingExitingWindow && !state.restoringSubWindow && state.activeSubWindowView) {
|
|
19849
19953
|
if (!state.subWindowStack) state.subWindowStack = [];
|
|
19850
19954
|
state.subWindowStack.push({
|
|
19851
19955
|
view: Object.assign({}, state.activeSubWindowView),
|
|
@@ -20504,6 +20608,7 @@ function applyUiAppearance() {
|
|
|
20504
20608
|
}
|
|
20505
20609
|
applyGlassPresentation(glassPresentationForOpacity(state.glassLevel));
|
|
20506
20610
|
window.refreshTitlebarThemeIcon();
|
|
20611
|
+
document.querySelectorAll('webview[data-newmark-browser-runtime-key]').forEach(syncBlankBrowserGuestTheme);
|
|
20507
20612
|
}
|
|
20508
20613
|
|
|
20509
20614
|
window.setTheme = function(value) {
|
|
@@ -21207,7 +21312,7 @@ window.validateAllModels = function() {
|
|
|
21207
21312
|
return state.modelValidationResults;
|
|
21208
21313
|
}).catch(function(err) {
|
|
21209
21314
|
document.body.classList.remove('model-evaluating');
|
|
21210
|
-
var failedHtml = '<div style="color
|
|
21315
|
+
var failedHtml = '<div style="color:var(--nm-state-danger);font-size:12px;">' + esc(t('model.validationFailed')) + ': ' + esc(err.message) + '</div>';
|
|
21211
21316
|
var body = document.getElementById('sub-win-body');
|
|
21212
21317
|
if (body && document.getElementById('model-validation-progress') && els['sub-win-overlay'].classList.contains('open')) {
|
|
21213
21318
|
body.innerHTML = failedHtml;
|
|
@@ -21483,7 +21588,7 @@ window.showAutomationWindow = function() {
|
|
|
21483
21588
|
'<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px;">' +
|
|
21484
21589
|
'<span style="font-size:11px;flex:1;color:var(--text);">' + esc(a.prompt) + '</span>' +
|
|
21485
21590
|
'<button class="sec-btn" style="font-size:9px;padding:2px 8px;" onclick="window.toggleAutomation(' + ai + ')">' + (a.active ? esc(t('automation.active')) : esc(t('automation.paused'))) + '</button>' +
|
|
21486
|
-
'<button class="sec-btn" style="font-size:0;padding:2px 8px;color
|
|
21591
|
+
'<button class="sec-btn" style="font-size:0;padding:2px 8px;color:var(--nm-state-danger);" onclick="window.deleteAutomation(' + ai + ')" title="' + escAttr(t('common.delete')) + '">' + iconSvg('trash', t('common.delete'), 'tiny') + '</button>' +
|
|
21487
21592
|
'</div>' +
|
|
21488
21593
|
'<div style="font-size:10px;color:var(--text-dim);">' + esc(t('message.model')) + ': ' + esc(a.model) + ' | ' + esc(t('automation.condition')) + ': ' + a.condition + '</div>' +
|
|
21489
21594
|
'</div>';
|
|
@@ -21563,7 +21668,7 @@ window.showAutomationWindow = async function() {
|
|
|
21563
21668
|
var wakeHtml = '';
|
|
21564
21669
|
if (wake) {
|
|
21565
21670
|
wakeHtml = '<div id="automation-wake-status" style="padding:8px 10px;margin-bottom:8px;border-radius:8px;background:var(--glass-bg-1);border:1px solid var(--glass-border-1);font-size:10px;color:var(--text-dim);">' +
|
|
21566
|
-
'<div style="color:var(--text);font-size:11px;margin-bottom:3px;">' + esc(t('automation.osWake')) + ': ' + (wake.registered ? '<span style="color:var(--accent2);">' + esc(t('automation.registered')) + '</span>' : (wake.active ? '<span style="color
|
|
21671
|
+
'<div style="color:var(--text);font-size:11px;margin-bottom:3px;">' + esc(t('automation.osWake')) + ': ' + (wake.registered ? '<span style="color:var(--accent2);">' + esc(t('automation.registered')) + '</span>' : (wake.active ? '<span style="color:var(--nm-state-warning);">' + esc(t('automation.pending')) + '</span>' : '<span>' + esc(t('automation.inactive')) + '</span>')) + '</div>' +
|
|
21567
21672
|
'<div>' + esc(t('automation.task')) + ': ' + esc(wake.taskName || '-') + '</div>' +
|
|
21568
21673
|
'<div>' + esc(t('automation.next')) + ': ' + esc(wake.nextRunAt ? new Date(wake.nextRunAt).toLocaleString(uiLocale()) : '-') + '</div>' +
|
|
21569
21674
|
(wake.skippedReason ? '<div>' + esc(wake.skippedReason) + '</div>' : '') +
|
|
@@ -21583,12 +21688,12 @@ window.showAutomationWindow = async function() {
|
|
|
21583
21688
|
'<div style="display:flex;align-items:center;gap:6px;margin-bottom:5px;">' +
|
|
21584
21689
|
'<span style="font-size:11px;flex:1;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' + esc(a.prompt || '') + '">' + esc(a.prompt || '') + '</span>' +
|
|
21585
21690
|
'<button class="sec-btn" style="font-size:9px;padding:2px 8px;' + (a.active ? 'Active' : 'Paused') + '" onclick="window.toggleAutomationById(' + JSON.stringify(a.id).replace(/"/g, '"') + ')">' + (a.active ? esc(t('automation.active')) : esc(t('automation.paused'))) + '</button>' +
|
|
21586
|
-
'<button class="sec-btn" style="font-size:9px;padding:2px 8px;color
|
|
21691
|
+
'<button class="sec-btn" style="font-size:9px;padding:2px 8px;color:var(--nm-state-danger);" onclick="window.deleteAutomationById(' + JSON.stringify(a.id).replace(/"/g, '"') + ')">' + esc(t('common.delete')) + '</button>' +
|
|
21587
21692
|
'</div>' +
|
|
21588
21693
|
'<div style="font-size:10px;color:var(--text-dim);">' + esc(t('automation.workspace')) + ': ' + esc(a.workspaceName || a.workspaceId || '-') + ' | ' + esc(t('automation.conversation')) + ': ' + esc(a.conversationMode === 'existing' ? (a.conversationId || '-') : t('automation.newConversation')) + '</div>' +
|
|
21589
21694
|
'<div style="font-size:10px;color:var(--text-dim);">' + esc(t('message.model')) + ': ' + esc(a.model || t('common.current')) + ' | ' + esc(t('automation.type')) + ': ' + esc(a.condition || 'once') + ' | ' + esc(t('automation.status')) + ': ' + status + ' | ' + esc(t('automation.runs')) + ': ' + (a.runCount || 0) + '</div>' +
|
|
21590
21695
|
'<div style="font-size:10px;color:var(--text-dim);">' + esc(t('automation.next')) + ': ' + esc(next) + ' | ' + esc(t('automation.last')) + ': ' + esc(last) + '</div>' +
|
|
21591
|
-
(lastLine ? '<div style="font-size:10px;color:' + (a.lastError ? '
|
|
21696
|
+
(lastLine ? '<div style="font-size:10px;color:' + (a.lastError ? 'var(--nm-state-danger)' : 'var(--text-dim)') + ';margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">' + esc(lastLine) + '</div>' : '') +
|
|
21592
21697
|
'</div>';
|
|
21593
21698
|
}
|
|
21594
21699
|
}
|
|
@@ -21748,7 +21853,7 @@ function renderFlowItem(work, idx, expanded) {
|
|
|
21748
21853
|
'<button class="sec-btn" style="flex:1;font-size:10px;" onclick="window.addFlowComp(' + idx + ',\'logic\')">+ ' + esc(t('flow.logic')) + '</button>' +
|
|
21749
21854
|
'<button class="sec-btn primary" style="flex:0;padding:6px 8px;font-size:10px;" onclick="window.runFlowWork(' + idx + ')" title="' + escAttr(t('flow.run')) + '">' + esc(t('flow.run')) + '</button>' +
|
|
21750
21855
|
'<button class="sec-btn" style="flex:0;padding:6px 8px;font-size:10px;" onclick="window.saveFlowToDisk(' + idx + ')" title="' + escAttr(t('flow.save')) + '">' + esc(t('flow.save')) + '</button>' +
|
|
21751
|
-
'<button class="sec-btn" style="flex:0;padding:6px 8px;font-size:0;color
|
|
21856
|
+
'<button class="sec-btn" style="flex:0;padding:6px 8px;font-size:0;color:var(--nm-state-danger);" onclick="window.deleteFlowWork(' + idx + ')" title="' + escAttr(t('flow.deleteWorkflow')) + '">' + iconSvg('trash', t('flow.deleteWorkflow'), 'tiny') + '</button>' +
|
|
21752
21857
|
'</div>' + componentsHtml +
|
|
21753
21858
|
'</div></div>';
|
|
21754
21859
|
}
|
|
@@ -23495,6 +23600,29 @@ function createBrowserGuestElement(target) {
|
|
|
23495
23600
|
return view;
|
|
23496
23601
|
}
|
|
23497
23602
|
|
|
23603
|
+
window.setBrowserViewport = function(contentsId, viewport) {
|
|
23604
|
+
var views = document.querySelectorAll('webview[data-newmark-browser-runtime-key]');
|
|
23605
|
+
var view = Array.from(views).find(function(candidate) { try { return candidate.getWebContentsId() === contentsId; } catch (_) { return false; } });
|
|
23606
|
+
if (!view || !view.parentElement) return false;
|
|
23607
|
+
var frame = view.parentElement;
|
|
23608
|
+
view._newmarkViewport = viewport;
|
|
23609
|
+
frame.style.position = 'relative';
|
|
23610
|
+
frame.style.overflow = 'hidden';
|
|
23611
|
+
view.style.position = 'absolute';
|
|
23612
|
+
view.style.left = '0'; view.style.top = '0'; view.style.flex = 'none';
|
|
23613
|
+
var fit = function() {
|
|
23614
|
+
if (!view.isConnected) { view._newmarkViewportObserver?.disconnect(); return; }
|
|
23615
|
+
var size = view._newmarkViewport;
|
|
23616
|
+
view.style.width = size.width + 'px'; view.style.height = size.height + 'px';
|
|
23617
|
+
view.style.transformOrigin = 'top left';
|
|
23618
|
+
var scale = Math.min(1, (frame.clientWidth || size.width) / size.width, (frame.clientHeight || size.height) / size.height);
|
|
23619
|
+
view.style.transform = 'scale(' + scale + ')';
|
|
23620
|
+
};
|
|
23621
|
+
if (!view._newmarkViewportObserver) { view._newmarkViewportObserver = new ResizeObserver(fit); view._newmarkViewportObserver.observe(frame); }
|
|
23622
|
+
fit();
|
|
23623
|
+
return true;
|
|
23624
|
+
};
|
|
23625
|
+
|
|
23498
23626
|
function restoreBrowserPlaceholder() {
|
|
23499
23627
|
var frame = els['browser-frame'] || document.getElementById('browser-frame');
|
|
23500
23628
|
if (!frame || document.getElementById('browser-guest-placeholder')) return;
|
|
@@ -23551,12 +23679,28 @@ function navigateBrowserView(view, url) {
|
|
|
23551
23679
|
}
|
|
23552
23680
|
}
|
|
23553
23681
|
|
|
23682
|
+
window.normalizeBrowserAddress = function(raw) {
|
|
23683
|
+
var value = String(raw || '').trim().replace(/^files:\/\//i, 'file://');
|
|
23684
|
+
if (!value || /[\x00-\x1f]/.test(value)) throw new Error('Invalid browser address');
|
|
23685
|
+
if (/^[a-z]:[\\/]/i.test(value) || value.startsWith('/')) {
|
|
23686
|
+
var localPath = value.replace(/\\/g, '/');
|
|
23687
|
+
value = 'file://' + (localPath.startsWith('/') ? '' : '/') + localPath.split('/').map(function(part, index) {
|
|
23688
|
+
return index === 0 && /^[a-z]:$/i.test(part) ? part : encodeURIComponent(part);
|
|
23689
|
+
}).join('/');
|
|
23690
|
+
}
|
|
23691
|
+
if (!/^[a-z][a-z0-9+.-]*:/i.test(value) || /^[^/:]+:\d+(?:\/|$)/.test(value)) value = 'https://' + value;
|
|
23692
|
+
var parsed = new URL(value);
|
|
23693
|
+
if (parsed.protocol === 'file:') {
|
|
23694
|
+
if (parsed.hostname && parsed.hostname !== 'localhost') throw new Error('Use a local file path');
|
|
23695
|
+
} else if (!['http:', 'https:', 'newmark-preview:'].includes(parsed.protocol) && value !== 'about:blank') {
|
|
23696
|
+
throw new Error('Unsupported browser address');
|
|
23697
|
+
}
|
|
23698
|
+
return parsed.href;
|
|
23699
|
+
};
|
|
23700
|
+
|
|
23554
23701
|
window.navigateBrowser = function(url) {
|
|
23555
23702
|
var target = currentConversationTarget();
|
|
23556
|
-
url =
|
|
23557
|
-
if (!/^(?:https?:\/\/|about:blank$|newmark-preview:\/\/)/i.test(url)) {
|
|
23558
|
-
url = 'https://' + url;
|
|
23559
|
-
}
|
|
23703
|
+
url = window.normalizeBrowserAddress(url);
|
|
23560
23704
|
if (state.browserPreviewToken && url !== state.browserPreviewUrl) window.revokeBrowserPreviewCapability();
|
|
23561
23705
|
rememberBrowserUrl(url, true, target);
|
|
23562
23706
|
var input = els['browser-url'];
|
|
@@ -23590,6 +23734,19 @@ window.browserReload = function() {
|
|
|
23590
23734
|
if (view && view.reload) view.reload();
|
|
23591
23735
|
};
|
|
23592
23736
|
|
|
23737
|
+
// The local empty browser canvas belongs to the app theme. Visited pages
|
|
23738
|
+
// retain their own styling; recheck the URL inside the guest after navigation.
|
|
23739
|
+
function syncBlankBrowserGuestTheme(view) {
|
|
23740
|
+
try {
|
|
23741
|
+
if (!view._newmarkDomReady || view.getURL() !== 'about:blank') return;
|
|
23742
|
+
var palette = getComputedStyle(document.documentElement);
|
|
23743
|
+
var bg = palette.getPropertyValue('--bg').trim();
|
|
23744
|
+
var fg = palette.getPropertyValue('--text').trim();
|
|
23745
|
+
var script = 'if(location.href === "about:blank"){document.documentElement.style.background=' + JSON.stringify(bg) + ';document.documentElement.style.color=' + JSON.stringify(fg) + ';}';
|
|
23746
|
+
view.executeJavaScript(script).catch(function() {});
|
|
23747
|
+
} catch {}
|
|
23748
|
+
}
|
|
23749
|
+
|
|
23593
23750
|
function initializeBrowserGuest(view) {
|
|
23594
23751
|
var target = arguments.length > 1 && arguments[1] ? arguments[1] : currentConversationTarget();
|
|
23595
23752
|
var targetKey = browserTargetKey(target);
|
|
@@ -23608,6 +23765,7 @@ function initializeBrowserGuest(view) {
|
|
|
23608
23765
|
currentUrl = view.getURL ? view.getURL() : '';
|
|
23609
23766
|
if (input && currentUrl && currentUrl !== 'about:blank') input.value = currentUrl;
|
|
23610
23767
|
} catch {}
|
|
23768
|
+
syncBlankBrowserGuestTheme(view);
|
|
23611
23769
|
rememberBrowserUrl(currentUrl, false, target);
|
|
23612
23770
|
if (view._newmarkReadySettled) return;
|
|
23613
23771
|
var registration = Promise.resolve({ accepted: true });
|
|
@@ -23676,7 +23834,7 @@ function initializeBrowserGuest(view) {
|
|
|
23676
23834
|
// reload control, so a popup page could not be refreshed in-place.
|
|
23677
23835
|
view.addEventListener('new-window', function(e) {
|
|
23678
23836
|
var popupUrl = String(e && e.url || '').trim();
|
|
23679
|
-
if (!popupUrl || !/^(?:https?:|about:blank|newmark-preview:)/i.test(popupUrl)) return;
|
|
23837
|
+
if (!popupUrl || !/^(?:https?:|file:|about:blank|newmark-preview:)/i.test(popupUrl)) return;
|
|
23680
23838
|
if (e && typeof e.preventDefault === 'function') e.preventDefault();
|
|
23681
23839
|
rememberBrowserUrl(popupUrl, true, target);
|
|
23682
23840
|
var input = els['browser-url'];
|
|
@@ -23863,6 +24021,7 @@ function syncBackendConversation() {
|
|
|
23863
24021
|
}
|
|
23864
24022
|
if (conv && api.ensureConversation) {
|
|
23865
24023
|
var requestedTarget = currentConversationTarget(conv.id);
|
|
24024
|
+
var modelRevisionAtActivation = Number(state.modelSelectionRevision || 0);
|
|
23866
24025
|
state.activeBackendConversationId = conv.id;
|
|
23867
24026
|
var historyPromise = loadActiveConversationMessages(conv.id);
|
|
23868
24027
|
requestedLoadGeneration = state.conversationLoadGeneration;
|
|
@@ -23871,7 +24030,7 @@ function syncBackendConversation() {
|
|
|
23871
24030
|
var id = (s && s.conversationId) || conv.id;
|
|
23872
24031
|
if (!requestIsCurrent() || String(id) !== requestedConversationId) return;
|
|
23873
24032
|
state.activeBackendConversationId = id;
|
|
23874
|
-
applyConversationSnapshot(s, id, { preserveReadableHistory: true });
|
|
24033
|
+
applyConversationSnapshot(s, id, { preserveReadableHistory: true, modelRevision: modelRevisionAtActivation });
|
|
23875
24034
|
}).catch(function(error) {
|
|
23876
24035
|
if (!requestIsCurrent()) return;
|
|
23877
24036
|
showUiNotice(
|
|
@@ -24403,12 +24562,13 @@ window.newConversation = function(workspaceReference, branchCommunication) {
|
|
|
24403
24562
|
renderConversations();
|
|
24404
24563
|
els['chat-area'].innerHTML = '';
|
|
24405
24564
|
var target = currentConversationTarget(id);
|
|
24565
|
+
var modelRevisionAtActivation = Number(state.modelSelectionRevision || 0);
|
|
24406
24566
|
var activation = api.activateConversation ? api.activateConversation(target) : (api.ensureConversation ? api.ensureConversation(target) : Promise.resolve(null));
|
|
24407
24567
|
var activationKey = runtimeKeyFor(target.workspaceId, target.conversationId);
|
|
24408
24568
|
var activationReady = activation.then(function(s) {
|
|
24409
24569
|
if (createdWorkspaceKey !== currentWorkspaceKey() || id !== String(activeConversationId() || 'default')) return;
|
|
24410
24570
|
state.activeBackendConversationId = String((s && s.conversationId) || id);
|
|
24411
|
-
if (s) applyConversationSnapshot(s, id, { preserveReadableHistory: true });
|
|
24571
|
+
if (s) applyConversationSnapshot(s, id, { preserveReadableHistory: true, modelRevision: modelRevisionAtActivation });
|
|
24412
24572
|
if (branchCommunication && api.setConversationBranchCommunication) {
|
|
24413
24573
|
api.setConversationBranchCommunication(target, true).then(function() {
|
|
24414
24574
|
var convsNow = currentWorkspaceConversations();
|
|
@@ -24805,7 +24965,7 @@ window.loadMemoryLabVisualization = function(reason, options) {
|
|
|
24805
24965
|
return result;
|
|
24806
24966
|
}).catch(function(err) {
|
|
24807
24967
|
var target = document.getElementById('memory-lab-panel');
|
|
24808
|
-
if (target) target.innerHTML = '<div style="color
|
|
24968
|
+
if (target) target.innerHTML = '<div style="color:var(--nm-state-danger);font-size:12px;">' + esc(err.message || String(err)) + '</div>';
|
|
24809
24969
|
throw err;
|
|
24810
24970
|
}).finally(function() {
|
|
24811
24971
|
if (generation === state.memoryLabVisualizationGeneration) state.memoryLabVisualizationLoading = false;
|
|
@@ -26961,7 +27121,7 @@ window.openWsSettings = function() {
|
|
|
26961
27121
|
'</select></div>' +
|
|
26962
27122
|
'<div style="display:flex;gap:6px;margin-top:8px;">' +
|
|
26963
27123
|
'<button class="sec-btn" style="flex:1;" onclick="window.showNewWorkspaceDialog()">+ ' + esc(t('left.new')) + '</button>' +
|
|
26964
|
-
'<button class="sec-btn" style="flex:1;color
|
|
27124
|
+
'<button class="sec-btn" style="flex:1;color:var(--nm-state-danger);" onclick="window.deleteCurrentWorkspace()">' + esc(t('common.delete')) + '</button>' +
|
|
26965
27125
|
'</div>';
|
|
26966
27126
|
window.openSubWin(t('workspace.settingsTitle') + ' - ' + esc(wsName), html);
|
|
26967
27127
|
|
|
@@ -28205,6 +28365,7 @@ function schedulePostStartupUiRendering() {
|
|
|
28205
28365
|
var selectedContextGeneration = state.conversationLoadGeneration;
|
|
28206
28366
|
var selectedContextModel = this.value;
|
|
28207
28367
|
state.model = selectedContextModel;
|
|
28368
|
+
state.modelSelectionRevision = Number(state.modelSelectionRevision || 0) + 1;
|
|
28208
28369
|
window.syncModelSelectSurface();
|
|
28209
28370
|
if (state.model !== state._syncedModel) {
|
|
28210
28371
|
var modelResult = await api.setModel(selectedContextModel);
|
|
@@ -28313,4 +28474,3 @@ function schedulePostStartupUiRendering() {
|
|
|
28313
28474
|
</body>
|
|
28314
28475
|
</html>
|
|
28315
28476
|
|
|
28316
|
-
|