feat: conversational branching, AI markers, TaskLane improvements, collapsible sidebar #120

Merged
chihlasm merged 58 commits from feat/conversational-branching into main 2026-03-27 13:16:44 +00:00
4 changed files with 151 additions and 0 deletions
Showing only changes of commit 30d7d6e5a3 - Show all commits

View File

@@ -0,0 +1,67 @@
import apiClient from './client'
import type {
BranchTreeResponse,
ForkCreateRequest,
ForkPointResponse,
BranchSwitchResponse,
ReviveRequest,
BranchMessageRequest,
BranchMessageResponse,
} from '@/types/branching'
export const branchesApi = {
async getBranches(sessionId: string): Promise<BranchTreeResponse> {
const response = await apiClient.get<BranchTreeResponse>(
`/ai-sessions/${sessionId}/branches`
)
return response.data
},
async createFork(sessionId: string, data: ForkCreateRequest): Promise<ForkPointResponse> {
const response = await apiClient.post<ForkPointResponse>(
`/ai-sessions/${sessionId}/branches/fork`,
data
)
return response.data
},
async updateBranchStatus(
sessionId: string,
branchId: string,
status: string,
reason?: string
): Promise<void> {
await apiClient.patch(
`/ai-sessions/${sessionId}/branches/${branchId}/status`,
{ status, reason }
)
},
async switchBranch(sessionId: string, branchId: string): Promise<BranchSwitchResponse> {
const response = await apiClient.post<BranchSwitchResponse>(
`/ai-sessions/${sessionId}/branches/${branchId}/switch`
)
return response.data
},
async reviveBranch(sessionId: string, branchId: string, data: ReviveRequest): Promise<void> {
await apiClient.post(
`/ai-sessions/${sessionId}/branches/${branchId}/revive`,
data
)
},
async sendBranchMessage(
sessionId: string,
branchId: string,
data: BranchMessageRequest
): Promise<BranchMessageResponse> {
const response = await apiClient.post<BranchMessageResponse>(
`/ai-sessions/${sessionId}/branches/${branchId}/message`,
data
)
return response.data
},
}
export default branchesApi

View File

@@ -0,0 +1,39 @@
import apiClient from './client'
import type {
HandoffCreateRequest,
HandoffResponse,
QueueItemResponse,
} from '@/types/branching'
export const handoffsApi = {
async createHandoff(sessionId: string, data: HandoffCreateRequest): Promise<HandoffResponse> {
const response = await apiClient.post<HandoffResponse>(
`/ai-sessions/${sessionId}/handoff`,
data
)
return response.data
},
async listHandoffs(sessionId: string): Promise<HandoffResponse[]> {
const response = await apiClient.get<HandoffResponse[]>(
`/ai-sessions/${sessionId}/handoffs`
)
return response.data
},
async claimHandoff(handoffId: string): Promise<HandoffResponse> {
const response = await apiClient.post<HandoffResponse>(
`/handoffs/${handoffId}/claim`
)
return response.data
},
async getQueue(params?: { intent?: 'park' | 'escalate'; limit?: number }): Promise<QueueItemResponse[]> {
const response = await apiClient.get<QueueItemResponse[]>('/handoffs/queue', {
params,
})
return response.data
},
}
export default handoffsApi

View File

@@ -32,3 +32,6 @@ export { publicTemplatesApi } from './publicTemplates'
export { uploadsApi, default as uploadsApiDefault } from './uploads'
export { scriptBuilderApi } from './scriptBuilder'
export { betaFeedbackApi } from './betaFeedback'
export { branchesApi } from './branches'
export { handoffsApi } from './handoffs'
export { resolutionsApi } from './resolutions'

View File

@@ -0,0 +1,42 @@
import apiClient from './client'
import type {
AllResolutionOutputsResponse,
ResolutionOutputResponse,
ResolutionOutputEditRequest,
ResolutionOutputPushRequest,
} from '@/types/branching'
export const resolutionsApi = {
async getOutputs(sessionId: string): Promise<AllResolutionOutputsResponse> {
const response = await apiClient.get<AllResolutionOutputsResponse>(
`/ai-sessions/${sessionId}/resolution-outputs`
)
return response.data
},
async editOutput(
sessionId: string,
outputId: string,
data: ResolutionOutputEditRequest
): Promise<ResolutionOutputResponse> {
const response = await apiClient.patch<ResolutionOutputResponse>(
`/ai-sessions/${sessionId}/resolution-outputs/${outputId}`,
data
)
return response.data
},
async pushOutput(
sessionId: string,
outputId: string,
data: ResolutionOutputPushRequest
): Promise<ResolutionOutputResponse> {
const response = await apiClient.post<ResolutionOutputResponse>(
`/ai-sessions/${sessionId}/resolution-outputs/${outputId}/push`,
data
)
return response.data
},
}
export default resolutionsApi