Remove hard timeouts and fallback paths in chat flow

This commit is contained in:
Ruslan Bakiev
2026-02-20 10:05:33 +07:00
parent d49b00d688
commit b3602d142e
10 changed files with 49 additions and 99 deletions

View File

@@ -430,13 +430,7 @@ export async function runLangGraphCrmAgentFor(input: {
llmBaseURL = gigachatBaseUrl;
llmModel = gigachatModel || "GigaChat-2-Max";
} catch (e: any) {
return {
text: `Не удалось получить токен GigaChat: ${String(e?.message || e)}`,
plan: ["Проверить GIGACHAT_AUTH_KEY", "Проверить GIGACHAT_SCOPE", "Проверить сетевой доступ до OAuth endpoint и перезапустить dev-сервер"],
tools: [],
thinking: ["Провайдер GigaChat настроен, но OAuth не прошел."],
toolRuns: [],
};
throw new Error(`Не удалось получить токен GigaChat: ${String(e?.message || e)}`);
}
}
@@ -918,8 +912,6 @@ export async function runLangGraphCrmAgentFor(input: {
tools: [crmTool],
});
const maxCycles = Math.max(1, Math.min(Number(process.env.CF_AGENT_MAX_CYCLES ?? "3"), 8));
const cycleTimeoutMs = Math.max(5000, Math.min(Number(process.env.CF_AGENT_CYCLE_TIMEOUT_MS ?? "1200000"), 1800000));
const tracingFlag = (process.env.LANGSMITH_TRACING ?? process.env.LANGCHAIN_TRACING_V2 ?? "").trim().toLowerCase();
const tracingEnabled = tracingFlag === "1" || tracingFlag === "true" || tracingFlag === "yes";
const langfuse = getLangfuseClient();
@@ -937,7 +929,6 @@ export async function runLangGraphCrmAgentFor(input: {
},
tags: ["clientsflow", "crm-agent", "langgraph"],
});
let consecutiveNoProgress = 0;
let finalText = "";
const cycleNotes: string[] = [];
@@ -1011,7 +1002,7 @@ export async function runLangGraphCrmAgentFor(input: {
};
};
for (let cycle = 1; cycle <= maxCycles; cycle += 1) {
for (let cycle = 1; ; cycle += 1) {
const userPrompt = cyclePrompt(input.userText, cycle, cycleNotes, pendingChanges.length);
const cycleSpan = lfTrace?.span({
name: "agent.cycle",
@@ -1028,7 +1019,11 @@ export async function runLangGraphCrmAgentFor(input: {
let res: any;
try {
const invokeConfig: Record<string, any> = { recursionLimit: 30 };
const invokeConfig: Record<string, any> = {};
const recursionLimit = Number(process.env.CF_AGENT_RECURSION_LIMIT ?? "1000000");
if (Number.isFinite(recursionLimit) && recursionLimit > 0) {
invokeConfig.recursionLimit = recursionLimit;
}
if (tracingEnabled) {
invokeConfig.runName = "clientsflow.crm_agent_cycle";
invokeConfig.tags = ["clientsflow", "crm-agent", "langgraph"];
@@ -1040,20 +1035,15 @@ export async function runLangGraphCrmAgentFor(input: {
cycle,
};
}
res = await Promise.race([
agent.invoke(
{
messages: [
{ role: "system", content: system },
{ role: "user", content: userPrompt },
],
},
invokeConfig,
),
new Promise((_resolve, reject) =>
setTimeout(() => reject(new Error(`Cycle timeout after ${cycleTimeoutMs}ms`)), cycleTimeoutMs),
),
]);
res = await agent.invoke(
{
messages: [
{ role: "system", content: system },
{ role: "user", content: userPrompt },
],
},
invokeConfig,
);
} catch (e: any) {
await emitTrace({ text: "Один из шагов завершился ошибкой." });
cycleSpan?.end({
@@ -1090,22 +1080,11 @@ export async function runLangGraphCrmAgentFor(input: {
: "Промежуточный шаг не дал прогресса, проверяю следующий вариант.",
});
if (!progressed) {
consecutiveNoProgress += 1;
} else {
consecutiveNoProgress = 0;
}
const done = (!progressed && cycle > 1) || cycle === maxCycles;
const done = !progressed && cycle > 1;
if (done) {
await emitTrace({ text: "Формирую итоговый ответ." });
break;
}
if (consecutiveNoProgress >= 2) {
await emitTrace({ text: "Останавливаюсь, чтобы не крутиться в пустом цикле." });
break;
}
}
lfTrace?.update({
@@ -1115,7 +1094,6 @@ export async function runLangGraphCrmAgentFor(input: {
toolRunsCount: toolRuns.length,
dbWritesCount: dbWrites.length,
pendingChangesCount: pendingChanges.length,
maxCycles,
},
});
void langfuse?.flushAsync().catch(() => {});