refactor: restructure project for multi-agent extensibility

- Migrate source to packages/client and packages/server directories
- Namespace all Hermes-specific code under hermes/ subdirectories
  (api/hermes/, components/hermes/, views/hermes/, stores/hermes/)
- Add hermes.* route names and /hermes/* path prefixes
- Upgrade @koa/router to v15, adapt path-to-regexp v8 syntax
- Fix proxy path rewriting: /api/hermes/v1/* → /v1/*, /api/hermes/* → /api/*
- Fix frontend API paths to match backend /api/hermes/* routes
- Fix WebSocket terminal path to /api/hermes/terminal
- Add proxyMiddleware for reliable unmatched route proxying
- Add profiles route module and hermes-cli profile commands
- Update CLAUDE.md development guide with new architecture
- Add Chinese README (README_zh.md)
- Add Web Terminal feature to README

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-04-16 08:38:18 +08:00
parent 4917242dca
commit 351c861777
106 changed files with 1409 additions and 317 deletions
+79
View File
@@ -0,0 +1,79 @@
import { request } from '../client'
export interface HealthResponse {
status: string
version?: string
}
// Config-based model types
export interface ModelInfo {
id: string
label: string
}
export interface ModelGroup {
provider: string
models: ModelInfo[]
}
export interface ConfigModelsResponse {
default: string
groups: ModelGroup[]
}
export interface AvailableModelGroup {
provider: string // credential pool key (e.g. "zai", "custom:subrouter.ai")
label: string // display name (e.g. "zai", "subrouter.ai")
base_url: string
models: string[]
}
export interface AvailableModelsResponse {
default: string
groups: AvailableModelGroup[]
}
export interface CustomProvider {
name: string
base_url: string
api_key: string
model: string
providerKey?: string | null
}
export async function checkHealth(): Promise<HealthResponse> {
return request<HealthResponse>('/health')
}
export async function fetchConfigModels(): Promise<ConfigModelsResponse> {
return request<ConfigModelsResponse>('/api/hermes/config/models')
}
export async function fetchAvailableModels(): Promise<AvailableModelsResponse> {
return request<AvailableModelsResponse>('/api/hermes/available-models')
}
export async function updateDefaultModel(data: {
default: string
provider?: string
base_url?: string
api_key?: string
}): Promise<void> {
await request('/api/hermes/config/model', {
method: 'PUT',
body: JSON.stringify(data),
})
}
export async function addCustomProvider(data: CustomProvider): Promise<void> {
await request('/api/hermes/config/providers', {
method: 'POST',
body: JSON.stringify(data),
})
}
export async function removeCustomProvider(name: string): Promise<void> {
await request(`/api/hermes/config/providers/${encodeURIComponent(name)}`, {
method: 'DELETE',
})
}