agentgui 1.0.771 → 1.0.773
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/package.json +1 -1
- package/server.js +3 -6
- package/static/app.js +62 -0
- package/static/css/main.css +33 -0
- package/static/index.html +9 -0
- package/static/js/conversations.js +38 -0
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -84,12 +84,9 @@ function buildSystemPrompt(agentId, model, subAgent) {
|
|
|
84
84
|
const displayAgentId = agentId.split('-·-')[0];
|
|
85
85
|
parts.push(`Use ${displayAgentId} subagent for all tasks.`);
|
|
86
86
|
}
|
|
87
|
-
if (model) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (subAgent) {
|
|
91
|
-
parts.push(`Subagent: ${subAgent}.`);
|
|
92
|
-
}
|
|
87
|
+
if (model) parts.push(`Model: ${model}.`);
|
|
88
|
+
if (subAgent) parts.push(`Subagent: ${subAgent}.`);
|
|
89
|
+
parts.push('Be concise. Minimize unnecessary tool calls. Read files before editing. Prefer targeted searches over broad exploration.');
|
|
93
90
|
return parts.join(' ');
|
|
94
91
|
}
|
|
95
92
|
|
package/static/app.js
CHANGED
|
@@ -903,4 +903,66 @@ document.addEventListener('keydown', (e) => {
|
|
|
903
903
|
});
|
|
904
904
|
})();
|
|
905
905
|
|
|
906
|
+
(function initPresets() {
|
|
907
|
+
const STORAGE_KEY = 'agentgui-presets';
|
|
908
|
+
const saveBtn = document.getElementById('savePresetBtn');
|
|
909
|
+
const selector = document.getElementById('presetSelector');
|
|
910
|
+
if (!saveBtn || !selector) return;
|
|
911
|
+
|
|
912
|
+
function getPresets() {
|
|
913
|
+
try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'); } catch { return []; }
|
|
914
|
+
}
|
|
915
|
+
function savePresets(p) { localStorage.setItem(STORAGE_KEY, JSON.stringify(p)); }
|
|
916
|
+
|
|
917
|
+
function renderSelector() {
|
|
918
|
+
const presets = getPresets();
|
|
919
|
+
if (presets.length === 0) { selector.style.display = 'none'; return; }
|
|
920
|
+
selector.style.display = 'inline-block';
|
|
921
|
+
selector.innerHTML = '<option value="">Presets</option>' +
|
|
922
|
+
presets.map((p, i) => `<option value="${i}">${window._escHtml(p.name)}</option>`).join('') +
|
|
923
|
+
'<option value="__clear">Clear all</option>';
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
saveBtn.addEventListener('click', () => {
|
|
927
|
+
const cli = document.querySelector('[data-cli-selector]');
|
|
928
|
+
const agent = document.querySelector('[data-agent-selector]');
|
|
929
|
+
const model = document.querySelector('[data-model-selector]');
|
|
930
|
+
const cliVal = cli?.value || '';
|
|
931
|
+
const agentVal = agent?.value || '';
|
|
932
|
+
const modelVal = model?.value || '';
|
|
933
|
+
if (!cliVal) return;
|
|
934
|
+
const parts = [cliVal.split('-').pop()];
|
|
935
|
+
if (agentVal) parts.push(agentVal.split('/').pop());
|
|
936
|
+
if (modelVal) parts.push(modelVal.split('/').pop().split('-')[0]);
|
|
937
|
+
const name = prompt('Preset name:', parts.join(' / '));
|
|
938
|
+
if (!name) return;
|
|
939
|
+
const presets = getPresets();
|
|
940
|
+
presets.push({ name, cli: cliVal, agent: agentVal, model: modelVal });
|
|
941
|
+
savePresets(presets);
|
|
942
|
+
renderSelector();
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
selector.addEventListener('change', () => {
|
|
946
|
+
const val = selector.value;
|
|
947
|
+
if (val === '__clear') { savePresets([]); renderSelector(); return; }
|
|
948
|
+
if (!val) return;
|
|
949
|
+
const presets = getPresets();
|
|
950
|
+
const preset = presets[parseInt(val)];
|
|
951
|
+
if (!preset) return;
|
|
952
|
+
const cli = document.querySelector('[data-cli-selector]');
|
|
953
|
+
const agent = document.querySelector('[data-agent-selector]');
|
|
954
|
+
const model = document.querySelector('[data-model-selector]');
|
|
955
|
+
if (cli && preset.cli) { cli.value = preset.cli; cli.dispatchEvent(new Event('change')); }
|
|
956
|
+
setTimeout(() => {
|
|
957
|
+
if (agent && preset.agent) { agent.value = preset.agent; agent.dispatchEvent(new Event('change')); }
|
|
958
|
+
setTimeout(() => {
|
|
959
|
+
if (model && preset.model) { model.value = preset.model; model.dispatchEvent(new Event('change')); }
|
|
960
|
+
}, 500);
|
|
961
|
+
}, 500);
|
|
962
|
+
selector.value = '';
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
renderSelector();
|
|
966
|
+
})();
|
|
967
|
+
|
|
906
968
|
window.addEventListener('load', initializeApp);
|
package/static/css/main.css
CHANGED
|
@@ -275,6 +275,18 @@
|
|
|
275
275
|
overflow: hidden;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
.conversation-item-checkbox {
|
|
279
|
+
flex-shrink: 0;
|
|
280
|
+
width: 16px;
|
|
281
|
+
height: 16px;
|
|
282
|
+
opacity: 0;
|
|
283
|
+
cursor: pointer;
|
|
284
|
+
margin: 0;
|
|
285
|
+
}
|
|
286
|
+
.conversation-item:hover .conversation-item-checkbox,
|
|
287
|
+
.conversation-item-checkbox:checked {
|
|
288
|
+
opacity: 1;
|
|
289
|
+
}
|
|
278
290
|
.conversation-item-delete,
|
|
279
291
|
.conversation-item-archive,
|
|
280
292
|
.conversation-item-export {
|
|
@@ -3182,4 +3194,25 @@
|
|
|
3182
3194
|
from { transform: translateX(100%); opacity: 0; }
|
|
3183
3195
|
to { transform: translateX(0); opacity: 1; }
|
|
3184
3196
|
}
|
|
3197
|
+
|
|
3198
|
+
.preset-btn {
|
|
3199
|
+
background: transparent;
|
|
3200
|
+
border: 1px solid var(--color-border);
|
|
3201
|
+
border-radius: 0.25rem;
|
|
3202
|
+
cursor: pointer;
|
|
3203
|
+
color: var(--color-text-secondary);
|
|
3204
|
+
font-size: 0.875rem;
|
|
3205
|
+
padding: 0.25rem 0.5rem;
|
|
3206
|
+
line-height: 1;
|
|
3207
|
+
}
|
|
3208
|
+
.preset-btn:hover { color: #f59e0b; }
|
|
3209
|
+
.preset-selector {
|
|
3210
|
+
font-size: 0.75rem;
|
|
3211
|
+
padding: 0.25rem;
|
|
3212
|
+
border: 1px solid var(--color-border);
|
|
3213
|
+
border-radius: 0.25rem;
|
|
3214
|
+
background: var(--color-bg);
|
|
3215
|
+
color: var(--color-text);
|
|
3216
|
+
max-width: 120px;
|
|
3217
|
+
}
|
|
3185
3218
|
|
package/static/index.html
CHANGED
|
@@ -49,6 +49,11 @@
|
|
|
49
49
|
<button class="clone-go-btn" id="cloneGoBtn" title="Clone">Go</button>
|
|
50
50
|
<button class="clone-cancel-btn" id="cloneCancelBtn" title="Cancel">×</button>
|
|
51
51
|
</div>
|
|
52
|
+
<div class="bulk-action-bar" id="bulkActionBar" style="display:none;padding:0.375rem 0.75rem;background:var(--color-primary);display:none;gap:0.5rem;align-items:center;">
|
|
53
|
+
<span id="bulkCount" style="color:white;font-size:0.75rem;flex:1;">0 selected</span>
|
|
54
|
+
<button id="bulkArchiveBtn" style="background:rgba(255,255,255,0.2);color:white;border:none;border-radius:0.25rem;padding:0.25rem 0.5rem;font-size:0.75rem;cursor:pointer;">Archive</button>
|
|
55
|
+
<button id="bulkDeleteBtn" style="background:rgba(255,255,255,0.2);color:white;border:none;border-radius:0.25rem;padding:0.25rem 0.5rem;font-size:0.75rem;cursor:pointer;">Delete</button>
|
|
56
|
+
</div>
|
|
52
57
|
<ul class="sidebar-list" data-conversation-list role="listbox" aria-label="Conversations">
|
|
53
58
|
<li class="sidebar-empty" data-conversation-empty>Loading...</li>
|
|
54
59
|
</ul>
|
|
@@ -183,6 +188,10 @@
|
|
|
183
188
|
<select class="agent-selector cli-selector" data-cli-selector title="Select CLI tool"></select>
|
|
184
189
|
<select class="agent-selector sub-agent-selector" data-agent-selector title="Select sub-agent" style="display:none"></select>
|
|
185
190
|
<select class="model-selector" data-model-selector title="Select model" data-empty="true"></select>
|
|
191
|
+
<div class="preset-controls" style="display:inline-flex;gap:0.25rem;margin-left:0.25rem;">
|
|
192
|
+
<select id="presetSelector" class="preset-selector" title="Load preset" style="display:none;"></select>
|
|
193
|
+
<button id="savePresetBtn" class="preset-btn" title="Save current agent/model as preset">★</button>
|
|
194
|
+
</div>
|
|
186
195
|
<div class="message-input-container">
|
|
187
196
|
<textarea
|
|
188
197
|
class="message-textarea"
|
|
@@ -116,6 +116,19 @@ class ConversationManager {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
setupDelegatedListeners() {
|
|
119
|
+
const bulkBar = document.getElementById('bulkActionBar');
|
|
120
|
+
const bulkCount = document.getElementById('bulkCount');
|
|
121
|
+
const updateBulkBar = () => {
|
|
122
|
+
const checked = this.getSelectedIds().length;
|
|
123
|
+
if (bulkBar) bulkBar.style.display = checked > 0 ? 'flex' : 'none';
|
|
124
|
+
if (bulkCount) bulkCount.textContent = `${checked} selected`;
|
|
125
|
+
};
|
|
126
|
+
this.listEl.addEventListener('change', (e) => {
|
|
127
|
+
if (e.target.matches('.conversation-item-checkbox')) updateBulkBar();
|
|
128
|
+
});
|
|
129
|
+
document.getElementById('bulkArchiveBtn')?.addEventListener('click', () => this.bulkArchive());
|
|
130
|
+
document.getElementById('bulkDeleteBtn')?.addEventListener('click', () => this.bulkDelete());
|
|
131
|
+
|
|
119
132
|
this.listEl.addEventListener('click', (e) => {
|
|
120
133
|
const exportBtn = e.target.closest('[data-export-conv]');
|
|
121
134
|
if (exportBtn) {
|
|
@@ -489,6 +502,7 @@ class ConversationManager {
|
|
|
489
502
|
h('div', { class: 'conversation-item-title' }, ...(badge ? [badge, title] : [title])),
|
|
490
503
|
h('div', { class: 'conversation-item-meta' }, metaParts.join(' \u2022 '))
|
|
491
504
|
),
|
|
505
|
+
h('input', { type: 'checkbox', class: 'conversation-item-checkbox', 'data-bulk-check': conv.id, title: 'Select for bulk action', onclick: 'event.stopPropagation()' }),
|
|
492
506
|
h('button', { class: 'conversation-item-export', title: 'Export as markdown', 'data-export-conv': conv.id },
|
|
493
507
|
h('svg', { width: '14', height: '14', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': '2' },
|
|
494
508
|
h('path', { d: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4' }),
|
|
@@ -610,6 +624,30 @@ class ConversationManager {
|
|
|
610
624
|
this.render();
|
|
611
625
|
}
|
|
612
626
|
|
|
627
|
+
getSelectedIds() {
|
|
628
|
+
return [...this.listEl.querySelectorAll('.conversation-item-checkbox:checked')].map(cb => cb.dataset.bulkCheck);
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
async bulkArchive() {
|
|
632
|
+
const ids = this.getSelectedIds();
|
|
633
|
+
if (ids.length === 0) return;
|
|
634
|
+
if (!await window.UIDialog?.confirm(`Archive ${ids.length} conversation(s)?`, 'Bulk Archive')) return;
|
|
635
|
+
const base = window.__BASE_URL || '';
|
|
636
|
+
for (const id of ids) {
|
|
637
|
+
try { await fetch(`${base}/api/conversations/${id}/archive`, { method: 'POST' }); } catch (_) {}
|
|
638
|
+
this.deleteConversation(id);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
async bulkDelete() {
|
|
643
|
+
const ids = this.getSelectedIds();
|
|
644
|
+
if (ids.length === 0) return;
|
|
645
|
+
if (!await window.UIDialog?.confirm(`Permanently delete ${ids.length} conversation(s)?`, 'Bulk Delete')) return;
|
|
646
|
+
for (const id of ids) {
|
|
647
|
+
this.confirmDelete(id, '');
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
613
651
|
async exportConversation(convId) {
|
|
614
652
|
try {
|
|
615
653
|
const result = await window.wsClient.rpc('conv.export', { id: convId, format: 'markdown' });
|