@auto-ai/agent 2.1.90 → 2.1.92
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/404/index.html +1 -1
- package/dist/404.html +1 -1
- package/dist/_next/static/{v7b7kpIIWrJ_TrI3XvYpK → IV9dkeTt0V-ZE8jl01i6B}/_buildManifest.js +1 -1
- package/dist/_next/static/IV9dkeTt0V-ZE8jl01i6B/_ssgManifest.js +1 -0
- package/dist/_next/static/chunks/091dc4a67d911a93.js +1 -0
- package/dist/_next/static/chunks/0b5fd45c6d5ed376.js +1 -0
- package/dist/_next/static/chunks/0c059f531456fce2.js +1 -0
- package/dist/_next/static/chunks/15734e910215c5c7.js +1 -0
- package/dist/_next/static/chunks/1f4af280db551c9d.js +1 -0
- package/dist/_next/static/chunks/2b6b9fdaaa345603.js +1 -0
- package/dist/_next/static/chunks/34b34d02b7d6b4cb.js +1 -0
- package/dist/_next/static/chunks/3740042834e8f1fa.js +1 -0
- package/dist/_next/static/chunks/3a17a1f5303a1c2c.js +1 -0
- package/dist/_next/static/chunks/40268f8e3ff0314e.js +1 -0
- package/dist/_next/static/chunks/4247f46093e522c6.js +1 -0
- package/dist/_next/static/chunks/4456351ffa1be45f.js +1 -0
- package/dist/_next/static/chunks/{2fa3e4168e941aef.js → 52e2164e45febae6.js} +1 -1
- package/dist/_next/static/chunks/620e3011cd69dfc9.js +1 -0
- package/dist/_next/static/chunks/67c7406790a840c1.js +1 -0
- package/dist/_next/static/chunks/6831f547a9403a0f.js +1 -0
- package/dist/_next/static/chunks/763710bf823861a8.js +1 -0
- package/dist/_next/static/chunks/76a71d344cc15a9f.js +1 -0
- package/dist/_next/static/chunks/7988d5ea63356e10.js +1 -0
- package/dist/_next/static/chunks/8c0da143ceae2767.js +1 -0
- package/dist/_next/static/chunks/8d0a29ce5f05a73d.js +1 -0
- package/dist/_next/static/chunks/{e99db8276524ccf5.js → 8dc694eabda7878d.js} +1 -1
- package/dist/_next/static/chunks/91adb7bdb9870c6a.js +1 -0
- package/dist/_next/static/chunks/ad4ba491cf12423f.js +5 -0
- package/dist/_next/static/chunks/c889d3f6eb8ab09e.css +1 -0
- package/dist/_next/static/chunks/ce0cac88dd992956.css +4 -0
- package/dist/_next/static/chunks/d9726d84bd7d40ff.js +1 -0
- package/dist/_next/static/chunks/e4675b3a8b7605e4.js +1 -0
- package/dist/_next/static/chunks/ebcd85ff4a1db0dc.js +5 -0
- package/dist/_next/static/chunks/{turbopack-8a0e770cd106af0c.js → turbopack-030a42d60560a927.js} +1 -1
- package/dist/_next/static/chunks/{turbopack-cd5b40c9e0ee1fe0.js → turbopack-3d84668fefd38b4b.js} +1 -1
- package/dist/_next/static/chunks/{turbopack-25a49bf58581b314.js → turbopack-8b41433c9a94981f.js} +1 -1
- package/dist/agent-office/accents.js +28 -0
- package/dist/agent-office/api.js +142 -0
- package/dist/agent-office/list.js +79 -0
- package/dist/agent-office/main.js +38 -0
- package/dist/agent-office/officeController.js +13 -0
- package/dist/agent-office/ui.js +264 -0
- package/dist/agent-office.html +307 -0
- package/dist/index.html +1 -1
- package/dist/index.txt +29 -19
- package/dist/manage/about/index.html +2 -0
- package/dist/manage/about/index.txt +37 -0
- package/dist/manage/add-account/basic/index.html +2 -0
- package/dist/manage/add-account/basic/index.txt +39 -0
- package/dist/manage/add-account/index.html +2 -1
- package/dist/manage/add-account/index.txt +34 -27
- package/dist/manage/add-account/prompt/index.html +2 -0
- package/dist/manage/add-account/prompt/index.txt +40 -0
- package/dist/manage/agent-teams/index.html +2 -2
- package/dist/manage/agent-teams/index.txt +34 -26
- package/dist/manage/env/index.html +2 -2
- package/dist/manage/env/index.txt +34 -26
- package/dist/manage/general/index.html +2 -0
- package/dist/manage/general/index.txt +37 -0
- package/dist/manage/index.html +1 -0
- package/dist/manage/index.txt +33 -0
- package/dist/manage/mcp/index.html +2 -2
- package/dist/manage/mcp/index.txt +34 -26
- package/dist/manage/permissions/index.html +2 -0
- package/dist/manage/permissions/index.txt +37 -0
- package/dist/manage/skills/index.html +2 -2
- package/dist/manage/skills/index.txt +34 -26
- package/dist/manage/task/index.html +1 -0
- package/dist/manage/task/index.txt +38 -0
- package/dist/manage/teams/index.html +1 -0
- package/dist/manage/teams/index.txt +37 -0
- package/dist/manage/tools/index.html +2 -2
- package/dist/manage/tools/index.txt +34 -26
- package/dist/ws-test.html +1151 -30
- package/package.json +6 -6
- package/dist/_next/static/chunks/01037955b0804f69.js +0 -1
- package/dist/_next/static/chunks/071c2b2eece424b8.js +0 -1
- package/dist/_next/static/chunks/19d949d5c8e7fc66.js +0 -1
- package/dist/_next/static/chunks/39dac725d46ff2cf.js +0 -5
- package/dist/_next/static/chunks/3a00f465f3afdd13.js +0 -1
- package/dist/_next/static/chunks/43c3e97de0c89c14.js +0 -1
- package/dist/_next/static/chunks/479bb32e1848b26b.js +0 -1
- package/dist/_next/static/chunks/573efa1cd3d0872c.js +0 -1
- package/dist/_next/static/chunks/6a8dfef8eb153262.js +0 -1
- package/dist/_next/static/chunks/6ea69f45a19b4f00.js +0 -1
- package/dist/_next/static/chunks/75622a4fe3b7b015.js +0 -1
- package/dist/_next/static/chunks/80a811d77e9d2ba6.js +0 -1
- package/dist/_next/static/chunks/8508beba62ed11df.js +0 -1
- package/dist/_next/static/chunks/8915ded29d610342.js +0 -1
- package/dist/_next/static/chunks/93e645e175860ad2.js +0 -1
- package/dist/_next/static/chunks/9597a4f1aa937100.js +0 -1
- package/dist/_next/static/chunks/9923762f97969b52.css +0 -4
- package/dist/_next/static/chunks/9c9c063cb0b2e562.js +0 -1
- package/dist/_next/static/chunks/a32559d6604a11fb.js +0 -5
- package/dist/_next/static/chunks/a6c743f3d7975ca2.css +0 -1
- package/dist/_next/static/chunks/ab6655809333a412.js +0 -1
- package/dist/_next/static/chunks/acb68dccafc14ac1.js +0 -1
- package/dist/_next/static/chunks/b1e8db918a2dcc7c.js +0 -1
- package/dist/_next/static/chunks/ca3c520aa0575c69.js +0 -1
- package/dist/_next/static/chunks/cdd193032944dfed.js +0 -1
- package/dist/_next/static/chunks/d9cb9883957b864c.js +0 -1
- package/dist/_next/static/v7b7kpIIWrJ_TrI3XvYpK/_ssgManifest.js +0 -1
- package/dist/manage/agent/index.html +0 -2
- package/dist/manage/agent/index.txt +0 -32
- /package/dist/_next/static/{v7b7kpIIWrJ_TrI3XvYpK → IV9dkeTt0V-ZE8jl01i6B}/_clientMiddlewareManifest.json +0 -0
package/dist/ws-test.html
CHANGED
|
@@ -72,6 +72,10 @@
|
|
|
72
72
|
justify-content: center;
|
|
73
73
|
min-width: 0;
|
|
74
74
|
}
|
|
75
|
+
.agent-switch-wrap {
|
|
76
|
+
position: relative;
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
}
|
|
75
79
|
.sidebar-avatar {
|
|
76
80
|
width: 40px;
|
|
77
81
|
height: 40px;
|
|
@@ -87,7 +91,140 @@
|
|
|
87
91
|
line-height: 1;
|
|
88
92
|
box-shadow: var(--ds-shadow);
|
|
89
93
|
user-select: none;
|
|
90
|
-
cursor:
|
|
94
|
+
cursor: pointer;
|
|
95
|
+
padding: 0;
|
|
96
|
+
font-family: inherit;
|
|
97
|
+
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
98
|
+
}
|
|
99
|
+
.sidebar-avatar:hover,
|
|
100
|
+
.agent-switch-wrap.open .sidebar-avatar {
|
|
101
|
+
border-color: var(--ds-accent);
|
|
102
|
+
box-shadow: 0 0 0 3px rgba(10, 132, 255, 0.14);
|
|
103
|
+
}
|
|
104
|
+
/* 浮层挂 body,fixed 定位,避免侧栏 overflow:hidden 裁剪 */
|
|
105
|
+
.agent-switch-dropdown {
|
|
106
|
+
display: none;
|
|
107
|
+
position: fixed;
|
|
108
|
+
z-index: 10050;
|
|
109
|
+
min-width: 168px;
|
|
110
|
+
width: max-content;
|
|
111
|
+
max-width: min(260px, calc(100vw - 24px));
|
|
112
|
+
max-height: min(360px, calc(100vh - 24px));
|
|
113
|
+
overflow: hidden;
|
|
114
|
+
background: var(--ds-bg);
|
|
115
|
+
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
116
|
+
border-radius: 14px;
|
|
117
|
+
box-shadow:
|
|
118
|
+
0 4px 6px rgba(15, 23, 42, 0.05),
|
|
119
|
+
0 16px 40px rgba(15, 23, 42, 0.14);
|
|
120
|
+
flex-direction: column;
|
|
121
|
+
}
|
|
122
|
+
.agent-switch-dropdown.is-open {
|
|
123
|
+
display: flex;
|
|
124
|
+
}
|
|
125
|
+
.agent-switch-dropdown-head {
|
|
126
|
+
flex-shrink: 0;
|
|
127
|
+
padding: 10px 12px 8px;
|
|
128
|
+
font-size: 12px;
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
color: var(--ds-muted);
|
|
131
|
+
letter-spacing: 0.02em;
|
|
132
|
+
border-bottom: 1px solid var(--ds-border);
|
|
133
|
+
background: #fafafa;
|
|
134
|
+
border-radius: 14px 14px 0 0;
|
|
135
|
+
}
|
|
136
|
+
.agent-switch-dropdown-list {
|
|
137
|
+
overflow-y: auto;
|
|
138
|
+
padding: 6px;
|
|
139
|
+
min-height: 0;
|
|
140
|
+
}
|
|
141
|
+
.agent-switch-item {
|
|
142
|
+
display: flex;
|
|
143
|
+
align-items: center;
|
|
144
|
+
justify-content: space-between;
|
|
145
|
+
gap: 10px;
|
|
146
|
+
width: 100%;
|
|
147
|
+
text-align: left;
|
|
148
|
+
padding: 8px 10px;
|
|
149
|
+
border: none;
|
|
150
|
+
border-radius: 10px;
|
|
151
|
+
background: transparent;
|
|
152
|
+
color: var(--ds-text);
|
|
153
|
+
font-size: 13px;
|
|
154
|
+
cursor: pointer;
|
|
155
|
+
}
|
|
156
|
+
.agent-switch-item:hover {
|
|
157
|
+
background: var(--ds-item-hover);
|
|
158
|
+
}
|
|
159
|
+
.agent-switch-item.is-current {
|
|
160
|
+
background: var(--ds-item-active);
|
|
161
|
+
color: var(--ds-accent);
|
|
162
|
+
}
|
|
163
|
+
.agent-switch-item-main {
|
|
164
|
+
min-width: 0;
|
|
165
|
+
display: flex;
|
|
166
|
+
flex-direction: column;
|
|
167
|
+
gap: 1px;
|
|
168
|
+
}
|
|
169
|
+
.agent-switch-item-name {
|
|
170
|
+
font-weight: 600;
|
|
171
|
+
line-height: 1.25;
|
|
172
|
+
overflow: hidden;
|
|
173
|
+
text-overflow: ellipsis;
|
|
174
|
+
white-space: nowrap;
|
|
175
|
+
}
|
|
176
|
+
.agent-switch-item-id {
|
|
177
|
+
font-size: 11px;
|
|
178
|
+
color: var(--ds-muted);
|
|
179
|
+
line-height: 1.2;
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
text-overflow: ellipsis;
|
|
182
|
+
white-space: nowrap;
|
|
183
|
+
}
|
|
184
|
+
.agent-switch-item.is-current .agent-switch-item-id {
|
|
185
|
+
color: var(--ds-accent);
|
|
186
|
+
opacity: 0.85;
|
|
187
|
+
}
|
|
188
|
+
.agent-switch-item-check {
|
|
189
|
+
flex-shrink: 0;
|
|
190
|
+
width: 16px;
|
|
191
|
+
height: 16px;
|
|
192
|
+
color: var(--ds-accent);
|
|
193
|
+
opacity: 0;
|
|
194
|
+
}
|
|
195
|
+
.agent-switch-item.is-current .agent-switch-item-check {
|
|
196
|
+
opacity: 1;
|
|
197
|
+
}
|
|
198
|
+
.agent-switch-loading,
|
|
199
|
+
.agent-switch-empty {
|
|
200
|
+
padding: 14px 12px;
|
|
201
|
+
font-size: 13px;
|
|
202
|
+
color: var(--ds-muted);
|
|
203
|
+
}
|
|
204
|
+
.agent-switch-dropdown-foot {
|
|
205
|
+
flex-shrink: 0;
|
|
206
|
+
border-top: 1px solid var(--ds-border);
|
|
207
|
+
padding: 6px;
|
|
208
|
+
background: #fafafa;
|
|
209
|
+
border-radius: 0 0 14px 14px;
|
|
210
|
+
}
|
|
211
|
+
.agent-switch-manage-btn {
|
|
212
|
+
display: flex;
|
|
213
|
+
width: 100%;
|
|
214
|
+
align-items: center;
|
|
215
|
+
justify-content: center;
|
|
216
|
+
gap: 6px;
|
|
217
|
+
border: none;
|
|
218
|
+
border-radius: 10px;
|
|
219
|
+
background: transparent;
|
|
220
|
+
color: var(--ds-accent);
|
|
221
|
+
font-size: 13px;
|
|
222
|
+
font-weight: 600;
|
|
223
|
+
padding: 8px 10px;
|
|
224
|
+
cursor: pointer;
|
|
225
|
+
}
|
|
226
|
+
.agent-switch-manage-btn:hover {
|
|
227
|
+
background: var(--ds-item-hover);
|
|
91
228
|
}
|
|
92
229
|
.sidebar-brand-ws {
|
|
93
230
|
margin-top: 0.45rem;
|
|
@@ -413,12 +550,17 @@
|
|
|
413
550
|
.sidebar-icon-rail {
|
|
414
551
|
align-items: center;
|
|
415
552
|
gap: 8px;
|
|
416
|
-
padding: 10px 0
|
|
417
|
-
overflow: hidden;
|
|
553
|
+
padding: 10px 0 12px;
|
|
554
|
+
overflow-x: hidden;
|
|
555
|
+
overflow-y: auto;
|
|
556
|
+
flex: 1;
|
|
557
|
+
min-height: 0;
|
|
558
|
+
scrollbar-width: thin;
|
|
418
559
|
}
|
|
419
560
|
.sidebar-nav-item {
|
|
420
561
|
width: 34px;
|
|
421
562
|
height: 34px;
|
|
563
|
+
flex-shrink: 0;
|
|
422
564
|
border: none;
|
|
423
565
|
border-radius: 10px;
|
|
424
566
|
display: inline-flex;
|
|
@@ -442,6 +584,103 @@
|
|
|
442
584
|
height: 18px;
|
|
443
585
|
display: block;
|
|
444
586
|
}
|
|
587
|
+
.schedule-manage-table-wrap {
|
|
588
|
+
overflow: auto;
|
|
589
|
+
max-height: min(52vh, 420px);
|
|
590
|
+
border: 1px solid var(--ds-border);
|
|
591
|
+
border-radius: var(--ds-radius-sm);
|
|
592
|
+
background: #fff;
|
|
593
|
+
}
|
|
594
|
+
.schedule-manage-table {
|
|
595
|
+
width: 100%;
|
|
596
|
+
border-collapse: collapse;
|
|
597
|
+
font-size: 0.78rem;
|
|
598
|
+
}
|
|
599
|
+
.schedule-manage-table th,
|
|
600
|
+
.schedule-manage-table td {
|
|
601
|
+
padding: 0.45rem 0.55rem;
|
|
602
|
+
border-bottom: 1px solid var(--ds-border);
|
|
603
|
+
text-align: left;
|
|
604
|
+
vertical-align: top;
|
|
605
|
+
}
|
|
606
|
+
.schedule-manage-table th {
|
|
607
|
+
position: sticky;
|
|
608
|
+
top: 0;
|
|
609
|
+
background: #f8fafc;
|
|
610
|
+
color: var(--ds-text-soft);
|
|
611
|
+
font-weight: 600;
|
|
612
|
+
z-index: 1;
|
|
613
|
+
}
|
|
614
|
+
.schedule-manage-table tr:last-child td {
|
|
615
|
+
border-bottom: none;
|
|
616
|
+
}
|
|
617
|
+
.schedule-manage-prompt {
|
|
618
|
+
max-width: 220px;
|
|
619
|
+
word-break: break-word;
|
|
620
|
+
white-space: pre-wrap;
|
|
621
|
+
}
|
|
622
|
+
.schedule-manage-session-link {
|
|
623
|
+
color: var(--ds-accent);
|
|
624
|
+
cursor: pointer;
|
|
625
|
+
text-decoration: underline;
|
|
626
|
+
background: none;
|
|
627
|
+
border: none;
|
|
628
|
+
padding: 0;
|
|
629
|
+
font: inherit;
|
|
630
|
+
}
|
|
631
|
+
.schedule-create-form {
|
|
632
|
+
display: grid;
|
|
633
|
+
gap: 0.55rem;
|
|
634
|
+
margin-top: 0.75rem;
|
|
635
|
+
padding: 0.75rem;
|
|
636
|
+
border: 1px dashed var(--ds-border);
|
|
637
|
+
border-radius: var(--ds-radius-sm);
|
|
638
|
+
background: #fafbfc;
|
|
639
|
+
}
|
|
640
|
+
.schedule-create-form[hidden] {
|
|
641
|
+
display: none !important;
|
|
642
|
+
}
|
|
643
|
+
.schedule-create-row {
|
|
644
|
+
display: grid;
|
|
645
|
+
gap: 0.25rem;
|
|
646
|
+
}
|
|
647
|
+
.schedule-create-row label {
|
|
648
|
+
font-size: 0.75rem;
|
|
649
|
+
color: var(--ds-text-soft);
|
|
650
|
+
}
|
|
651
|
+
.schedule-create-row input,
|
|
652
|
+
.schedule-create-row select,
|
|
653
|
+
.schedule-create-row textarea {
|
|
654
|
+
width: 100%;
|
|
655
|
+
box-sizing: border-box;
|
|
656
|
+
border: 1px solid var(--ds-border);
|
|
657
|
+
border-radius: 6px;
|
|
658
|
+
padding: 0.4rem 0.5rem;
|
|
659
|
+
font: inherit;
|
|
660
|
+
background: #fff;
|
|
661
|
+
}
|
|
662
|
+
.schedule-create-row textarea {
|
|
663
|
+
min-height: 72px;
|
|
664
|
+
resize: vertical;
|
|
665
|
+
}
|
|
666
|
+
.schedule-create-actions {
|
|
667
|
+
display: flex;
|
|
668
|
+
gap: 0.5rem;
|
|
669
|
+
justify-content: flex-end;
|
|
670
|
+
margin-top: 0.25rem;
|
|
671
|
+
}
|
|
672
|
+
.schedule-manage-toolbar {
|
|
673
|
+
display: flex;
|
|
674
|
+
gap: 0.5rem;
|
|
675
|
+
align-items: center;
|
|
676
|
+
margin-bottom: 0.65rem;
|
|
677
|
+
}
|
|
678
|
+
.schedule-manage-empty {
|
|
679
|
+
padding: 1rem;
|
|
680
|
+
text-align: center;
|
|
681
|
+
color: var(--ds-text-soft);
|
|
682
|
+
font-size: 0.82rem;
|
|
683
|
+
}
|
|
445
684
|
/* 侧栏图标悬浮说明(fixed,避免被 sidebar overflow 裁切) */
|
|
446
685
|
.sidebar-hover-tip {
|
|
447
686
|
position: fixed;
|
|
@@ -1815,11 +2054,16 @@
|
|
|
1815
2054
|
}
|
|
1816
2055
|
.sidebar-icon-rail {
|
|
1817
2056
|
gap: 7px;
|
|
1818
|
-
padding: var(--layout-card-gap) 0;
|
|
2057
|
+
padding: var(--layout-card-gap) 0 12px;
|
|
2058
|
+
overflow-x: hidden;
|
|
2059
|
+
overflow-y: auto;
|
|
2060
|
+
flex: 1;
|
|
2061
|
+
min-height: 0;
|
|
1819
2062
|
}
|
|
1820
2063
|
.sidebar-nav-item {
|
|
1821
2064
|
width: 32px;
|
|
1822
2065
|
height: 32px;
|
|
2066
|
+
flex-shrink: 0;
|
|
1823
2067
|
border-radius: 10px;
|
|
1824
2068
|
}
|
|
1825
2069
|
.sidebar-brand-ws {
|
|
@@ -2241,16 +2485,34 @@
|
|
|
2241
2485
|
<aside class="sidebar">
|
|
2242
2486
|
<div class="sidebar-brand">
|
|
2243
2487
|
<div class="sidebar-brand-title-row">
|
|
2244
|
-
<div
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2488
|
+
<div class="agent-switch-wrap" id="agentSwitchWrap">
|
|
2489
|
+
<button
|
|
2490
|
+
type="button"
|
|
2491
|
+
class="sidebar-avatar"
|
|
2492
|
+
id="brandAgentName"
|
|
2493
|
+
title="agent: qihoo"
|
|
2494
|
+
aria-label="agent: qihoo"
|
|
2495
|
+
aria-haspopup="listbox"
|
|
2496
|
+
aria-expanded="false"
|
|
2497
|
+
>Q</button>
|
|
2498
|
+
</div>
|
|
2250
2499
|
</div>
|
|
2251
2500
|
</div>
|
|
2252
2501
|
|
|
2253
2502
|
<div class="sidebar-drawers sidebar-icon-rail" aria-label="左侧管理导航">
|
|
2503
|
+
<button
|
|
2504
|
+
type="button"
|
|
2505
|
+
class="sidebar-nav-item"
|
|
2506
|
+
id="btnManageAgents"
|
|
2507
|
+
title="返回办公室"
|
|
2508
|
+
aria-label="返回办公室"
|
|
2509
|
+
>
|
|
2510
|
+
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
2511
|
+
<rect x="4" y="4" width="16" height="16" rx="4"/>
|
|
2512
|
+
<circle cx="12" cy="10" r="2.6"/>
|
|
2513
|
+
<path d="M7.5 17.5c.8-2.2 2.4-3.5 4.5-3.5s3.7 1.3 4.5 3.5"/>
|
|
2514
|
+
</svg>
|
|
2515
|
+
</button>
|
|
2254
2516
|
<button
|
|
2255
2517
|
type="button"
|
|
2256
2518
|
class="sidebar-nav-item"
|
|
@@ -2300,6 +2562,19 @@
|
|
|
2300
2562
|
<path d="M11 7h2M12 10v4"/>
|
|
2301
2563
|
</svg>
|
|
2302
2564
|
</button>
|
|
2565
|
+
<button
|
|
2566
|
+
type="button"
|
|
2567
|
+
class="sidebar-nav-item"
|
|
2568
|
+
id="btnManageSchedules"
|
|
2569
|
+
data-add="schedules"
|
|
2570
|
+
title="定时任务"
|
|
2571
|
+
aria-label="定时任务"
|
|
2572
|
+
>
|
|
2573
|
+
<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" aria-hidden="true">
|
|
2574
|
+
<circle cx="12" cy="12" r="10"/>
|
|
2575
|
+
<polyline points="12 6 12 12 16 14"/>
|
|
2576
|
+
</svg>
|
|
2577
|
+
</button>
|
|
2303
2578
|
<button
|
|
2304
2579
|
type="button"
|
|
2305
2580
|
class="sidebar-nav-item"
|
|
@@ -2493,6 +2768,23 @@
|
|
|
2493
2768
|
</div>
|
|
2494
2769
|
</div>
|
|
2495
2770
|
|
|
2771
|
+
<div id="skillMdModal" class="agent-md-modal" aria-hidden="true">
|
|
2772
|
+
<div class="agent-md-modal-backdrop" id="skillMdModalBackdrop"></div>
|
|
2773
|
+
<div class="agent-md-modal-card" role="dialog" aria-modal="true" aria-labelledby="skillMdModalTitle">
|
|
2774
|
+
<div class="agent-md-modal-head">
|
|
2775
|
+
<h2 id="skillMdModalTitle">编辑 SKILL.md</h2>
|
|
2776
|
+
<button type="button" class="agent-md-modal-close" id="btnSkillMdModalClose" aria-label="关闭">
|
|
2777
|
+
×
|
|
2778
|
+
</button>
|
|
2779
|
+
</div>
|
|
2780
|
+
<textarea id="skillMdEditor" class="agent-md-editor" spellcheck="false" placeholder="加载中…"></textarea>
|
|
2781
|
+
<div class="agent-md-modal-foot">
|
|
2782
|
+
<button type="button" class="btn-agent-md-cancel" id="btnSkillMdCancel">取消</button>
|
|
2783
|
+
<button type="button" class="btn-primary" id="btnSkillMdSave">保存</button>
|
|
2784
|
+
</div>
|
|
2785
|
+
</div>
|
|
2786
|
+
</div>
|
|
2787
|
+
|
|
2496
2788
|
<div id="toolFilesModal" class="agent-md-modal" aria-hidden="true">
|
|
2497
2789
|
<div class="agent-md-modal-backdrop" id="toolFilesModalBackdrop"></div>
|
|
2498
2790
|
<div class="agent-md-modal-card modal-unified" role="dialog" aria-modal="true" aria-labelledby="toolFilesModalTitle">
|
|
@@ -2757,11 +3049,102 @@
|
|
|
2757
3049
|
</div>
|
|
2758
3050
|
</div>
|
|
2759
3051
|
|
|
3052
|
+
<div id="scheduleManageModal" class="agent-md-modal" aria-hidden="true">
|
|
3053
|
+
<div class="agent-md-modal-backdrop" id="scheduleManageModalBackdrop"></div>
|
|
3054
|
+
<div id="scheduleManageModalCard" class="agent-md-modal-card modal-unified" role="dialog" aria-modal="true" aria-labelledby="scheduleManageModalTitle">
|
|
3055
|
+
<div class="agent-md-modal-head">
|
|
3056
|
+
<h2 id="scheduleManageModalTitle">定时任务</h2>
|
|
3057
|
+
<div class="modal-head-actions modal-head-actions--close-only">
|
|
3058
|
+
<button type="button" class="agent-md-modal-close" id="btnScheduleManageModalClose" aria-label="关闭">
|
|
3059
|
+
×
|
|
3060
|
+
</button>
|
|
3061
|
+
</div>
|
|
3062
|
+
</div>
|
|
3063
|
+
<div class="tool-files-body">
|
|
3064
|
+
<p id="scheduleManageMeta" class="tool-files-meta" style="margin: 0 0 0.5rem"></p>
|
|
3065
|
+
<div class="schedule-manage-toolbar">
|
|
3066
|
+
<button type="button" class="btn-system-settings" id="btnScheduleRefresh">刷新</button>
|
|
3067
|
+
<button type="button" class="btn-system-settings" id="btnScheduleCreateToggle">新建任务</button>
|
|
3068
|
+
<button type="button" class="btn-system-settings" id="btnScheduleGeelibPreset">Geelib 巡检</button>
|
|
3069
|
+
</div>
|
|
3070
|
+
<div id="scheduleCreateForm" class="schedule-create-form" hidden>
|
|
3071
|
+
<div class="schedule-create-row">
|
|
3072
|
+
<label for="scheduleSessionSelect">关联会话</label>
|
|
3073
|
+
<select id="scheduleSessionSelect"></select>
|
|
3074
|
+
</div>
|
|
3075
|
+
<div class="schedule-create-row">
|
|
3076
|
+
<label for="schedulePromptInput">Prompt</label>
|
|
3077
|
+
<textarea id="schedulePromptInput" placeholder="到期后发送给 agent 的提示词"></textarea>
|
|
3078
|
+
</div>
|
|
3079
|
+
<div class="schedule-create-row">
|
|
3080
|
+
<label>触发方式</label>
|
|
3081
|
+
<div style="display:flex;gap:0.75rem;align-items:center;font-size:0.78rem">
|
|
3082
|
+
<label><input type="radio" name="scheduleTriggerMode" value="delay" checked /> 相对分钟</label>
|
|
3083
|
+
<label><input type="radio" name="scheduleTriggerMode" value="cron" /> Cron</label>
|
|
3084
|
+
<label><input type="checkbox" id="scheduleRecurringInput" /> 循环</label>
|
|
3085
|
+
</div>
|
|
3086
|
+
</div>
|
|
3087
|
+
<div class="schedule-create-row" id="scheduleDelayRow">
|
|
3088
|
+
<label for="scheduleDelayMinutesInput">delayMinutes(1~10080)</label>
|
|
3089
|
+
<input id="scheduleDelayMinutesInput" type="number" min="1" max="10080" value="5" />
|
|
3090
|
+
</div>
|
|
3091
|
+
<div class="schedule-create-row" id="scheduleCronRow" hidden>
|
|
3092
|
+
<label for="scheduleCronInput">Cron(5 段,本地时区)</label>
|
|
3093
|
+
<input id="scheduleCronInput" type="text" placeholder="30 9 * * *" />
|
|
3094
|
+
</div>
|
|
3095
|
+
<div class="schedule-create-actions">
|
|
3096
|
+
<button type="button" class="btn-agent-md-cancel" id="btnScheduleCreateCancel">取消</button>
|
|
3097
|
+
<button type="button" class="btn-agent-md-save" id="btnScheduleCreateSubmit">创建</button>
|
|
3098
|
+
</div>
|
|
3099
|
+
</div>
|
|
3100
|
+
<div class="schedule-manage-table-wrap">
|
|
3101
|
+
<table class="schedule-manage-table">
|
|
3102
|
+
<thead>
|
|
3103
|
+
<tr>
|
|
3104
|
+
<th>ID</th>
|
|
3105
|
+
<th>会话</th>
|
|
3106
|
+
<th>Cron</th>
|
|
3107
|
+
<th>下次执行</th>
|
|
3108
|
+
<th>Prompt</th>
|
|
3109
|
+
<th>类型</th>
|
|
3110
|
+
<th>操作</th>
|
|
3111
|
+
</tr>
|
|
3112
|
+
</thead>
|
|
3113
|
+
<tbody id="scheduleTaskTableBody"></tbody>
|
|
3114
|
+
</table>
|
|
3115
|
+
<div id="scheduleManageEmpty" class="schedule-manage-empty" hidden>暂无定时任务</div>
|
|
3116
|
+
</div>
|
|
3117
|
+
</div>
|
|
3118
|
+
</div>
|
|
3119
|
+
</div>
|
|
3120
|
+
|
|
3121
|
+
</div>
|
|
3122
|
+
|
|
2760
3123
|
<div id="sidebarHoverTip" class="sidebar-hover-tip" role="tooltip" hidden></div>
|
|
3124
|
+
<div
|
|
3125
|
+
class="agent-switch-dropdown"
|
|
3126
|
+
id="agentSwitchDropdown"
|
|
3127
|
+
role="listbox"
|
|
3128
|
+
aria-label="切换 agent"
|
|
3129
|
+
hidden
|
|
3130
|
+
></div>
|
|
2761
3131
|
|
|
2762
3132
|
<script src="https://cdn.jsdelivr.net/npm/marked@12.0.2/marked.min.js"></script>
|
|
2763
3133
|
<script>
|
|
2764
3134
|
(function () {
|
|
3135
|
+
/** ws-test 必须有合法 ?agent= 参数,否则回到办公室首页 */
|
|
3136
|
+
;(function wsTestRequireAgentParam() {
|
|
3137
|
+
try {
|
|
3138
|
+
const ag = new URLSearchParams(window.location.search).get('agent')
|
|
3139
|
+
const id = ag ? String(ag).trim() : ''
|
|
3140
|
+
if (!id || !/^[a-zA-Z0-9_-]{1,64}$/.test(id)) {
|
|
3141
|
+
location.replace('/')
|
|
3142
|
+
}
|
|
3143
|
+
} catch {
|
|
3144
|
+
location.replace('/')
|
|
3145
|
+
}
|
|
3146
|
+
})()
|
|
3147
|
+
|
|
2765
3148
|
const $ = (id) => document.getElementById(id)
|
|
2766
3149
|
const logEl = $('log')
|
|
2767
3150
|
const chatThreadEl = $('chatThread')
|
|
@@ -2785,6 +3168,14 @@
|
|
|
2785
3168
|
const btnAgentMdModalClose = $('btnAgentMdModalClose')
|
|
2786
3169
|
const btnAgentMdCancel = $('btnAgentMdCancel')
|
|
2787
3170
|
const btnAgentMdSave = $('btnAgentMdSave')
|
|
3171
|
+
const skillMdModal = $('skillMdModal')
|
|
3172
|
+
const skillMdModalTitle = $('skillMdModalTitle')
|
|
3173
|
+
const skillMdModalBackdrop = $('skillMdModalBackdrop')
|
|
3174
|
+
const skillMdEditor = $('skillMdEditor')
|
|
3175
|
+
const btnSkillMdModalClose = $('btnSkillMdModalClose')
|
|
3176
|
+
const btnSkillMdCancel = $('btnSkillMdCancel')
|
|
3177
|
+
const btnSkillMdSave = $('btnSkillMdSave')
|
|
3178
|
+
let skillMdEditingName = ''
|
|
2788
3179
|
const agentEnvModal = $('agentEnvModal')
|
|
2789
3180
|
const agentEnvModalCard = $('agentEnvModalCard')
|
|
2790
3181
|
const agentEnvModalBackdrop = $('agentEnvModalBackdrop')
|
|
@@ -2838,6 +3229,27 @@
|
|
|
2838
3229
|
const runGroupModalTitle = $('runGroupModalTitle')
|
|
2839
3230
|
const runGroupModalBody = $('runGroupModalBody')
|
|
2840
3231
|
const btnRunGroupModalClose = $('btnRunGroupModalClose')
|
|
3232
|
+
const scheduleManageModal = $('scheduleManageModal')
|
|
3233
|
+
const scheduleManageModalBackdrop = $('scheduleManageModalBackdrop')
|
|
3234
|
+
const scheduleManageMeta = $('scheduleManageMeta')
|
|
3235
|
+
const scheduleTaskTableBody = $('scheduleTaskTableBody')
|
|
3236
|
+
const scheduleManageEmpty = $('scheduleManageEmpty')
|
|
3237
|
+
const btnScheduleManageModalClose = $('btnScheduleManageModalClose')
|
|
3238
|
+
const btnScheduleRefresh = $('btnScheduleRefresh')
|
|
3239
|
+
const btnScheduleCreateToggle = $('btnScheduleCreateToggle')
|
|
3240
|
+
const btnScheduleGeelibPreset = $('btnScheduleGeelibPreset')
|
|
3241
|
+
const scheduleCreateForm = $('scheduleCreateForm')
|
|
3242
|
+
const scheduleSessionSelect = $('scheduleSessionSelect')
|
|
3243
|
+
const schedulePromptInput = $('schedulePromptInput')
|
|
3244
|
+
const scheduleDelayMinutesInput = $('scheduleDelayMinutesInput')
|
|
3245
|
+
const scheduleCronInput = $('scheduleCronInput')
|
|
3246
|
+
const scheduleRecurringInput = $('scheduleRecurringInput')
|
|
3247
|
+
const scheduleDelayRow = $('scheduleDelayRow')
|
|
3248
|
+
const scheduleCronRow = $('scheduleCronRow')
|
|
3249
|
+
const btnScheduleCreateCancel = $('btnScheduleCreateCancel')
|
|
3250
|
+
const btnScheduleCreateSubmit = $('btnScheduleCreateSubmit')
|
|
3251
|
+
const btnManageAgents = $('btnManageAgents')
|
|
3252
|
+
const DEFAULT_AGENT_ID = 'qihoo'
|
|
2841
3253
|
const mcpPackageMeta = $('mcpPackageMeta')
|
|
2842
3254
|
const mcpPackageList = $('mcpPackageList')
|
|
2843
3255
|
const btnMcpPackageModalClose = $('btnMcpPackageModalClose')
|
|
@@ -2852,6 +3264,9 @@
|
|
|
2852
3264
|
const mainTitleEl = $('mainTitle')
|
|
2853
3265
|
const mainSubEl = $('mainSub')
|
|
2854
3266
|
const brandAgentNameEl = $('brandAgentName')
|
|
3267
|
+
const agentSwitchWrapEl = $('agentSwitchWrap')
|
|
3268
|
+
const agentSwitchDropdownEl = $('agentSwitchDropdown')
|
|
3269
|
+
let agentSwitchOpen = false
|
|
2855
3270
|
const sidebarHoverTipEl = $('sidebarHoverTip')
|
|
2856
3271
|
const sidebarAsideEl = document.querySelector('aside.sidebar')
|
|
2857
3272
|
let sidebarHoverTipHideTimer = null
|
|
@@ -2907,7 +3322,7 @@
|
|
|
2907
3322
|
}
|
|
2908
3323
|
function wireSidebarHoverTips() {
|
|
2909
3324
|
if (!sidebarAsideEl || !sidebarHoverTipEl) return
|
|
2910
|
-
const nodes = sidebarAsideEl.querySelectorAll('#brandAgentName, .sidebar-nav-item')
|
|
3325
|
+
const nodes = sidebarAsideEl.querySelectorAll('#brandAgentName, #btnManageAgents, .sidebar-nav-item')
|
|
2911
3326
|
for (let i = 0; i < nodes.length; i++) {
|
|
2912
3327
|
const el = nodes[i]
|
|
2913
3328
|
el.addEventListener('pointerenter', function () {
|
|
@@ -3005,7 +3420,7 @@
|
|
|
3005
3420
|
let refreshSkillPickerRows = null
|
|
3006
3421
|
let remoteMcpServers = []
|
|
3007
3422
|
const WS_PERMISSION_MODE_KEY = 'WS_PERMISSION_MODE'
|
|
3008
|
-
const
|
|
3423
|
+
const LLM_MODEL_KEY = 'LLM_MODEL'
|
|
3009
3424
|
const WS_PERMISSION_MODE_ALLOWED = new Set([
|
|
3010
3425
|
'acceptEdits',
|
|
3011
3426
|
'plan',
|
|
@@ -3021,17 +3436,71 @@
|
|
|
3021
3436
|
return typeof envObj[key] === 'string' ? envObj[key].trim() : ''
|
|
3022
3437
|
}
|
|
3023
3438
|
|
|
3439
|
+
/** 项目根 .env 中的 LLM 默认值(agent.json 未配置时用于新 session 展示) */
|
|
3440
|
+
let projectEnvDefaults = { LLM_MODEL: '' }
|
|
3441
|
+
|
|
3442
|
+
function parseDotEnvValue(content, key) {
|
|
3443
|
+
if (!content || typeof content !== 'string' || !key) return ''
|
|
3444
|
+
const lines = content.split('\n')
|
|
3445
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3446
|
+
const trimmed = lines[i].trim()
|
|
3447
|
+
if (!trimmed || trimmed.charAt(0) === '#') continue
|
|
3448
|
+
const eq = trimmed.indexOf('=')
|
|
3449
|
+
if (eq <= 0) continue
|
|
3450
|
+
if (trimmed.slice(0, eq).trim() !== key) continue
|
|
3451
|
+
let value = trimmed.slice(eq + 1).trim()
|
|
3452
|
+
if (
|
|
3453
|
+
(value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') ||
|
|
3454
|
+
(value.charAt(0) === "'" && value.charAt(value.length - 1) === "'")
|
|
3455
|
+
) {
|
|
3456
|
+
value = value.slice(1, -1)
|
|
3457
|
+
}
|
|
3458
|
+
return value
|
|
3459
|
+
}
|
|
3460
|
+
return ''
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
function buildSystemEnvApiUrl() {
|
|
3464
|
+
const u = new URL('/api/system/env', httpOriginForApi() + '/')
|
|
3465
|
+
u.searchParams.set('agent', currentAgentParam())
|
|
3466
|
+
return u.toString()
|
|
3467
|
+
}
|
|
3468
|
+
|
|
3469
|
+
async function loadProjectEnvDefaults() {
|
|
3470
|
+
try {
|
|
3471
|
+
const r = await fetch(buildSystemEnvApiUrl())
|
|
3472
|
+
if (!r.ok) return
|
|
3473
|
+
const body = await r.json().catch(function () {
|
|
3474
|
+
return {}
|
|
3475
|
+
})
|
|
3476
|
+
const content = typeof body.content === 'string' ? body.content : ''
|
|
3477
|
+
projectEnvDefaults = {
|
|
3478
|
+
LLM_MODEL: parseDotEnvValue(content, LLM_MODEL_KEY),
|
|
3479
|
+
}
|
|
3480
|
+
} catch {
|
|
3481
|
+
/* 项目 .env 不可读时不阻塞 composer */
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
/** 新 session 默认模型:agent.json.env → agent.json.model → 项目 .env */
|
|
3486
|
+
function readDefaultLlmModel() {
|
|
3487
|
+
const fromAgentEnv = readAgentEnvString(LLM_MODEL_KEY)
|
|
3488
|
+
if (fromAgentEnv) return fromAgentEnv
|
|
3489
|
+
const fromAgentModel =
|
|
3490
|
+
typeof agentConfigState.model === 'string' ? agentConfigState.model.trim() : ''
|
|
3491
|
+
if (fromAgentModel) return fromAgentModel
|
|
3492
|
+
return projectEnvDefaults.LLM_MODEL || ''
|
|
3493
|
+
}
|
|
3494
|
+
|
|
3024
3495
|
/**
|
|
3025
3496
|
* 业务语义:三个会话级配置的初始化顺序必须稳定:
|
|
3026
|
-
* 1)
|
|
3027
|
-
* 2)
|
|
3497
|
+
* 1) 先读取 agent.json.env / agent.json.model;
|
|
3498
|
+
* 2) 再回退到项目 .env 的 LLM_MODEL;
|
|
3028
3499
|
* 3) 将结果投影为 sessionOverrideState,保证 UI 与后端 PATCH 入参一致。
|
|
3029
3500
|
*/
|
|
3030
3501
|
function buildDefaultSessionOverrideState() {
|
|
3031
|
-
const model = readAgentEnvString(ANTHROPIC_MODEL_KEY)
|
|
3032
|
-
// 新 session 产品默认权限模式为 default,不继承 agent.json 中的 plan
|
|
3033
3502
|
return {
|
|
3034
|
-
model:
|
|
3503
|
+
model: readDefaultLlmModel(),
|
|
3035
3504
|
env: {
|
|
3036
3505
|
[WS_PERMISSION_MODE_KEY]: 'default',
|
|
3037
3506
|
},
|
|
@@ -3942,11 +4411,195 @@
|
|
|
3942
4411
|
typeof name === 'string' && name.trim() ? name.trim() : currentAgentParam()
|
|
3943
4412
|
const initial = id.charAt(0).toUpperCase() || 'A'
|
|
3944
4413
|
brandAgentNameEl.textContent = initial
|
|
3945
|
-
const tip = 'agent: ' + id
|
|
4414
|
+
const tip = 'agent: ' + id + '(点击切换)'
|
|
3946
4415
|
brandAgentNameEl.setAttribute('title', tip)
|
|
3947
4416
|
brandAgentNameEl.setAttribute('aria-label', tip)
|
|
3948
4417
|
}
|
|
3949
4418
|
|
|
4419
|
+
/** 构建 agent 列表 API 地址,用于侧栏头像切换 workspace agent */
|
|
4420
|
+
function buildAgentsListUrl() {
|
|
4421
|
+
const u = new URL('/api/agents', httpOriginForApi() + '/')
|
|
4422
|
+
u.searchParams.set('agent', currentAgentParam())
|
|
4423
|
+
return u.toString()
|
|
4424
|
+
}
|
|
4425
|
+
|
|
4426
|
+
/** 构建单个 agent 的 REST 地址,用于详情/修改/删除 */
|
|
4427
|
+
function buildAgentItemUrl(id) {
|
|
4428
|
+
const u = new URL(
|
|
4429
|
+
'/api/agents/' + encodeURIComponent(String(id || '').trim()),
|
|
4430
|
+
httpOriginForApi() + '/'
|
|
4431
|
+
)
|
|
4432
|
+
u.searchParams.set('agent', currentAgentParam())
|
|
4433
|
+
return u.toString()
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
/** 关闭 agent 切换下拉,恢复头像按钮状态 */
|
|
4437
|
+
function closeAgentSwitchMenu() {
|
|
4438
|
+
agentSwitchOpen = false
|
|
4439
|
+
if (agentSwitchWrapEl) agentSwitchWrapEl.classList.remove('open')
|
|
4440
|
+
if (agentSwitchDropdownEl) {
|
|
4441
|
+
agentSwitchDropdownEl.classList.remove('is-open')
|
|
4442
|
+
agentSwitchDropdownEl.hidden = true
|
|
4443
|
+
agentSwitchDropdownEl.style.left = ''
|
|
4444
|
+
agentSwitchDropdownEl.style.top = ''
|
|
4445
|
+
}
|
|
4446
|
+
if (brandAgentNameEl) brandAgentNameEl.setAttribute('aria-expanded', 'false')
|
|
4447
|
+
}
|
|
4448
|
+
|
|
4449
|
+
/** 根据头像位置计算浮层坐标,显示在侧栏右侧避免被 overflow 裁剪 */
|
|
4450
|
+
function positionAgentSwitchDropdown() {
|
|
4451
|
+
if (!brandAgentNameEl || !agentSwitchDropdownEl || !agentSwitchOpen) return
|
|
4452
|
+
requestAnimationFrame(function () {
|
|
4453
|
+
if (!agentSwitchOpen || !brandAgentNameEl || !agentSwitchDropdownEl) return
|
|
4454
|
+
const rect = brandAgentNameEl.getBoundingClientRect()
|
|
4455
|
+
const gap = 10
|
|
4456
|
+
const menuW = agentSwitchDropdownEl.offsetWidth
|
|
4457
|
+
const menuH = agentSwitchDropdownEl.offsetHeight
|
|
4458
|
+
let left = rect.right + gap
|
|
4459
|
+
let top = rect.top
|
|
4460
|
+
if (left + menuW > window.innerWidth - 12) {
|
|
4461
|
+
left = rect.left
|
|
4462
|
+
top = rect.bottom + gap
|
|
4463
|
+
}
|
|
4464
|
+
left = Math.max(12, Math.min(left, window.innerWidth - menuW - 12))
|
|
4465
|
+
top = Math.max(12, Math.min(top, window.innerHeight - menuH - 12))
|
|
4466
|
+
agentSwitchDropdownEl.style.left = left + 'px'
|
|
4467
|
+
agentSwitchDropdownEl.style.top = top + 'px'
|
|
4468
|
+
})
|
|
4469
|
+
}
|
|
4470
|
+
|
|
4471
|
+
/** 在 agent 切换下拉底部追加「管理 Agent」入口 */
|
|
4472
|
+
function appendAgentSwitchManageFooter() {
|
|
4473
|
+
if (!agentSwitchDropdownEl) return
|
|
4474
|
+
const foot = document.createElement('div')
|
|
4475
|
+
foot.className = 'agent-switch-dropdown-foot'
|
|
4476
|
+
const manageBtn = document.createElement('button')
|
|
4477
|
+
manageBtn.type = 'button'
|
|
4478
|
+
manageBtn.className = 'agent-switch-manage-btn'
|
|
4479
|
+
manageBtn.textContent = '管理 Agent…'
|
|
4480
|
+
manageBtn.addEventListener('click', function (ev) {
|
|
4481
|
+
ev.preventDefault()
|
|
4482
|
+
ev.stopPropagation()
|
|
4483
|
+
closeAgentSwitchMenu()
|
|
4484
|
+
const cur = currentAgentParam()
|
|
4485
|
+
window.location.href = cur ? '/?agent=' + encodeURIComponent(cur) : '/'
|
|
4486
|
+
})
|
|
4487
|
+
foot.appendChild(manageBtn)
|
|
4488
|
+
agentSwitchDropdownEl.appendChild(foot)
|
|
4489
|
+
}
|
|
4490
|
+
|
|
4491
|
+
/** 渲染 agent 列表项;当前 agent 高亮,点击后立即切换 workspace */
|
|
4492
|
+
function renderAgentSwitchList(agents) {
|
|
4493
|
+
if (!agentSwitchDropdownEl) return
|
|
4494
|
+
agentSwitchDropdownEl.innerHTML = ''
|
|
4495
|
+
const current = currentAgentParam()
|
|
4496
|
+
const head = document.createElement('div')
|
|
4497
|
+
head.className = 'agent-switch-dropdown-head'
|
|
4498
|
+
head.textContent = '切换 Agent'
|
|
4499
|
+
agentSwitchDropdownEl.appendChild(head)
|
|
4500
|
+
if (!Array.isArray(agents) || !agents.length) {
|
|
4501
|
+
const empty = document.createElement('div')
|
|
4502
|
+
empty.className = 'agent-switch-empty'
|
|
4503
|
+
empty.textContent = '暂无 agent'
|
|
4504
|
+
agentSwitchDropdownEl.appendChild(empty)
|
|
4505
|
+
appendAgentSwitchManageFooter()
|
|
4506
|
+
positionAgentSwitchDropdown()
|
|
4507
|
+
return
|
|
4508
|
+
}
|
|
4509
|
+
const list = document.createElement('div')
|
|
4510
|
+
list.className = 'agent-switch-dropdown-list'
|
|
4511
|
+
const frag = document.createDocumentFragment()
|
|
4512
|
+
for (let i = 0; i < agents.length; i++) {
|
|
4513
|
+
const row = agents[i]
|
|
4514
|
+
const id = String(row && row.id != null ? row.id : '').trim()
|
|
4515
|
+
if (!id) continue
|
|
4516
|
+
const displayName =
|
|
4517
|
+
row && typeof row.displayName === 'string' && row.displayName.trim()
|
|
4518
|
+
? row.displayName.trim()
|
|
4519
|
+
: id
|
|
4520
|
+
const btn = document.createElement('button')
|
|
4521
|
+
btn.type = 'button'
|
|
4522
|
+
btn.className = 'agent-switch-item' + (id === current ? ' is-current' : '')
|
|
4523
|
+
btn.setAttribute('role', 'option')
|
|
4524
|
+
btn.setAttribute('aria-selected', id === current ? 'true' : 'false')
|
|
4525
|
+
const mainEl = document.createElement('span')
|
|
4526
|
+
mainEl.className = 'agent-switch-item-main'
|
|
4527
|
+
const nameEl = document.createElement('span')
|
|
4528
|
+
nameEl.className = 'agent-switch-item-name'
|
|
4529
|
+
nameEl.textContent = displayName
|
|
4530
|
+
mainEl.appendChild(nameEl)
|
|
4531
|
+
if (displayName !== id) {
|
|
4532
|
+
const idEl = document.createElement('span')
|
|
4533
|
+
idEl.className = 'agent-switch-item-id'
|
|
4534
|
+
idEl.textContent = id
|
|
4535
|
+
mainEl.appendChild(idEl)
|
|
4536
|
+
}
|
|
4537
|
+
btn.appendChild(mainEl)
|
|
4538
|
+
const checkEl = document.createElement('span')
|
|
4539
|
+
checkEl.className = 'agent-switch-item-check'
|
|
4540
|
+
checkEl.setAttribute('aria-hidden', 'true')
|
|
4541
|
+
checkEl.innerHTML =
|
|
4542
|
+
'<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 8.2 6.6 11.3 12.5 4.8"/></svg>'
|
|
4543
|
+
btn.appendChild(checkEl)
|
|
4544
|
+
btn.addEventListener('click', function (ev) {
|
|
4545
|
+
ev.preventDefault()
|
|
4546
|
+
ev.stopPropagation()
|
|
4547
|
+
selectWorkspaceAgent(id)
|
|
4548
|
+
})
|
|
4549
|
+
frag.appendChild(btn)
|
|
4550
|
+
}
|
|
4551
|
+
list.appendChild(frag)
|
|
4552
|
+
agentSwitchDropdownEl.appendChild(list)
|
|
4553
|
+
appendAgentSwitchManageFooter()
|
|
4554
|
+
positionAgentSwitchDropdown()
|
|
4555
|
+
}
|
|
4556
|
+
|
|
4557
|
+
/** 选中目标 agent:复用 onAgentChanged 完成 WS 切换、会话刷新与配置重载 */
|
|
4558
|
+
function selectWorkspaceAgent(nextId) {
|
|
4559
|
+
const id = String(nextId || '').trim()
|
|
4560
|
+
if (!id || !agentIdInput) return
|
|
4561
|
+
closeAgentSwitchMenu()
|
|
4562
|
+
if (id === currentAgentParam()) return
|
|
4563
|
+
agentIdInput.value = id
|
|
4564
|
+
onAgentChanged()
|
|
4565
|
+
}
|
|
4566
|
+
|
|
4567
|
+
/** 打开 agent 切换下拉,按需拉取 /api/agents 列表 */
|
|
4568
|
+
async function openAgentSwitchMenu() {
|
|
4569
|
+
if (!agentSwitchWrapEl || !agentSwitchDropdownEl || !brandAgentNameEl) return
|
|
4570
|
+
hideSidebarHoverTip()
|
|
4571
|
+
agentSwitchOpen = true
|
|
4572
|
+
agentSwitchWrapEl.classList.add('open')
|
|
4573
|
+
agentSwitchDropdownEl.hidden = false
|
|
4574
|
+
agentSwitchDropdownEl.classList.add('is-open')
|
|
4575
|
+
brandAgentNameEl.setAttribute('aria-expanded', 'true')
|
|
4576
|
+
agentSwitchDropdownEl.innerHTML = '<div class="agent-switch-loading">加载中…</div>'
|
|
4577
|
+
positionAgentSwitchDropdown()
|
|
4578
|
+
try {
|
|
4579
|
+
const r = await fetch(buildAgentsListUrl())
|
|
4580
|
+
const body = await r.json().catch(function () {
|
|
4581
|
+
return {}
|
|
4582
|
+
})
|
|
4583
|
+
if (!r.ok) {
|
|
4584
|
+
throw new Error(body.message || body.error || r.statusText)
|
|
4585
|
+
}
|
|
4586
|
+
renderAgentSwitchList(body.agents)
|
|
4587
|
+
} catch (e) {
|
|
4588
|
+
agentSwitchDropdownEl.innerHTML =
|
|
4589
|
+
'<div class="agent-switch-empty">加载失败: ' + escapeHtml(String(e)) + '</div>'
|
|
4590
|
+
positionAgentSwitchDropdown()
|
|
4591
|
+
}
|
|
4592
|
+
}
|
|
4593
|
+
|
|
4594
|
+
/** 点击头像时切换下拉开关 */
|
|
4595
|
+
async function toggleAgentSwitchMenu() {
|
|
4596
|
+
if (agentSwitchOpen) {
|
|
4597
|
+
closeAgentSwitchMenu()
|
|
4598
|
+
return
|
|
4599
|
+
}
|
|
4600
|
+
await openAgentSwitchMenu()
|
|
4601
|
+
}
|
|
4602
|
+
|
|
3950
4603
|
function rewriteSameOriginNavLinks() {
|
|
3951
4604
|
const agent = currentAgentParam()
|
|
3952
4605
|
const origin = window.location.origin
|
|
@@ -3988,6 +4641,244 @@
|
|
|
3988
4641
|
return u.toString()
|
|
3989
4642
|
}
|
|
3990
4643
|
|
|
4644
|
+
function buildSchedulesUrl() {
|
|
4645
|
+
const u = new URL('/api/schedules', httpOriginForApi() + '/')
|
|
4646
|
+
u.searchParams.set('agent', currentAgentParam())
|
|
4647
|
+
return u.toString()
|
|
4648
|
+
}
|
|
4649
|
+
|
|
4650
|
+
function buildScheduleDeleteUrl(id) {
|
|
4651
|
+
const u = new URL('/api/schedules', httpOriginForApi() + '/')
|
|
4652
|
+
u.searchParams.set('agent', currentAgentParam())
|
|
4653
|
+
u.searchParams.set('id', id)
|
|
4654
|
+
return u.toString()
|
|
4655
|
+
}
|
|
4656
|
+
|
|
4657
|
+
/** 从已加载 session 列表解析会话标题 */
|
|
4658
|
+
function scheduleSessionLabel(sessionId) {
|
|
4659
|
+
const sid = String(sessionId || '')
|
|
4660
|
+
const sessions = window.__lastSessions
|
|
4661
|
+
if (Array.isArray(sessions)) {
|
|
4662
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
4663
|
+
const s = sessions[i]
|
|
4664
|
+
if (s && s.sessionId === sid) {
|
|
4665
|
+
return sessionTitle(s)
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
return sid.slice(0, 8) + '…'
|
|
4670
|
+
}
|
|
4671
|
+
|
|
4672
|
+
function formatScheduleFireAt(ms) {
|
|
4673
|
+
if (typeof ms !== 'number' || !Number.isFinite(ms)) return '—'
|
|
4674
|
+
try {
|
|
4675
|
+
return new Date(ms).toLocaleString()
|
|
4676
|
+
} catch {
|
|
4677
|
+
return String(ms)
|
|
4678
|
+
}
|
|
4679
|
+
}
|
|
4680
|
+
|
|
4681
|
+
/** 填充新建任务时的 session 下拉 */
|
|
4682
|
+
function populateScheduleSessionSelect() {
|
|
4683
|
+
if (!scheduleSessionSelect) return
|
|
4684
|
+
const sessions = Array.isArray(window.__lastSessions) ? window.__lastSessions : []
|
|
4685
|
+
const currentSid = sessionIdInput.value.trim()
|
|
4686
|
+
scheduleSessionSelect.innerHTML = ''
|
|
4687
|
+
if (!sessions.length) {
|
|
4688
|
+
const opt = document.createElement('option')
|
|
4689
|
+
opt.value = currentSid
|
|
4690
|
+
opt.textContent = currentSid ? currentSid.slice(0, 8) + '…' : '(当前会话)'
|
|
4691
|
+
scheduleSessionSelect.appendChild(opt)
|
|
4692
|
+
return
|
|
4693
|
+
}
|
|
4694
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
4695
|
+
const s = sessions[i]
|
|
4696
|
+
if (!s || !s.sessionId) continue
|
|
4697
|
+
const opt = document.createElement('option')
|
|
4698
|
+
opt.value = s.sessionId
|
|
4699
|
+
opt.textContent = sessionTitle(s) + ' (' + s.sessionId.slice(0, 8) + '…)'
|
|
4700
|
+
if (s.sessionId === currentSid) opt.selected = true
|
|
4701
|
+
scheduleSessionSelect.appendChild(opt)
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
|
|
4705
|
+
/** Geelib 定时巡检快捷模板:/geelib poll,每分钟循环 */
|
|
4706
|
+
function applyGeelibSchedulePreset() {
|
|
4707
|
+
if (scheduleCreateForm) scheduleCreateForm.hidden = false
|
|
4708
|
+
populateScheduleSessionSelect()
|
|
4709
|
+
if (schedulePromptInput) schedulePromptInput.value = '/geelib poll'
|
|
4710
|
+
document.querySelectorAll('input[name="scheduleTriggerMode"]').forEach(function (el) {
|
|
4711
|
+
el.checked = el.value === 'cron'
|
|
4712
|
+
})
|
|
4713
|
+
if (scheduleDelayRow) scheduleDelayRow.hidden = true
|
|
4714
|
+
if (scheduleCronRow) scheduleCronRow.hidden = false
|
|
4715
|
+
if (scheduleCronInput) scheduleCronInput.value = '* * * * *'
|
|
4716
|
+
if (scheduleRecurringInput) scheduleRecurringInput.checked = true
|
|
4717
|
+
}
|
|
4718
|
+
|
|
4719
|
+
/** 渲染定时任务表格 */
|
|
4720
|
+
function renderScheduleTaskTable(tasks, timezone) {
|
|
4721
|
+
if (!scheduleTaskTableBody || !scheduleManageEmpty) return
|
|
4722
|
+
scheduleTaskTableBody.innerHTML = ''
|
|
4723
|
+
const list = Array.isArray(tasks) ? tasks : []
|
|
4724
|
+
scheduleManageEmpty.hidden = list.length > 0
|
|
4725
|
+
for (let i = 0; i < list.length; i++) {
|
|
4726
|
+
const task = list[i]
|
|
4727
|
+
if (!task || !task.id) continue
|
|
4728
|
+
const tr = document.createElement('tr')
|
|
4729
|
+
const tdId = document.createElement('td')
|
|
4730
|
+
tdId.textContent = task.id
|
|
4731
|
+
const tdSession = document.createElement('td')
|
|
4732
|
+
const sessionBtn = document.createElement('button')
|
|
4733
|
+
sessionBtn.type = 'button'
|
|
4734
|
+
sessionBtn.className = 'schedule-manage-session-link'
|
|
4735
|
+
sessionBtn.textContent = scheduleSessionLabel(task.sessionId)
|
|
4736
|
+
sessionBtn.title = task.sessionId
|
|
4737
|
+
sessionBtn.addEventListener('click', function () {
|
|
4738
|
+
closeScheduleManageModal()
|
|
4739
|
+
switchToSession(task.sessionId)
|
|
4740
|
+
})
|
|
4741
|
+
tdSession.appendChild(sessionBtn)
|
|
4742
|
+
const tdCron = document.createElement('td')
|
|
4743
|
+
tdCron.textContent = task.cron || '—'
|
|
4744
|
+
const tdNext = document.createElement('td')
|
|
4745
|
+
tdNext.textContent = formatScheduleFireAt(task.nextFireAt)
|
|
4746
|
+
const tdPrompt = document.createElement('td')
|
|
4747
|
+
tdPrompt.className = 'schedule-manage-prompt'
|
|
4748
|
+
tdPrompt.textContent = task.prompt || ''
|
|
4749
|
+
const tdType = document.createElement('td')
|
|
4750
|
+
tdType.textContent = task.recurring ? '循环' : '一次性'
|
|
4751
|
+
const tdAction = document.createElement('td')
|
|
4752
|
+
const delBtn = document.createElement('button')
|
|
4753
|
+
delBtn.type = 'button'
|
|
4754
|
+
delBtn.className = 'btn-system-settings'
|
|
4755
|
+
delBtn.textContent = '删除'
|
|
4756
|
+
delBtn.addEventListener('click', function () {
|
|
4757
|
+
void deleteScheduleTask(task.id)
|
|
4758
|
+
})
|
|
4759
|
+
tdAction.appendChild(delBtn)
|
|
4760
|
+
tr.appendChild(tdId)
|
|
4761
|
+
tr.appendChild(tdSession)
|
|
4762
|
+
tr.appendChild(tdCron)
|
|
4763
|
+
tr.appendChild(tdNext)
|
|
4764
|
+
tr.appendChild(tdPrompt)
|
|
4765
|
+
tr.appendChild(tdType)
|
|
4766
|
+
tr.appendChild(tdAction)
|
|
4767
|
+
scheduleTaskTableBody.appendChild(tr)
|
|
4768
|
+
}
|
|
4769
|
+
if (scheduleManageMeta) {
|
|
4770
|
+
scheduleManageMeta.textContent =
|
|
4771
|
+
'时区: ' + (timezone || 'local') + ' · 共 ' + list.length + ' 个任务'
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4774
|
+
|
|
4775
|
+
/** 拉取 agent 全部定时任务 */
|
|
4776
|
+
async function loadScheduleTasks() {
|
|
4777
|
+
const res = await fetch(buildSchedulesUrl())
|
|
4778
|
+
const body = await res.json()
|
|
4779
|
+
if (!res.ok) {
|
|
4780
|
+
throw new Error(body.message || body.error || res.statusText)
|
|
4781
|
+
}
|
|
4782
|
+
renderScheduleTaskTable(body.tasks, body.timezone)
|
|
4783
|
+
return body
|
|
4784
|
+
}
|
|
4785
|
+
|
|
4786
|
+
/** 创建定时任务 */
|
|
4787
|
+
async function createScheduleTask() {
|
|
4788
|
+
if (!scheduleSessionSelect || !schedulePromptInput) return
|
|
4789
|
+
const sessionId = scheduleSessionSelect.value.trim()
|
|
4790
|
+
const prompt = schedulePromptInput.value.trim()
|
|
4791
|
+
if (!sessionId) {
|
|
4792
|
+
window.alert('请选择关联会话')
|
|
4793
|
+
return
|
|
4794
|
+
}
|
|
4795
|
+
if (!prompt) {
|
|
4796
|
+
window.alert('请填写 Prompt')
|
|
4797
|
+
return
|
|
4798
|
+
}
|
|
4799
|
+
const modeEl = document.querySelector('input[name="scheduleTriggerMode"]:checked')
|
|
4800
|
+
const mode = modeEl ? modeEl.value : 'delay'
|
|
4801
|
+
const payload = {
|
|
4802
|
+
sessionId: sessionId,
|
|
4803
|
+
prompt: prompt,
|
|
4804
|
+
recurring: !!(scheduleRecurringInput && scheduleRecurringInput.checked),
|
|
4805
|
+
}
|
|
4806
|
+
if (mode === 'cron') {
|
|
4807
|
+
const cron = scheduleCronInput ? scheduleCronInput.value.trim() : ''
|
|
4808
|
+
if (!cron) {
|
|
4809
|
+
window.alert('请填写 Cron 表达式')
|
|
4810
|
+
return
|
|
4811
|
+
}
|
|
4812
|
+
payload.cron = cron
|
|
4813
|
+
} else {
|
|
4814
|
+
const delay = scheduleDelayMinutesInput
|
|
4815
|
+
? Number(scheduleDelayMinutesInput.value)
|
|
4816
|
+
: NaN
|
|
4817
|
+
if (!Number.isFinite(delay) || delay < 1) {
|
|
4818
|
+
window.alert('delayMinutes 必须是 >= 1 的整数')
|
|
4819
|
+
return
|
|
4820
|
+
}
|
|
4821
|
+
payload.delayMinutes = Math.floor(delay)
|
|
4822
|
+
}
|
|
4823
|
+
const res = await fetch(buildSchedulesUrl(), {
|
|
4824
|
+
method: 'POST',
|
|
4825
|
+
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
|
4826
|
+
body: JSON.stringify(payload),
|
|
4827
|
+
})
|
|
4828
|
+
const body = await res.json()
|
|
4829
|
+
if (!res.ok) {
|
|
4830
|
+
throw new Error(body.message || body.error || res.statusText)
|
|
4831
|
+
}
|
|
4832
|
+
if (scheduleCreateForm) scheduleCreateForm.hidden = true
|
|
4833
|
+
if (schedulePromptInput) schedulePromptInput.value = ''
|
|
4834
|
+
await loadScheduleTasks()
|
|
4835
|
+
}
|
|
4836
|
+
|
|
4837
|
+
/** 删除定时任务 */
|
|
4838
|
+
async function deleteScheduleTask(id) {
|
|
4839
|
+
if (!window.confirm('确定删除定时任务 ' + id + '?')) return
|
|
4840
|
+
const res = await fetch(buildScheduleDeleteUrl(id), { method: 'DELETE' })
|
|
4841
|
+
const body = await res.json()
|
|
4842
|
+
if (!res.ok) {
|
|
4843
|
+
window.alert('删除失败: ' + (body.message || body.error || res.statusText))
|
|
4844
|
+
return
|
|
4845
|
+
}
|
|
4846
|
+
await loadScheduleTasks()
|
|
4847
|
+
}
|
|
4848
|
+
|
|
4849
|
+
function closeScheduleManageModal() {
|
|
4850
|
+
if (!scheduleManageModal) return
|
|
4851
|
+
scheduleManageModal.classList.remove('is-open')
|
|
4852
|
+
scheduleManageModal.setAttribute('aria-hidden', 'true')
|
|
4853
|
+
document.body.style.overflow = ''
|
|
4854
|
+
if (scheduleCreateForm) scheduleCreateForm.hidden = true
|
|
4855
|
+
}
|
|
4856
|
+
|
|
4857
|
+
/** 打开定时任务管理弹窗 */
|
|
4858
|
+
async function openScheduleManageModal() {
|
|
4859
|
+
if (!scheduleManageModal) return
|
|
4860
|
+
scheduleManageModal.classList.add('is-open')
|
|
4861
|
+
scheduleManageModal.setAttribute('aria-hidden', 'false')
|
|
4862
|
+
document.body.style.overflow = 'hidden'
|
|
4863
|
+
populateScheduleSessionSelect()
|
|
4864
|
+
if (scheduleTaskTableBody) {
|
|
4865
|
+
scheduleTaskTableBody.innerHTML =
|
|
4866
|
+
'<tr><td colspan="7" style="padding:1rem;text-align:center;color:#8892a8">加载中…</td></tr>'
|
|
4867
|
+
}
|
|
4868
|
+
try {
|
|
4869
|
+
await loadSessions()
|
|
4870
|
+
populateScheduleSessionSelect()
|
|
4871
|
+
await loadScheduleTasks()
|
|
4872
|
+
} catch (e) {
|
|
4873
|
+
if (scheduleTaskTableBody) {
|
|
4874
|
+
scheduleTaskTableBody.innerHTML =
|
|
4875
|
+
'<tr><td colspan="7" style="padding:1rem;color:#c0392b">加载失败: ' +
|
|
4876
|
+
String(e) +
|
|
4877
|
+
'</td></tr>'
|
|
4878
|
+
}
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
|
|
3991
4882
|
function renderPendingPromptsList(items) {
|
|
3992
4883
|
if (!pendingPromptsListEl || !pendingPromptsBarEl) return
|
|
3993
4884
|
pendingPromptsCache = Array.isArray(items) ? items : []
|
|
@@ -4181,6 +5072,13 @@
|
|
|
4181
5072
|
return u.toString()
|
|
4182
5073
|
}
|
|
4183
5074
|
|
|
5075
|
+
function buildBaseSkillMdUrl(skillName) {
|
|
5076
|
+
const u = new URL('/api/skills/base-skill-md', httpOriginForApi() + '/')
|
|
5077
|
+
u.searchParams.set('agent', currentAgentParam())
|
|
5078
|
+
u.searchParams.set('name', skillName)
|
|
5079
|
+
return u.toString()
|
|
5080
|
+
}
|
|
5081
|
+
|
|
4184
5082
|
function buildSkillInstalledListUrl() {
|
|
4185
5083
|
const u = new URL('/api/skills/installed-list', httpOriginForApi() + '/')
|
|
4186
5084
|
u.searchParams.set('agent', currentAgentParam())
|
|
@@ -4864,10 +5762,6 @@
|
|
|
4864
5762
|
|
|
4865
5763
|
async function deleteSessionById(sessionId) {
|
|
4866
5764
|
if (!sessionId) return
|
|
4867
|
-
const ok = window.confirm(
|
|
4868
|
-
'确定删除该会话?将删除磁盘上的 transcript 与相关目录,不可恢复。\n\n' + sessionId,
|
|
4869
|
-
)
|
|
4870
|
-
if (!ok) return
|
|
4871
5765
|
const delUrl = buildSessionDeleteUrl(sessionId)
|
|
4872
5766
|
try {
|
|
4873
5767
|
const r = await fetch(delUrl, { method: 'DELETE' })
|
|
@@ -4960,12 +5854,23 @@
|
|
|
4960
5854
|
const nextSid = typeof id === 'string' ? id : ''
|
|
4961
5855
|
sessionIdInput.value = nextSid
|
|
4962
5856
|
void loadPendingPrompts()
|
|
5857
|
+
if (nextSid) {
|
|
5858
|
+
void loadSessionOverridesIntoComposer()
|
|
5859
|
+
} else {
|
|
5860
|
+
void loadProjectEnvDefaults().then(function () {
|
|
5861
|
+
resetSessionOverrideStateToDefault()
|
|
5862
|
+
})
|
|
5863
|
+
}
|
|
4963
5864
|
// 优先走「单 WS、多子进程」路径:复用当前连接,仅让后端 kill+respawn 子进程
|
|
4964
5865
|
if (socket && socket.readyState === WebSocket.OPEN) {
|
|
4965
5866
|
serverReady = false
|
|
4966
5867
|
resetChatUi()
|
|
4967
5868
|
pendingSessionOverrides = null
|
|
4968
|
-
|
|
5869
|
+
if (nextSid) {
|
|
5870
|
+
/* 已在上方拉取 overrides;切换中勿清空 composer 模型 */
|
|
5871
|
+
} else {
|
|
5872
|
+
resetSessionOverrideStateToDefault()
|
|
5873
|
+
}
|
|
4969
5874
|
if (window.__lastSessions) renderSessionList(window.__lastSessions)
|
|
4970
5875
|
else updateMainHeader()
|
|
4971
5876
|
const payload = {
|
|
@@ -4990,7 +5895,9 @@
|
|
|
4990
5895
|
disconnectIfOpen()
|
|
4991
5896
|
if (window.__lastSessions) renderSessionList(window.__lastSessions)
|
|
4992
5897
|
else updateMainHeader()
|
|
4993
|
-
|
|
5898
|
+
if (!nextSid) {
|
|
5899
|
+
resetSessionOverrideStateToDefault()
|
|
5900
|
+
}
|
|
4994
5901
|
connectWebSocket()
|
|
4995
5902
|
}
|
|
4996
5903
|
|
|
@@ -5391,7 +6298,7 @@
|
|
|
5391
6298
|
const model = typeof sessionOverrideState.model === 'string'
|
|
5392
6299
|
? sessionOverrideState.model.trim()
|
|
5393
6300
|
: ''
|
|
5394
|
-
env[
|
|
6301
|
+
env[LLM_MODEL_KEY] = model
|
|
5395
6302
|
}
|
|
5396
6303
|
|
|
5397
6304
|
function normalizePermissionMode(value) {
|
|
@@ -5549,8 +6456,8 @@
|
|
|
5549
6456
|
: {}
|
|
5550
6457
|
sessionOverrideState = {
|
|
5551
6458
|
model:
|
|
5552
|
-
typeof ovEnv[
|
|
5553
|
-
? String(ovEnv[
|
|
6459
|
+
typeof ovEnv[LLM_MODEL_KEY] === 'string'
|
|
6460
|
+
? String(ovEnv[LLM_MODEL_KEY]).trim()
|
|
5554
6461
|
: defaults.model,
|
|
5555
6462
|
env: {
|
|
5556
6463
|
[WS_PERMISSION_MODE_KEY]:
|
|
@@ -5569,7 +6476,7 @@
|
|
|
5569
6476
|
const env = getSessionOverrideEnv()
|
|
5570
6477
|
const patchEnv = {}
|
|
5571
6478
|
const defaults = buildDefaultSessionOverrideState()
|
|
5572
|
-
patchEnv[
|
|
6479
|
+
patchEnv[LLM_MODEL_KEY] =
|
|
5573
6480
|
typeof sessionOverrideState.model === 'string'
|
|
5574
6481
|
? sessionOverrideState.model.trim()
|
|
5575
6482
|
: defaults.model
|
|
@@ -5766,7 +6673,13 @@
|
|
|
5766
6673
|
}
|
|
5767
6674
|
renderBindChips()
|
|
5768
6675
|
syncModelInputFromState()
|
|
5769
|
-
void
|
|
6676
|
+
void loadProjectEnvDefaults().then(function () {
|
|
6677
|
+
if (!sessionIdInput || !sessionIdInput.value.trim()) {
|
|
6678
|
+
resetSessionOverrideStateToDefault()
|
|
6679
|
+
} else {
|
|
6680
|
+
void loadSessionOverridesIntoComposer()
|
|
6681
|
+
}
|
|
6682
|
+
})
|
|
5770
6683
|
logLine('agent-config', 'load failed ' + (body.message || r.status))
|
|
5771
6684
|
return
|
|
5772
6685
|
}
|
|
@@ -5810,7 +6723,13 @@
|
|
|
5810
6723
|
}
|
|
5811
6724
|
renderBindChips()
|
|
5812
6725
|
syncModelInputFromState()
|
|
5813
|
-
void
|
|
6726
|
+
void loadProjectEnvDefaults().then(function () {
|
|
6727
|
+
if (!sessionIdInput || !sessionIdInput.value.trim()) {
|
|
6728
|
+
resetSessionOverrideStateToDefault()
|
|
6729
|
+
} else {
|
|
6730
|
+
void loadSessionOverridesIntoComposer()
|
|
6731
|
+
}
|
|
6732
|
+
})
|
|
5814
6733
|
} catch (e) {
|
|
5815
6734
|
logLine('agent-config', String(e))
|
|
5816
6735
|
}
|
|
@@ -6762,6 +7681,16 @@
|
|
|
6762
7681
|
renderSkillRows()
|
|
6763
7682
|
})
|
|
6764
7683
|
actions.appendChild(toggleBtn)
|
|
7684
|
+
if (!canDelete) {
|
|
7685
|
+
const editBtn = document.createElement('button')
|
|
7686
|
+
editBtn.type = 'button'
|
|
7687
|
+
editBtn.className = 'btn-picker-action'
|
|
7688
|
+
editBtn.textContent = '编辑'
|
|
7689
|
+
editBtn.addEventListener('click', function () {
|
|
7690
|
+
openSkillMdModal(id)
|
|
7691
|
+
})
|
|
7692
|
+
actions.appendChild(editBtn)
|
|
7693
|
+
}
|
|
6765
7694
|
if (canDelete) {
|
|
6766
7695
|
const exportBtn = document.createElement('button')
|
|
6767
7696
|
exportBtn.type = 'button'
|
|
@@ -7089,6 +8018,16 @@
|
|
|
7089
8018
|
const btn = ev.target && ev.target.closest ? ev.target.closest('[data-add]') : null
|
|
7090
8019
|
if (!btn) return
|
|
7091
8020
|
const k = btn.getAttribute('data-add')
|
|
8021
|
+
if (k === 'schedules') {
|
|
8022
|
+
ev.preventDefault()
|
|
8023
|
+
ev.stopPropagation()
|
|
8024
|
+
const items = sidebarDrawersEl.querySelectorAll('.sidebar-nav-item')
|
|
8025
|
+
for (let i = 0; i < items.length; i++) {
|
|
8026
|
+
items[i].classList.toggle('is-active', items[i] === btn)
|
|
8027
|
+
}
|
|
8028
|
+
void openScheduleManageModal()
|
|
8029
|
+
return
|
|
8030
|
+
}
|
|
7092
8031
|
if (k === 'tools' || k === 'mcp' || k === 'skills' || k === 'agentTeams') {
|
|
7093
8032
|
ev.preventDefault()
|
|
7094
8033
|
ev.stopPropagation()
|
|
@@ -7197,6 +8136,59 @@
|
|
|
7197
8136
|
})
|
|
7198
8137
|
}
|
|
7199
8138
|
|
|
8139
|
+
if (btnScheduleManageModalClose) {
|
|
8140
|
+
btnScheduleManageModalClose.addEventListener('click', closeScheduleManageModal)
|
|
8141
|
+
}
|
|
8142
|
+
if (scheduleManageModalBackdrop) {
|
|
8143
|
+
scheduleManageModalBackdrop.addEventListener('click', closeScheduleManageModal)
|
|
8144
|
+
}
|
|
8145
|
+
if (btnScheduleRefresh) {
|
|
8146
|
+
btnScheduleRefresh.addEventListener('click', function () {
|
|
8147
|
+
void loadScheduleTasks().catch(function (e) {
|
|
8148
|
+
window.alert('刷新失败: ' + e)
|
|
8149
|
+
})
|
|
8150
|
+
})
|
|
8151
|
+
}
|
|
8152
|
+
if (btnScheduleCreateToggle && scheduleCreateForm) {
|
|
8153
|
+
btnScheduleCreateToggle.addEventListener('click', function () {
|
|
8154
|
+
scheduleCreateForm.hidden = !scheduleCreateForm.hidden
|
|
8155
|
+
if (!scheduleCreateForm.hidden) populateScheduleSessionSelect()
|
|
8156
|
+
})
|
|
8157
|
+
}
|
|
8158
|
+
if (btnScheduleGeelibPreset) {
|
|
8159
|
+
btnScheduleGeelibPreset.addEventListener('click', function () {
|
|
8160
|
+
applyGeelibSchedulePreset()
|
|
8161
|
+
})
|
|
8162
|
+
}
|
|
8163
|
+
if (btnScheduleCreateCancel && scheduleCreateForm) {
|
|
8164
|
+
btnScheduleCreateCancel.addEventListener('click', function () {
|
|
8165
|
+
scheduleCreateForm.hidden = true
|
|
8166
|
+
})
|
|
8167
|
+
}
|
|
8168
|
+
if (btnScheduleCreateSubmit) {
|
|
8169
|
+
btnScheduleCreateSubmit.addEventListener('click', function () {
|
|
8170
|
+
void createScheduleTask().catch(function (e) {
|
|
8171
|
+
window.alert('创建失败: ' + e)
|
|
8172
|
+
})
|
|
8173
|
+
})
|
|
8174
|
+
}
|
|
8175
|
+
document.querySelectorAll('input[name="scheduleTriggerMode"]').forEach(function (el) {
|
|
8176
|
+
el.addEventListener('change', function () {
|
|
8177
|
+
const useCron = el.value === 'cron' && el.checked
|
|
8178
|
+
if (scheduleDelayRow) scheduleDelayRow.hidden = useCron
|
|
8179
|
+
if (scheduleCronRow) scheduleCronRow.hidden = !useCron
|
|
8180
|
+
})
|
|
8181
|
+
})
|
|
8182
|
+
|
|
8183
|
+
if (btnManageAgents) {
|
|
8184
|
+
btnManageAgents.addEventListener('click', function (ev) {
|
|
8185
|
+
ev.preventDefault()
|
|
8186
|
+
ev.stopPropagation()
|
|
8187
|
+
const cur = currentAgentParam()
|
|
8188
|
+
window.location.href = cur ? '/?agent=' + encodeURIComponent(cur) : '/'
|
|
8189
|
+
})
|
|
8190
|
+
}
|
|
8191
|
+
|
|
7200
8192
|
function closeAgentMdModal() {
|
|
7201
8193
|
if (!agentMdModal) return
|
|
7202
8194
|
agentMdModal.classList.remove('is-open')
|
|
@@ -7204,6 +8196,78 @@
|
|
|
7204
8196
|
document.body.style.overflow = ''
|
|
7205
8197
|
}
|
|
7206
8198
|
|
|
8199
|
+
function closeSkillMdModal() {
|
|
8200
|
+
if (!skillMdModal) return
|
|
8201
|
+
skillMdModal.classList.remove('is-open')
|
|
8202
|
+
skillMdModal.setAttribute('aria-hidden', 'true')
|
|
8203
|
+
document.body.style.overflow = ''
|
|
8204
|
+
skillMdEditingName = ''
|
|
8205
|
+
}
|
|
8206
|
+
|
|
8207
|
+
function openSkillMdModal(skillName) {
|
|
8208
|
+
if (!skillMdModal || !skillMdEditor || !skillMdModalTitle) return
|
|
8209
|
+
skillMdEditingName = String(skillName || '').trim()
|
|
8210
|
+
if (!skillMdEditingName) return
|
|
8211
|
+
skillMdModal.classList.add('is-open')
|
|
8212
|
+
skillMdModal.setAttribute('aria-hidden', 'false')
|
|
8213
|
+
document.body.style.overflow = 'hidden'
|
|
8214
|
+
skillMdEditor.value = ''
|
|
8215
|
+
skillMdEditor.placeholder = '加载中…'
|
|
8216
|
+
skillMdModalTitle.textContent = '编辑 SKILL.md · /' + skillMdEditingName
|
|
8217
|
+
fetch(buildBaseSkillMdUrl(skillMdEditingName))
|
|
8218
|
+
.then(function (r) {
|
|
8219
|
+
return r.json().then(function (body) {
|
|
8220
|
+
return { r: r, body: body }
|
|
8221
|
+
})
|
|
8222
|
+
})
|
|
8223
|
+
.then(function (x) {
|
|
8224
|
+
if (!x.r.ok) {
|
|
8225
|
+
skillMdEditor.placeholder = ''
|
|
8226
|
+
const msg = x.body.message || x.body.error || x.r.statusText || '请求失败'
|
|
8227
|
+
window.alert('加载 SKILL.md 失败:' + msg)
|
|
8228
|
+
closeSkillMdModal()
|
|
8229
|
+
return
|
|
8230
|
+
}
|
|
8231
|
+
skillMdEditor.value =
|
|
8232
|
+
typeof x.body.content === 'string' ? x.body.content : ''
|
|
8233
|
+
skillMdEditor.placeholder = 'Markdown 源码…'
|
|
8234
|
+
})
|
|
8235
|
+
.catch(function (e) {
|
|
8236
|
+
window.alert('加载 SKILL.md 失败: ' + e)
|
|
8237
|
+
closeSkillMdModal()
|
|
8238
|
+
})
|
|
8239
|
+
}
|
|
8240
|
+
|
|
8241
|
+
async function saveSkillMd() {
|
|
8242
|
+
if (!skillMdEditor || !btnSkillMdSave || !skillMdEditingName) return
|
|
8243
|
+
btnSkillMdSave.disabled = true
|
|
8244
|
+
try {
|
|
8245
|
+
const r = await fetch(buildBaseSkillMdUrl(skillMdEditingName), {
|
|
8246
|
+
method: 'PUT',
|
|
8247
|
+
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
|
8248
|
+
body: JSON.stringify({ content: String(skillMdEditor.value) }),
|
|
8249
|
+
})
|
|
8250
|
+
const body = await r.json().catch(function () {
|
|
8251
|
+
return {}
|
|
8252
|
+
})
|
|
8253
|
+
if (!r.ok) {
|
|
8254
|
+
window.alert('保存失败:' + (body.message || body.error || r.statusText))
|
|
8255
|
+
return
|
|
8256
|
+
}
|
|
8257
|
+
closeSkillMdModal()
|
|
8258
|
+
setStatus('SKILL.md 已保存', serverReady ? 'ready' : '')
|
|
8259
|
+
restartCurrentSessionSubprocessWithReason('save-base-skill-md')
|
|
8260
|
+
if (typeof refreshSkillPickerRows === 'function') {
|
|
8261
|
+
void refreshSkillPickerRows()
|
|
8262
|
+
}
|
|
8263
|
+
window.alert('SKILL.md 已保存,并已重启当前 session 子进程。')
|
|
8264
|
+
} catch (e) {
|
|
8265
|
+
window.alert('保存失败: ' + e)
|
|
8266
|
+
} finally {
|
|
8267
|
+
btnSkillMdSave.disabled = false
|
|
8268
|
+
}
|
|
8269
|
+
}
|
|
8270
|
+
|
|
7207
8271
|
function closeAgentEnvModal() {
|
|
7208
8272
|
if (!agentEnvModal) return
|
|
7209
8273
|
agentEnvModal.classList.remove('is-open')
|
|
@@ -7942,6 +9006,20 @@
|
|
|
7942
9006
|
void saveAgentMd()
|
|
7943
9007
|
})
|
|
7944
9008
|
}
|
|
9009
|
+
if (btnSkillMdModalClose) {
|
|
9010
|
+
btnSkillMdModalClose.addEventListener('click', closeSkillMdModal)
|
|
9011
|
+
}
|
|
9012
|
+
if (btnSkillMdCancel) {
|
|
9013
|
+
btnSkillMdCancel.addEventListener('click', closeSkillMdModal)
|
|
9014
|
+
}
|
|
9015
|
+
if (skillMdModalBackdrop) {
|
|
9016
|
+
skillMdModalBackdrop.addEventListener('click', closeSkillMdModal)
|
|
9017
|
+
}
|
|
9018
|
+
if (btnSkillMdSave) {
|
|
9019
|
+
btnSkillMdSave.addEventListener('click', function () {
|
|
9020
|
+
void saveSkillMd()
|
|
9021
|
+
})
|
|
9022
|
+
}
|
|
7945
9023
|
if (btnToolFilesModalClose) {
|
|
7946
9024
|
btnToolFilesModalClose.addEventListener('click', closeToolFilesModal)
|
|
7947
9025
|
}
|
|
@@ -7959,6 +9037,10 @@
|
|
|
7959
9037
|
}
|
|
7960
9038
|
document.addEventListener('keydown', function (ev) {
|
|
7961
9039
|
if (ev.key !== 'Escape') return
|
|
9040
|
+
if (agentSwitchOpen) {
|
|
9041
|
+
closeAgentSwitchMenu()
|
|
9042
|
+
return
|
|
9043
|
+
}
|
|
7962
9044
|
if (agentPickerModal && agentPickerModal.classList.contains('is-open')) {
|
|
7963
9045
|
closeAgentPickerModal()
|
|
7964
9046
|
return
|
|
@@ -7971,10 +9053,18 @@
|
|
|
7971
9053
|
closeAgentMdModal()
|
|
7972
9054
|
return
|
|
7973
9055
|
}
|
|
9056
|
+
if (skillMdModal && skillMdModal.classList.contains('is-open')) {
|
|
9057
|
+
closeSkillMdModal()
|
|
9058
|
+
return
|
|
9059
|
+
}
|
|
7974
9060
|
if (agentEnvModal && agentEnvModal.classList.contains('is-open')) {
|
|
7975
9061
|
closeAgentEnvModal()
|
|
7976
9062
|
return
|
|
7977
9063
|
}
|
|
9064
|
+
if (scheduleManageModal && scheduleManageModal.classList.contains('is-open')) {
|
|
9065
|
+
closeScheduleManageModal()
|
|
9066
|
+
return
|
|
9067
|
+
}
|
|
7978
9068
|
if (toolFilesModal && toolFilesModal.classList.contains('is-open')) {
|
|
7979
9069
|
closeToolFilesModal()
|
|
7980
9070
|
return
|
|
@@ -8025,6 +9115,37 @@
|
|
|
8025
9115
|
rewriteSameOriginNavLinks()
|
|
8026
9116
|
})
|
|
8027
9117
|
}
|
|
9118
|
+
if (brandAgentNameEl) {
|
|
9119
|
+
brandAgentNameEl.addEventListener('click', function (ev) {
|
|
9120
|
+
ev.preventDefault()
|
|
9121
|
+
ev.stopPropagation()
|
|
9122
|
+
void toggleAgentSwitchMenu()
|
|
9123
|
+
})
|
|
9124
|
+
}
|
|
9125
|
+
if (agentSwitchDropdownEl) {
|
|
9126
|
+
agentSwitchDropdownEl.addEventListener('click', function (ev) {
|
|
9127
|
+
ev.stopPropagation()
|
|
9128
|
+
})
|
|
9129
|
+
}
|
|
9130
|
+
document.addEventListener('click', function (ev) {
|
|
9131
|
+
if (!agentSwitchOpen) return
|
|
9132
|
+
const t = ev.target
|
|
9133
|
+
if (t instanceof Node) {
|
|
9134
|
+
if (agentSwitchWrapEl && agentSwitchWrapEl.contains(t)) return
|
|
9135
|
+
if (agentSwitchDropdownEl && agentSwitchDropdownEl.contains(t)) return
|
|
9136
|
+
}
|
|
9137
|
+
closeAgentSwitchMenu()
|
|
9138
|
+
})
|
|
9139
|
+
window.addEventListener('resize', function () {
|
|
9140
|
+
if (agentSwitchOpen) positionAgentSwitchDropdown()
|
|
9141
|
+
})
|
|
9142
|
+
window.addEventListener(
|
|
9143
|
+
'scroll',
|
|
9144
|
+
function () {
|
|
9145
|
+
if (agentSwitchOpen) positionAgentSwitchDropdown()
|
|
9146
|
+
},
|
|
9147
|
+
true
|
|
9148
|
+
)
|
|
8028
9149
|
|
|
8029
9150
|
updateBrandAgent()
|
|
8030
9151
|
rewriteSameOriginNavLinks()
|