|
|
@ -99,7 +99,12 @@ export function useAgentChat(options: UseAgentChatOptions) { |
|
|
|
|
|
|
|
|
async function tryResumeStream(sid: string) { |
|
|
async function tryResumeStream(sid: string) { |
|
|
const lastMsg = messages.value[messages.value.length - 1]; |
|
|
const lastMsg = messages.value[messages.value.length - 1]; |
|
|
if (!lastMsg || lastMsg.role !== "user") return; |
|
|
if (!lastMsg) return; |
|
|
|
|
|
|
|
|
|
|
|
const isApprovalResume = lastMsg.role === "assistant" && |
|
|
|
|
|
lastMsg.parts?.some((p) => p.state === "approval-responded"); |
|
|
|
|
|
const isNormalResume = lastMsg.role === "user"; |
|
|
|
|
|
if (!isApprovalResume && !isNormalResume) return; |
|
|
|
|
|
|
|
|
let res: Response; |
|
|
let res: Response; |
|
|
try { |
|
|
try { |
|
|
@ -118,18 +123,36 @@ export function useAgentChat(options: UseAgentChatOptions) { |
|
|
const modelIdHeader = res.headers.get("X-Stream-Model-Id"); |
|
|
const modelIdHeader = res.headers.get("X-Stream-Model-Id"); |
|
|
const userMessageIdHeader = res.headers.get("X-Stream-User-Message-Id"); |
|
|
const userMessageIdHeader = res.headers.get("X-Stream-User-Message-Id"); |
|
|
|
|
|
|
|
|
const assistantMsg: AgentMessage = { |
|
|
let assistantIdx: number; |
|
|
id: generateId(), |
|
|
let assistantMsg: AgentMessage; |
|
|
role: "assistant", |
|
|
|
|
|
content: "", |
|
|
|
|
|
parts: [], |
|
|
|
|
|
modelId: modelIdHeader ? Number(modelIdHeader) : null, |
|
|
|
|
|
}; |
|
|
|
|
|
messages.value.push(assistantMsg); |
|
|
|
|
|
const assistantIdx = messages.value.length - 1; |
|
|
|
|
|
|
|
|
|
|
|
if (userMessageIdHeader && lastMsg) { |
|
|
if (isApprovalResume) { |
|
|
lastMsg.id = userMessageIdHeader; |
|
|
assistantMsg = lastMsg; |
|
|
|
|
|
assistantIdx = messages.value.length - 1; |
|
|
|
|
|
if (modelIdHeader) { |
|
|
|
|
|
assistantMsg.modelId = Number(modelIdHeader); |
|
|
|
|
|
} |
|
|
|
|
|
staleApprovalToolCallIds = new Set( |
|
|
|
|
|
messages.value.flatMap((m) => |
|
|
|
|
|
(m.parts ?? []) |
|
|
|
|
|
.filter((p) => p.state === "approval-requested" && !p.isAutomaticApproval) |
|
|
|
|
|
.map((p) => p.toolCallId ?? ""), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
|
|
|
} else { |
|
|
|
|
|
assistantMsg = { |
|
|
|
|
|
id: generateId(), |
|
|
|
|
|
role: "assistant", |
|
|
|
|
|
content: "", |
|
|
|
|
|
parts: [], |
|
|
|
|
|
modelId: modelIdHeader ? Number(modelIdHeader) : null, |
|
|
|
|
|
}; |
|
|
|
|
|
messages.value.push(assistantMsg); |
|
|
|
|
|
assistantIdx = messages.value.length - 1; |
|
|
|
|
|
|
|
|
|
|
|
if (userMessageIdHeader && lastMsg) { |
|
|
|
|
|
lastMsg.id = userMessageIdHeader; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
isLoading.value = true; |
|
|
isLoading.value = true; |
|
|
@ -137,7 +160,7 @@ export function useAgentChat(options: UseAgentChatOptions) { |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
await processStream(res, assistantIdx); |
|
|
await processStream(res, assistantIdx); |
|
|
validateAssistantContent(assistantIdx); |
|
|
validateAssistantContent(assistantIdx, isApprovalResume); |
|
|
onStreamComplete?.(); |
|
|
onStreamComplete?.(); |
|
|
} catch (err: any) { |
|
|
} catch (err: any) { |
|
|
if (err.name !== "AbortError") { |
|
|
if (err.name !== "AbortError") { |
|
|
|