@bitseek/hermes-webui 0.1.0-beta.0 → 0.1.0-beta.1
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 +2 -2
- package/vendor/agent-frontend-shell/.bitseek-source.json +2 -2
- package/vendor/agent-frontend-shell/CHANGELOG.md +178 -1
- package/vendor/agent-frontend-shell/CONTRIBUTORS.md +5 -5
- package/vendor/agent-frontend-shell/api/agent_health.py +134 -0
- package/vendor/agent-frontend-shell/api/config.py +145 -104
- package/vendor/agent-frontend-shell/api/gateway_chat.py +56 -12
- package/vendor/agent-frontend-shell/api/helpers.py +4 -2
- package/vendor/agent-frontend-shell/api/models.py +202 -20
- package/vendor/agent-frontend-shell/api/paths.py +77 -0
- package/vendor/agent-frontend-shell/api/plugins.py +185 -0
- package/vendor/agent-frontend-shell/api/profiles.py +95 -16
- package/vendor/agent-frontend-shell/api/routes.py +831 -30
- package/vendor/agent-frontend-shell/api/run_journal.py +1 -0
- package/vendor/agent-frontend-shell/api/state_sync.py +5 -4
- package/vendor/agent-frontend-shell/api/streaming.py +211 -56
- package/vendor/agent-frontend-shell/api/todo_state.py +122 -0
- package/vendor/agent-frontend-shell/api/updates.py +30 -3
- package/vendor/agent-frontend-shell/api/upload.py +251 -18
- package/vendor/agent-frontend-shell/api/workspace.py +323 -65
- package/vendor/agent-frontend-shell/bitseek_docs/BitSeek_Claw_Operation_Manual_EN.docx +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/BitSeek_Claw_Operation_Manual_ZH.docx +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/00-Installation.md +174 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/01-Overview.md +128 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/02-Page-Operations.md +461 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/README.md +61 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/ai-colleagues.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/chat-area.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/kanban.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/main-page.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-notes.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-overview.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-profile.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory-soul.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/memory.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/navigation-bar.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-appearance.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-conversation.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-overview.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-plugins.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-preferences.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-providers.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings-system.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/settings.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/sidebar.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/skills.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/tasks.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/en/images/workspace-panel.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/md_to_docx.py +351 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/00-/345/256/211/350/243/205/345/220/257/345/212/250.md +174 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/01-/346/225/264/344/275/223/346/246/202/350/247/210.md +128 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/02-/351/241/265/351/235/242/346/223/215/344/275/234.md +463 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/README.md +61 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/ai-colleagues.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/chat-area.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/kanban.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/main-page.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-notes.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-overview.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-profile.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory-soul.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/memory.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/navigation-bar.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-appearance.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-conversation.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-overview.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-plugins.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-preferences.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-providers.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings-system.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/settings.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/sidebar.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/skills.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/tasks.png +0 -0
- package/vendor/agent-frontend-shell/bitseek_docs/zh/images/workspace-panel.png +0 -0
- package/vendor/agent-frontend-shell/build-release.sh +62 -0
- package/vendor/agent-frontend-shell/ctl.sh +1 -0
- package/vendor/agent-frontend-shell/docker-compose.local.yml +33 -0
- package/vendor/agent-frontend-shell/docker-compose.yml +8 -0
- package/vendor/agent-frontend-shell/docker_init.bash +1 -0
- package/vendor/agent-frontend-shell/docs/rfcs/hermes-run-adapter-contract.md +74 -15
- package/vendor/agent-frontend-shell/extensions/common/index.css +6 -0
- package/vendor/agent-frontend-shell/extensions/manifest.json +6 -0
- package/vendor/agent-frontend-shell/extensions/pages/ai-teammates/page.js +60 -14
- package/vendor/agent-frontend-shell/readme-simple.md +103 -0
- package/vendor/agent-frontend-shell/requirements.txt +5 -0
- package/vendor/agent-frontend-shell/server.py +7 -0
- package/vendor/agent-frontend-shell/static/boot.js +53 -1
- package/vendor/agent-frontend-shell/static/commands.js +20 -10
- package/vendor/agent-frontend-shell/static/i18n.js +1142 -1016
- package/vendor/agent-frontend-shell/static/index.html +13 -3
- package/vendor/agent-frontend-shell/static/messages.js +48 -3
- package/vendor/agent-frontend-shell/static/panels.js +199 -30
- package/vendor/agent-frontend-shell/static/sessions.js +249 -39
- package/vendor/agent-frontend-shell/static/style.css +46 -2
- package/vendor/agent-frontend-shell/static/ui.js +323 -79
- package/vendor/agent-frontend-shell/static/workspace.js +185 -7
- package/vendor/agent-frontend-shell/README-CUSTOM.md +0 -76
- package/vendor/agent-frontend-shell/docker-compose.custom.yml +0 -26
|
@@ -268,12 +268,42 @@ function collectSessionArtifacts(){
|
|
|
268
268
|
if(!path || seen.has(path)) return;
|
|
269
269
|
seen.add(path); items.push({path, source});
|
|
270
270
|
};
|
|
271
|
+
// Source 1: session-level tool call summaries (may be empty when messages
|
|
272
|
+
// carry their own tool metadata — see _syncToolCallsForLoadedMessages).
|
|
271
273
|
for(const tc of (S.toolCalls || [])){
|
|
272
274
|
for(const a of _artifactCandidatesFromToolCall(tc)) push(a.path, a.kind || tc.name || 'tool');
|
|
273
275
|
}
|
|
276
|
+
// Source 2 & 3: message-level data — both text-mined diffs and structured
|
|
277
|
+
// tool_calls / tool_use content blocks that survive the S.toolCalls clear.
|
|
274
278
|
for(const msg of (S.messages || [])){
|
|
275
|
-
|
|
276
|
-
|
|
279
|
+
if(!msg) continue;
|
|
280
|
+
const text = msg.content || msg.text || msg.message || '';
|
|
281
|
+
// Text-mined diff/patch fences (existing path).
|
|
282
|
+
if(typeof text === 'string'){
|
|
283
|
+
for(const a of _artifactCandidatesFromText(text)) push(a.path, a.kind);
|
|
284
|
+
}
|
|
285
|
+
// Structured tool_calls array (OpenAI format: {function:{name,arguments}}).
|
|
286
|
+
if(Array.isArray(msg.tool_calls)){
|
|
287
|
+
for(const tc of msg.tool_calls){
|
|
288
|
+
if(!tc || typeof tc !== 'object') continue;
|
|
289
|
+
const fn = (tc.function && typeof tc.function === 'object') ? tc.function : tc;
|
|
290
|
+
const name = fn.name || tc.name || '';
|
|
291
|
+
let args = fn.arguments || tc.arguments || tc.args || tc.input || {};
|
|
292
|
+
if(typeof args === 'string'){ try{ args = JSON.parse(args); }catch(_){} }
|
|
293
|
+
const fakeTc = {name, args, result: tc.result || tc.output || ''};
|
|
294
|
+
for(const a of _artifactCandidatesFromToolCall(fakeTc)) push(a.path, a.kind || name || 'tool');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Structured content array with tool_use blocks (Anthropic format).
|
|
298
|
+
if(Array.isArray(msg.content)){
|
|
299
|
+
for(const block of msg.content){
|
|
300
|
+
if(!block || block.type !== 'tool_use') continue;
|
|
301
|
+
let inp = block.input || {};
|
|
302
|
+
if(typeof inp === 'string'){ try{ inp = JSON.parse(inp); }catch(_){} }
|
|
303
|
+
const fakeTc = {name: block.name || '', args: inp, result: block.result || ''};
|
|
304
|
+
for(const a of _artifactCandidatesFromToolCall(fakeTc)) push(a.path, a.kind || block.name || 'tool');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
277
307
|
}
|
|
278
308
|
return items.slice(0, 50);
|
|
279
309
|
}
|
|
@@ -292,7 +322,14 @@ function renderSessionArtifacts(){
|
|
|
292
322
|
root.innerHTML = '<div class="workspace-artifact-empty">No artifacts detected yet. Files created or edited during this session will appear here.</div>';
|
|
293
323
|
return;
|
|
294
324
|
}
|
|
295
|
-
|
|
325
|
+
// Strip workspace prefix for display so long absolute paths don't clutter the list.
|
|
326
|
+
const ws = S.session && S.session.workspace;
|
|
327
|
+
const normWs = ws ? ws.replace(/\/+$/,'') + '/' : '';
|
|
328
|
+
const displayPath = (p) => {
|
|
329
|
+
if(normWs && p.startsWith(normWs)) return p.slice(normWs.length);
|
|
330
|
+
return p;
|
|
331
|
+
};
|
|
332
|
+
root.innerHTML = items.map(item => `<button type="button" class="workspace-artifact-item" data-artifact-path="${esc(item.path)}" onclick="openArtifactPath(this.dataset.artifactPath)"><div class="workspace-artifact-path">${esc(displayPath(item.path))}</div><div class="workspace-artifact-meta">${esc(item.source || 'session')}</div></button>`).join('');
|
|
296
333
|
}
|
|
297
334
|
|
|
298
335
|
async function _workspacePathExists(path){
|
|
@@ -308,7 +345,15 @@ async function _workspacePathExists(path){
|
|
|
308
345
|
async function openArtifactPath(path){
|
|
309
346
|
if(!path) return;
|
|
310
347
|
switchWorkspacePanelTab('files');
|
|
311
|
-
|
|
348
|
+
let rel = path.replace(/^~\//,'').replace(/^\.\/+/,'');
|
|
349
|
+
// Strip workspace prefix so /api/list receives a workspace-relative path.
|
|
350
|
+
const ws = S.session && S.session.workspace;
|
|
351
|
+
if(ws){
|
|
352
|
+
const normWs = ws.replace(/\/+$/,'') + '/';
|
|
353
|
+
if(rel.startsWith(normWs)) rel = rel.slice(normWs.length);
|
|
354
|
+
else if(rel === ws.replace(/\/+$/,'')) rel = '.';
|
|
355
|
+
}
|
|
356
|
+
if(!rel) rel = '.';
|
|
312
357
|
try{
|
|
313
358
|
if(!(await _workspacePathExists(rel))){
|
|
314
359
|
setStatus(t('file_open_failed'));
|
|
@@ -528,6 +573,40 @@ function cancelEditMode(){
|
|
|
528
573
|
updateEditBtn();
|
|
529
574
|
}
|
|
530
575
|
|
|
576
|
+
// Map file extensions to Prism.js language identifiers.
|
|
577
|
+
// Prism autoloader fetches missing language components from CDN on demand.
|
|
578
|
+
const _PRISM_LANG_MAP={
|
|
579
|
+
js:'javascript',mjs:'javascript',jsx:'jsx',ts:'typescript',tsx:'tsx',
|
|
580
|
+
py:'python',pyw:'python',pyi:'python',
|
|
581
|
+
rb:'ruby',go:'go',rs:'rust',java:'java',kt:'kotlin',kts:'kotlin',
|
|
582
|
+
c:'c',h:'c',cpp:'cpp',cxx:'cpp',hpp:'cpp',cc:'cpp',
|
|
583
|
+
cs:'csharp',swift:'swift',scala:'scala',
|
|
584
|
+
php:'php',pl:'perl',pm:'perl',r:'r',lua:'lua',
|
|
585
|
+
sh:'bash',bash:'bash',zsh:'bash',fish:'bash',
|
|
586
|
+
ps1:'powershell',psm1:'powershell',
|
|
587
|
+
sql:'sql',graphql:'graphql',
|
|
588
|
+
json:'json',yaml:'yaml',yml:'yaml',toml:'toml',xml:'xml',
|
|
589
|
+
html:'markup',htm:'markup',svg:'markup',vue:'markup',
|
|
590
|
+
css:'css',scss:'scss',sass:'sass',less:'less',
|
|
591
|
+
md:'markdown',markdown:'markdown',
|
|
592
|
+
dockerfile:'docker',makefile:'makefile',cmake:'cmake',
|
|
593
|
+
ini:'ini',cfg:'ini',conf:'ini',properties:'properties',
|
|
594
|
+
diff:'diff',patch:'diff',
|
|
595
|
+
txt:'',log:'',csv:'',tsv:'',
|
|
596
|
+
};
|
|
597
|
+
const _PRISM_BASENAME_LANG_MAP={
|
|
598
|
+
'dockerfile':'docker','makefile':'makefile','gnumakefile':'makefile',
|
|
599
|
+
'cmakelists.txt':'cmake',
|
|
600
|
+
'.gitignore':'ignore','.dockerignore':'ignore',
|
|
601
|
+
};
|
|
602
|
+
function _prismLanguageForPath(path){
|
|
603
|
+
const base=String(path||'').split(/[\\/]/).pop().toLowerCase();
|
|
604
|
+
if(base.startsWith('dockerfile.')) return 'docker';
|
|
605
|
+
if(_PRISM_BASENAME_LANG_MAP[base]!==undefined) return _PRISM_BASENAME_LANG_MAP[base];
|
|
606
|
+
const ext=fileExt(path).replace(/^\./,'');
|
|
607
|
+
return _PRISM_LANG_MAP[ext]!==undefined?_PRISM_LANG_MAP[ext]:'plaintext';
|
|
608
|
+
}
|
|
609
|
+
|
|
531
610
|
async function openFile(path, opts={}){
|
|
532
611
|
if(!S.session)return;
|
|
533
612
|
const ext=fileExt(path);
|
|
@@ -614,7 +693,26 @@ async function openFile(path, opts={}){
|
|
|
614
693
|
return;
|
|
615
694
|
}
|
|
616
695
|
showPreview('code');
|
|
617
|
-
|
|
696
|
+
// Syntax highlighting with Prism.js (already loaded on the page).
|
|
697
|
+
const codeEl=document.createElement('code');
|
|
698
|
+
codeEl.textContent=data.content;
|
|
699
|
+
const lang=_prismLanguageForPath(path);
|
|
700
|
+
if(lang) codeEl.className='language-'+lang;
|
|
701
|
+
const pre=$('previewCode');
|
|
702
|
+
pre.textContent='';
|
|
703
|
+
// Prism.highlightElement() propagates the language-* class onto the
|
|
704
|
+
// parent <pre>, so a previously-previewed code file leaves e.g.
|
|
705
|
+
// "language-css" on #previewCode. A subsequent plain-text file builds a
|
|
706
|
+
// class-less <code>, and Prism walks up to that stale ancestor class and
|
|
707
|
+
// mis-highlights prose. Strip any inherited language-* token from the
|
|
708
|
+
// <pre> before each render so highlighting never leaks across files.
|
|
709
|
+
pre.className=pre.className.replace(/\blanguage-\S+/g,'').replace(/\s+/g,' ').trim();
|
|
710
|
+
pre.appendChild(codeEl);
|
|
711
|
+
// Only invoke Prism when we actually assigned a language; otherwise the
|
|
712
|
+
// class-less <code> would inherit any ancestor language-* class.
|
|
713
|
+
if(lang&&typeof Prism!=='undefined'&&typeof Prism.highlightElement==='function'){
|
|
714
|
+
Prism.highlightElement(codeEl);
|
|
715
|
+
}
|
|
618
716
|
}catch(e){
|
|
619
717
|
// If it's a 400/too-large error, offer download instead
|
|
620
718
|
downloadFile(path);
|
|
@@ -675,6 +773,86 @@ function renderFileBreadcrumb(filePath) {
|
|
|
675
773
|
|
|
676
774
|
function openInBrowser(){
|
|
677
775
|
if(!_previewCurrentPath||!S.session) return;
|
|
678
|
-
const url=`api/file/raw?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(_previewCurrentPath)}`;
|
|
679
|
-
window.open(url,'_blank');
|
|
776
|
+
const url=`api/file/raw?session_id=${encodeURIComponent(S.session.session_id)}&path=${encodeURIComponent(_previewCurrentPath)}&inline=1`;
|
|
777
|
+
window.open(url,'_blank','noopener');
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// ── Workspace upload ──────────────────────────────────────────────────
|
|
781
|
+
function triggerWorkspaceUpload() {
|
|
782
|
+
const input = $('workspaceFileInput');
|
|
783
|
+
if (!input) return;
|
|
784
|
+
input.value = '';
|
|
785
|
+
input.onchange = async () => {
|
|
786
|
+
const files = input.files;
|
|
787
|
+
if (!files || !files.length) return;
|
|
788
|
+
for (const file of files) {
|
|
789
|
+
await uploadToWorkspace(file, S.currentDir || '.');
|
|
790
|
+
}
|
|
791
|
+
if (S.session) loadDir(S.currentDir);
|
|
792
|
+
};
|
|
793
|
+
input.click();
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
async function uploadToWorkspace(file, dir) {
|
|
797
|
+
if (!S.session) return;
|
|
798
|
+
const formData = new FormData();
|
|
799
|
+
formData.append('session_id', S.session.session_id);
|
|
800
|
+
formData.append('path', dir || '.');
|
|
801
|
+
formData.append('file', file, file.name);
|
|
802
|
+
try {
|
|
803
|
+
showToast(t('uploading') || 'Uploading\u2026', 2000);
|
|
804
|
+
const data = await api('/api/workspace/upload', {
|
|
805
|
+
method: 'POST',
|
|
806
|
+
body: formData,
|
|
807
|
+
headers: {},
|
|
808
|
+
timeoutMs: 120000,
|
|
809
|
+
});
|
|
810
|
+
if (data && data.error) {
|
|
811
|
+
showToast(data.error, 5000, 'error');
|
|
812
|
+
} else if (data && (data.extract_error || (Array.isArray(data.files) && data.files.some(function(f){return f && f.extract_error;})))) {
|
|
813
|
+
// Archive was rejected (zip-slip / zip-bomb / corrupt / too-many-members):
|
|
814
|
+
// the file uploaded but extraction failed. Surface it as an error instead
|
|
815
|
+
// of a misleading "Uploaded" success toast.
|
|
816
|
+
var msg = data.extract_error
|
|
817
|
+
|| (data.files.find(function(f){return f && f.extract_error;}) || {}).extract_error
|
|
818
|
+
|| 'Archive extraction failed';
|
|
819
|
+
showToast(msg, 5000, 'error');
|
|
820
|
+
} else {
|
|
821
|
+
showToast(t('uploaded') || ('Uploaded ' + (data.filename || file.name)), 2000);
|
|
822
|
+
}
|
|
823
|
+
} catch (e) {
|
|
824
|
+
showToast(t('upload_failed') || ('Upload failed: ' + e.message), 5000, 'error');
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// Drag-and-drop files onto workspace file tree
|
|
829
|
+
if (typeof document !== 'undefined') {
|
|
830
|
+
const _wsUploadInit = () => {
|
|
831
|
+
const tree = $('fileTree');
|
|
832
|
+
if (!tree) return;
|
|
833
|
+
tree.addEventListener('dragover', (e) => {
|
|
834
|
+
if (e.dataTransfer && e.dataTransfer.types && e.dataTransfer.types.includes('Files')) {
|
|
835
|
+
e.preventDefault();
|
|
836
|
+
e.dataTransfer.dropEffect = 'copy';
|
|
837
|
+
tree.classList.add('drag-over-upload');
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
tree.addEventListener('dragleave', () => {
|
|
841
|
+
tree.classList.remove('drag-over-upload');
|
|
842
|
+
});
|
|
843
|
+
tree.addEventListener('drop', async (e) => {
|
|
844
|
+
tree.classList.remove('drag-over-upload');
|
|
845
|
+
if (!e.dataTransfer || !e.dataTransfer.types || !e.dataTransfer.types.includes('Files')) return;
|
|
846
|
+
e.preventDefault();
|
|
847
|
+
for (const file of e.dataTransfer.files) {
|
|
848
|
+
await uploadToWorkspace(file, S.currentDir || '.');
|
|
849
|
+
}
|
|
850
|
+
if (S.session) loadDir(S.currentDir);
|
|
851
|
+
});
|
|
852
|
+
};
|
|
853
|
+
if (document.readyState === 'loading') {
|
|
854
|
+
document.addEventListener('DOMContentLoaded', _wsUploadInit, {once: true});
|
|
855
|
+
} else {
|
|
856
|
+
_wsUploadInit();
|
|
857
|
+
}
|
|
680
858
|
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# Hermes WebUI 定制版
|
|
2
|
-
|
|
3
|
-
这是 Hermes WebUI 的定制版本,包含优化的用户界面和增强功能。
|
|
4
|
-
|
|
5
|
-
## 🚀 一键安装 (推荐)
|
|
6
|
-
|
|
7
|
-
### Linux / macOS 用户
|
|
8
|
-
```bash
|
|
9
|
-
curl -fsSL https://your-domain.com/install.sh | bash
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
### Windows 用户
|
|
13
|
-
请使用 WSL2 或虚拟机,然后运行上面的命令
|
|
14
|
-
|
|
15
|
-
## 📦 手动安装
|
|
16
|
-
|
|
17
|
-
如果一键安装失败,可以手动安装:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# 1. 克隆项目
|
|
21
|
-
git clone -b dev-zkp https://github.com/yourusername/hermes-webui.git
|
|
22
|
-
cd hermes-webui
|
|
23
|
-
|
|
24
|
-
# 2. 运行自动安装
|
|
25
|
-
python3 bootstrap.py
|
|
26
|
-
|
|
27
|
-
# 3. 启动服务
|
|
28
|
-
./start.sh
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## 🎯 使用方法
|
|
32
|
-
|
|
33
|
-
1. 安装完成后,访问 http://localhost:8787
|
|
34
|
-
2. 首次使用需要配置 AI 提供商:
|
|
35
|
-
- OpenAI、Anthropic、Google 等
|
|
36
|
-
- 在设置中添加 API 密钥
|
|
37
|
-
3. 开始聊天使用
|
|
38
|
-
|
|
39
|
-
## ✨ 定制功能
|
|
40
|
-
|
|
41
|
-
- 🎨 全新设计主题
|
|
42
|
-
- 🖼️ 定制 logo 和图标
|
|
43
|
-
- 📱 优化的移动端体验
|
|
44
|
-
- 🔧 增强的扩展系统
|
|
45
|
-
- ⚡ 性能优化
|
|
46
|
-
|
|
47
|
-
## 🔧 系统要求
|
|
48
|
-
|
|
49
|
-
- **操作系统**: Linux, macOS, 或 WSL2
|
|
50
|
-
- **Python**: 3.11 或更高版本
|
|
51
|
-
- **内存**: 建议 2GB 以上
|
|
52
|
-
- **网络**: 需要访问 AI 提供商 API
|
|
53
|
-
|
|
54
|
-
## 🆘 常见问题
|
|
55
|
-
|
|
56
|
-
### Q: 安装失败怎么办?
|
|
57
|
-
A: 检查 Python 版本,确保有网络连接,或尝试手动安装
|
|
58
|
-
|
|
59
|
-
### Q: 如何更新?
|
|
60
|
-
A: 进入安装目录,运行 `git pull` 然后重启服务
|
|
61
|
-
|
|
62
|
-
### Q: 忘记密码怎么办?
|
|
63
|
-
A: 删除 `~/.hermes/webui/settings.json` 文件,重新设置
|
|
64
|
-
|
|
65
|
-
### Q: 如何备份数据?
|
|
66
|
-
A: 备份 `~/.hermes` 目录
|
|
67
|
-
|
|
68
|
-
## 📞 技术支持
|
|
69
|
-
|
|
70
|
-
- 📧 邮箱: your-email@example.com
|
|
71
|
-
- 💬 微信群: [扫码加入]
|
|
72
|
-
- 🐛 问题反馈: https://github.com/yourusername/hermes-webui/issues
|
|
73
|
-
|
|
74
|
-
## 📄 许可证
|
|
75
|
-
|
|
76
|
-
MIT License - 详见 LICENSE 文件
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
version: '3.8'
|
|
2
|
-
|
|
3
|
-
services:
|
|
4
|
-
hermes-webui-custom:
|
|
5
|
-
image: ghcr.io/yourusername/hermes-webui:custom
|
|
6
|
-
container_name: hermes-webui-custom
|
|
7
|
-
restart: unless-stopped
|
|
8
|
-
ports:
|
|
9
|
-
- "127.0.0.1:8787:8787"
|
|
10
|
-
environment:
|
|
11
|
-
- HERMES_WEBUI_HOST=0.0.0.0
|
|
12
|
-
- HERMES_WEBUI_PASSWORD=${HERMES_WEBUI_PASSWORD:-}
|
|
13
|
-
- WANTED_UID=${UID:-1000}
|
|
14
|
-
- WANTED_GID=${GID:-1000}
|
|
15
|
-
volumes:
|
|
16
|
-
- hermes-data:/home/hermeswebui/.hermes
|
|
17
|
-
- ${HOME}/workspace:/workspace
|
|
18
|
-
healthcheck:
|
|
19
|
-
test: ["CMD", "curl", "-f", "http://127.0.0.1:8787/health"]
|
|
20
|
-
interval: 30s
|
|
21
|
-
timeout: 10s
|
|
22
|
-
retries: 3
|
|
23
|
-
|
|
24
|
-
volumes:
|
|
25
|
-
hermes-data:
|
|
26
|
-
driver: local
|