diff --git a/packages/client/src/api/hermes/profiles.ts b/packages/client/src/api/hermes/profiles.ts new file mode 100644 index 0000000..2073966 --- /dev/null +++ b/packages/client/src/api/hermes/profiles.ts @@ -0,0 +1,113 @@ +import { request, getBaseUrlValue, getApiKey } from '../client' + +export interface HermesProfile { + name: string + active: boolean + model: string + gateway: string + alias: string +} + +export interface HermesProfileDetail { + name: string + path: string + model: string + provider: string + gateway: string + skills: number + hasEnv: boolean + hasSoulMd: boolean +} + +export async function fetchProfiles(): Promise { + const res = await request<{ profiles: HermesProfile[] }>('/api/hermes/profiles') + return res.profiles +} + +export async function fetchProfileDetail(name: string): Promise { + const res = await request<{ profile: HermesProfileDetail }>(`/api/hermes/profiles/${encodeURIComponent(name)}`) + return res.profile +} + +export async function createProfile(name: string, clone?: boolean): Promise { + try { + await request('/api/hermes/profiles', { + method: 'POST', + body: JSON.stringify({ name, clone }), + }) + return true + } catch { + return false + } +} + +export async function deleteProfile(name: string): Promise { + try { + await request(`/api/hermes/profiles/${encodeURIComponent(name)}`, { method: 'DELETE' }) + return true + } catch { + return false + } +} + +export async function renameProfile(name: string, newName: string): Promise { + try { + await request(`/api/hermes/profiles/${encodeURIComponent(name)}/rename`, { + method: 'POST', + body: JSON.stringify({ new_name: newName }), + }) + return true + } catch { + return false + } +} + +export async function switchProfile(name: string): Promise { + try { + await request('/api/hermes/profiles/active', { + method: 'PUT', + body: JSON.stringify({ name }), + }) + return true + } catch { + return false + } +} + +export async function exportProfile(name: string): Promise { + try { + const baseUrl = getBaseUrlValue() + const token = getApiKey() + const headers: Record = {} + if (token) headers['Authorization'] = `Bearer ${token}` + + const res = await fetch(`${baseUrl}/api/hermes/profiles/${encodeURIComponent(name)}/export`, { + method: 'POST', + headers, + }) + if (!res.ok) throw new Error() + + const blob = await res.blob() + const url = URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = `hermes-profile-${name}.tar.gz` + a.click() + URL.revokeObjectURL(url) + return true + } catch { + return false + } +} + +export async function importProfile(archive: string, name?: string): Promise { + try { + await request('/api/hermes/profiles/import', { + method: 'POST', + body: JSON.stringify({ archive, name }), + }) + return true + } catch { + return false + } +} diff --git a/packages/client/src/components/hermes/profiles/ProfileCard.vue b/packages/client/src/components/hermes/profiles/ProfileCard.vue new file mode 100644 index 0000000..ce9ef52 --- /dev/null +++ b/packages/client/src/components/hermes/profiles/ProfileCard.vue @@ -0,0 +1,290 @@ + + + + + diff --git a/packages/client/src/components/hermes/profiles/ProfileCreateModal.vue b/packages/client/src/components/hermes/profiles/ProfileCreateModal.vue new file mode 100644 index 0000000..1b23f11 --- /dev/null +++ b/packages/client/src/components/hermes/profiles/ProfileCreateModal.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/packages/client/src/components/hermes/profiles/ProfileImportModal.vue b/packages/client/src/components/hermes/profiles/ProfileImportModal.vue new file mode 100644 index 0000000..d9d3f94 --- /dev/null +++ b/packages/client/src/components/hermes/profiles/ProfileImportModal.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/packages/client/src/components/hermes/profiles/ProfileRenameModal.vue b/packages/client/src/components/hermes/profiles/ProfileRenameModal.vue new file mode 100644 index 0000000..aa09dbb --- /dev/null +++ b/packages/client/src/components/hermes/profiles/ProfileRenameModal.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/packages/client/src/components/hermes/profiles/ProfilesPanel.vue b/packages/client/src/components/hermes/profiles/ProfilesPanel.vue new file mode 100644 index 0000000..2a1e3e9 --- /dev/null +++ b/packages/client/src/components/hermes/profiles/ProfilesPanel.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/packages/client/src/components/layout/AppSidebar.vue b/packages/client/src/components/layout/AppSidebar.vue index a0ef8e7..0f3d5fd 100644 --- a/packages/client/src/components/layout/AppSidebar.vue +++ b/packages/client/src/components/layout/AppSidebar.vue @@ -147,6 +147,27 @@ function handleNav(key: string) { {{ t("sidebar.models") }} + +