Files
Hermes-ui/src/api/chat.ts
T
ekkoandClaude Opus 4.6 5887462f7d feat: add model selector, skills/memory pages, and config management
- Add model selector in sidebar that discovers models from auth.json credential pool
- Add per-session model display (badge in chat header and session list)
- Add skills browser page and memory editor page
- Add BFF routes for skills, memory, and config model management
- Model switching updates config.yaml provider field to bypass env auto-detection
- Refactor Settings page, simplify ChatInput with file upload
- Add attachment upload support via BFF /upload endpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 23:23:50 +08:00

89 lines
1.8 KiB
TypeScript

import { request, getBaseUrlValue } from './client'
export interface ChatMessage {
role: 'user' | 'assistant' | 'system'
content: string
}
export interface StartRunRequest {
input: string | ChatMessage[]
instructions?: string
conversation_history?: ChatMessage[]
session_id?: string
model?: string
}
export interface StartRunResponse {
run_id: string
status: string
}
// SSE event types from /v1/runs/{id}/events
export interface RunEvent {
event: string
run_id?: string
delta?: string
tool?: string
name?: string
preview?: string
timestamp?: number
error?: string
}
export async function startRun(body: StartRunRequest): Promise<StartRunResponse> {
return request<StartRunResponse>('/v1/runs', {
method: 'POST',
body: JSON.stringify(body),
})
}
export function streamRunEvents(
runId: string,
onEvent: (event: RunEvent) => void,
onDone: () => void,
onError: (err: Error) => void,
) {
const baseUrl = getBaseUrlValue()
const url = `${baseUrl}/v1/runs/${runId}/events`
let closed = false
const source = new EventSource(url)
source.onmessage = (e) => {
if (closed) return
try {
const parsed = JSON.parse(e.data)
onEvent(parsed)
if (parsed.event === 'run.completed' || parsed.event === 'run.failed') {
closed = true
source.close()
onDone()
}
} catch {
onEvent({ event: 'message', delta: e.data })
}
}
source.onerror = () => {
if (closed) return
closed = true
source.close()
onError(new Error('SSE connection error'))
}
// Return AbortController-compatible object
return {
abort: () => {
if (!closed) {
closed = true
source.close()
}
},
} as unknown as AbortController
}
export async function fetchModels(): Promise<{ data: Array<{ id: string }> }> {
return request('/v1/models')
}