You've already forked agentic-coding-workflow
feat(web): acp api sessions + WS factory (?token= auth)
This commit is contained in:
@@ -47,6 +47,54 @@ export interface UpdateAgentKindReq {
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
// AcpSession mirrors the backend session DTO returned by /api/v1/acp/sessions.
|
||||
export interface AcpSession {
|
||||
id: string
|
||||
workspace_id: string
|
||||
project_id: string
|
||||
agent_kind_id: string
|
||||
user_id: string
|
||||
issue_id: string | null
|
||||
requirement_id: string | null
|
||||
agent_session_id: string | null
|
||||
branch: string
|
||||
cwd_path: string
|
||||
is_main_worktree: boolean
|
||||
status: 'starting' | 'running' | 'crashed' | 'exited'
|
||||
pid: number | null
|
||||
exit_code: number | null
|
||||
last_error: string | null
|
||||
started_at: string
|
||||
ended_at: string | null
|
||||
}
|
||||
|
||||
export interface CreateSessionReq {
|
||||
workspace_id: string
|
||||
agent_kind_id: string
|
||||
branch?: string
|
||||
issue_number?: number
|
||||
requirement_number?: number
|
||||
initial_prompt?: string
|
||||
}
|
||||
|
||||
// AcpEvent is one frame from the session event stream (history REST + WS push).
|
||||
export interface AcpEvent {
|
||||
id: number
|
||||
direction: 'in' | 'out'
|
||||
kind:
|
||||
| 'request'
|
||||
| 'response'
|
||||
| 'notification'
|
||||
| 'error'
|
||||
| 'state'
|
||||
| 'session_terminated'
|
||||
| 'slow_consumer_disconnect'
|
||||
| 'client_error'
|
||||
method?: string
|
||||
payload: unknown
|
||||
truncated: boolean
|
||||
}
|
||||
|
||||
const enc = (v: string) => encodeURIComponent(v)
|
||||
|
||||
export const acpApi = {
|
||||
@@ -62,4 +110,30 @@ export const acpApi = {
|
||||
remove: (id: string) =>
|
||||
request<void>(`/api/v1/acp/agent-kinds/${enc(id)}`, { method: 'DELETE' }),
|
||||
},
|
||||
sessions: {
|
||||
list: (all?: boolean) =>
|
||||
request<AcpSession[]>('/api/v1/acp/sessions' + (all ? '?all=true' : '')),
|
||||
get: (id: string) =>
|
||||
request<AcpSession>(`/api/v1/acp/sessions/${enc(id)}`),
|
||||
create: (req: CreateSessionReq) =>
|
||||
request<AcpSession>('/api/v1/acp/sessions', { method: 'POST', body: req }),
|
||||
terminate: (id: string) =>
|
||||
request<void>(`/api/v1/acp/sessions/${enc(id)}`, { method: 'DELETE' }),
|
||||
events: (id: string, since: number) =>
|
||||
request<AcpEvent[]>(`/api/v1/acp/sessions/${enc(id)}/events?since=${since}`),
|
||||
},
|
||||
}
|
||||
|
||||
// openSessionWS opens a native WebSocket to /sessions/{id}/ws.
|
||||
//
|
||||
// Auth: browser WebSocket cannot send custom headers, so the token is sent
|
||||
// via the ?token= query parameter. The backend auth middleware accepts it
|
||||
// as a fallback to Authorization. Keep token lifetimes short.
|
||||
export function openSessionWS(sessionId: string, since: number, token: string): WebSocket {
|
||||
const proto = window.location.protocol === 'https:' ? 'wss' : 'ws'
|
||||
const host = window.location.host
|
||||
const url =
|
||||
`${proto}://${host}/api/v1/acp/sessions/${enc(sessionId)}` +
|
||||
`/ws?since=${since}&token=${enc(token)}`
|
||||
return new WebSocket(url)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user