u
This commit is contained in:
@@ -630,15 +630,31 @@ const actions = {
|
||||
* Adds brain icon with text as chunks stream in.
|
||||
*/
|
||||
applyStreamReasoning(data) {
|
||||
const text = typeof data?.text === 'string' ? data.text : (typeof data === 'string' ? data : '');
|
||||
let text = '';
|
||||
if (typeof data === 'string') {
|
||||
text = data;
|
||||
} else if (data && typeof data === 'object') {
|
||||
if (typeof data.plain === 'string') {
|
||||
text = data.plain;
|
||||
} else if (data.encrypted) {
|
||||
text = '';
|
||||
} else if (typeof data.text === 'string') {
|
||||
text = data.text;
|
||||
}
|
||||
}
|
||||
if (!text || !text.trim()) return;
|
||||
const trimmed = text.trim();
|
||||
if (trimmed.startsWith('{') && (trimmed.includes('"encrypted"') || trimmed.includes('"plain"'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
chatAutomat.setState((prev) => {
|
||||
const turns = prev.activeTurns ? [...prev.activeTurns] : [];
|
||||
if (turns.length === 0) {
|
||||
turns.push({
|
||||
id: `turn-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
||||
handshake: 'green',
|
||||
reasonings: [{ id: `r-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, text, sealed: false }],
|
||||
reasonings: [{ id: `r-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, text: trimmed, sealed: false }],
|
||||
tools: [],
|
||||
usage: null,
|
||||
content: '',
|
||||
@@ -648,6 +664,7 @@ const actions = {
|
||||
}
|
||||
const lastIdx = turns.length - 1;
|
||||
const lastTurn = { ...turns[lastIdx] };
|
||||
lastTurn.tools = (lastTurn.tools || []).filter((tool) => Boolean(tool.name));
|
||||
const rList = (lastTurn.reasonings || []).map((r) => ({ ...r }));
|
||||
let unsealedIdx = -1;
|
||||
for (let i = rList.length - 1; i >= 0; i--) {
|
||||
@@ -657,9 +674,9 @@ const actions = {
|
||||
}
|
||||
}
|
||||
if (unsealedIdx >= 0) {
|
||||
rList[unsealedIdx].text = text;
|
||||
rList[unsealedIdx].text = trimmed;
|
||||
} else {
|
||||
rList.push({ id: `r-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, text, sealed: false });
|
||||
rList.push({ id: `r-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`, text: trimmed, sealed: false });
|
||||
}
|
||||
lastTurn.reasonings = rList;
|
||||
turns[lastIdx] = lastTurn;
|
||||
@@ -790,6 +807,7 @@ const actions = {
|
||||
lastTurn.reasonings = (lastTurn.reasonings || [])
|
||||
.filter((r) => r.text && r.text.trim())
|
||||
.map((r) => ({ ...r, sealed: true }));
|
||||
lastTurn.tools = (lastTurn.tools || []).filter((tool) => Boolean(tool.name));
|
||||
turns[lastIdx] = lastTurn;
|
||||
return { activeTurns: turns, streamPhase: 'working' };
|
||||
});
|
||||
@@ -815,6 +833,7 @@ const actions = {
|
||||
}
|
||||
const lastIdx = turns.length - 1;
|
||||
const lastTurn = { ...turns[lastIdx] };
|
||||
lastTurn.tools = (lastTurn.tools || []).filter((tool) => Boolean(tool.name));
|
||||
const currentText = typeof data.text === 'string'
|
||||
? data.text
|
||||
: ((lastTurn.content || '') + (data.delta || ''));
|
||||
@@ -874,7 +893,9 @@ const actions = {
|
||||
reasonings: (t.reasonings || [])
|
||||
.filter((r) => r.text && r.text.trim())
|
||||
.map((r) => ({ ...r, sealed: true })),
|
||||
tools: (t.tools || []).map((tool) => (tool.state === 'black' ? { ...tool, state: 'green' } : tool)),
|
||||
tools: (t.tools || [])
|
||||
.filter((tool) => Boolean(tool.name))
|
||||
.map((tool) => (tool.state === 'black' ? { ...tool, state: 'green' } : tool)),
|
||||
}));
|
||||
|
||||
// Gather full cumulative content from all turns
|
||||
@@ -1039,6 +1060,7 @@ const actions = {
|
||||
const payload = {
|
||||
role: 'tool',
|
||||
tool_call_id,
|
||||
name: 'ask_user',
|
||||
content: answer,
|
||||
answer,
|
||||
};
|
||||
@@ -1062,16 +1084,60 @@ const actions = {
|
||||
sealed: false,
|
||||
};
|
||||
|
||||
chatAutomat.setState((prev) => ({
|
||||
messages: [...prev.messages, optimisticMsg],
|
||||
activeTurns: [initialTurn],
|
||||
conversationState: 'busy',
|
||||
streamPhase: 'thinking',
|
||||
streamingText: '',
|
||||
lastUsage: null,
|
||||
isSending: true,
|
||||
sendError: null,
|
||||
}));
|
||||
chatAutomat.setState((prev) => {
|
||||
const turns = prev.activeTurns ? [...prev.activeTurns] : [];
|
||||
const sealedTurns = turns.map((t) => ({
|
||||
...t,
|
||||
sealed: true,
|
||||
reasonings: (t.reasonings || [])
|
||||
.filter((r) => r.text && r.text.trim())
|
||||
.map((r) => ({ ...r, sealed: true })),
|
||||
tools: (t.tools || [])
|
||||
.filter((tool) => Boolean(tool.name))
|
||||
.map((tool) => (tool.state === 'black' ? { ...tool, state: 'green' } : tool)),
|
||||
}));
|
||||
|
||||
const hasActiveTurns = sealedTurns.some(
|
||||
(t) => (t.reasonings && t.reasonings.length > 0) || (t.tools && t.tools.length > 0) || t.content || t.usage
|
||||
);
|
||||
|
||||
let foundExisting = false;
|
||||
const nextMessages = prev.messages.map((m) => {
|
||||
if (m.role === 'assistant' && !m.turns) {
|
||||
try {
|
||||
const p = typeof m.message === 'string' ? JSON.parse(m.message) : m.message;
|
||||
if (p?.tool_calls?.some((tc) => tc.id === tool_call_id || tc.function?.name === 'ask_user')) {
|
||||
foundExisting = true;
|
||||
return { ...m, turns: sealedTurns };
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return m;
|
||||
});
|
||||
|
||||
if (!foundExisting && hasActiveTurns) {
|
||||
nextMessages.push({
|
||||
id: `msg-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
||||
conversation_id: selectedConversationId,
|
||||
role: 'assistant',
|
||||
message: '',
|
||||
turns: sealedTurns,
|
||||
created_at: new Date().toISOString(),
|
||||
});
|
||||
}
|
||||
nextMessages.push(optimisticMsg);
|
||||
|
||||
return {
|
||||
messages: nextMessages,
|
||||
activeTurns: [initialTurn],
|
||||
conversationState: 'busy',
|
||||
streamPhase: 'thinking',
|
||||
streamingText: '',
|
||||
lastUsage: null,
|
||||
isSending: true,
|
||||
sendError: null,
|
||||
};
|
||||
});
|
||||
|
||||
try {
|
||||
const res = await modelconversationApi.addMessage(selectedConversationId, payload);
|
||||
|
||||
Reference in New Issue
Block a user