import { useQuery } from '@tanstack/react-query'
import type { UseQueryResult } from '@tanstack/react-query'
import { apiFetch } from '../../api/client'
import { adaptSession } from '../../api/adapters'
import type { Session, SessionDTO } from '../../api/adapters'
export interface TurnDTO {
turn_id: string
seq: number
role: 'user' | 'assistant' | 'tool' | 'system'
timestamp: number
content: string
model?: string
tokens_in?: number
tokens_out?: number
cost_usd?: number
tool_calls?: unknown
metadata?: unknown
}
export interface Turn {
i: number
role: 'user' | 'assistant' | 'tool'
body: string
model?: string
tokensIn?: number
tokensOut?: number
toolName?: string
toolKind?: 'call' | 'result'
}
export interface SessionWithTurnsDTO extends SessionDTO {
turns: TurnDTO[]
}
export interface SessionWithTurns extends Omit<Session, 'turns'> {
turns: Turn[]
}
function extractToolCalls(
raw: unknown,
): { toolName?: string; toolKind?: 'call' | 'result' } {
if (raw == null || typeof raw !== 'object') {
return {}
}
const obj = raw as Record<string, unknown>
const name = typeof obj['name'] === 'string' ? obj['name'] : undefined
const kind =
obj['kind'] === 'call' || obj['kind'] === 'result'
? (obj['kind'] as 'call' | 'result')
: undefined
if (name == null && kind == null) {
return {}
}
return { toolName: name, toolKind: kind }
}
export function adaptTurn(d: TurnDTO): Turn {
const role: 'user' | 'assistant' | 'tool' =
d.role === 'system' ? 'assistant' : d.role
const { toolName, toolKind } = extractToolCalls(d.tool_calls)
return {
i: d.seq,
role,
body: d.content,
model: d.model,
tokensIn: d.tokens_in,
tokensOut: d.tokens_out,
toolName,
toolKind,
}
}
export function useSession(
tool: string,
host: string,
id: string,
): UseQueryResult<SessionWithTurns> {
// id is the composite `tool/host/session_id` from Session.id.
// Extract only the session_id tail for the API URL.
const rawSessionId = id.split('/').slice(2).join('/')
return useQuery({
queryKey: ['session', tool, host, id],
queryFn: async () => {
const dto = await apiFetch<SessionWithTurnsDTO>(
`/api/v1/sessions/${tool}/${host}/${rawSessionId}`,
)
const session = adaptSession(dto)
return { ...session, turns: dto.turns.map(adaptTurn) }
},
})
}