Browse Source

feat: update session handling to include title generation and error logging improvements

feat/ai-sdk-v6-upgrade
npmrun 8 hours ago
parent
commit
09020cfa03
  1. BIN
      packages/drizzle-pkg/db.sqlite
  2. 27
      server/api/agent/chat/index.post.ts

BIN
packages/drizzle-pkg/db.sqlite

Binary file not shown.

27
server/api/agent/chat/index.post.ts

@ -4,7 +4,7 @@ import { getCurrentUser, getConfigGlobal, getConfigUser } from "#server/utils/co
import { createOpenAI } from "@ai-sdk/openai";
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { type LanguageModel, type ModelMessage, streamText, stepCountIs } from "ai";
import { getSessionByIdAndUser, getMessagesBySession, getMaxSortOrder, saveMessage, truncateMessagesAfter, deleteMessage, getMessageById, updateMessageContent, updateMessageParts, touchSession, countAssistantMessages } from "#server/service/agent/session";
import { getSessionByIdAndUser, getMessagesBySession, getMaxSortOrder, saveMessage, truncateMessagesAfter, deleteMessage, getMessageById, updateMessageContent, updateMessageParts, touchSession, countAssistantMessages, updateSession } from "#server/service/agent/session";
import { getAgentToolsForChat, getAgentToolsBySlugs, executeAgentTool } from "#server/service/agent-tool";
import { getTempTokenFromCookie } from "#server/service/agent/temp-token";
import { checkRateLimit, incrementRateLimit } from "#server/service/agent/rate-limit";
@ -493,6 +493,7 @@ export default defineEventHandler(async (event) => {
}
},
onFinish: async ({ finishReason, usage, steps, text: assistantText }) => {
try {
if (serverAbortController.signal.aborted) {
logger.info("[%s] [AGENT-CHAT] onFinish skipped due to abort", event.context.requestId ?? "-");
unregisterAbortController(sessionId);
@ -616,16 +617,36 @@ export default defineEventHandler(async (event) => {
if (!user) {
incrementRateLimit(sessionId, ip);
const rateLimit = checkRateLimit(sessionId, ip);
try {
setResponseHeaders(event, {
"X-RateLimit-Session-Remaining": String(rateLimit.sessionRemaining),
"X-RateLimit-Ip-Remaining": String(rateLimit.ipRemaining),
});
} catch {}
}
if (shouldGenerateTitle && titleModelId && assistantText.trim().length > 0) {
generateSessionTitle(sessionId, content.trim(), assistantText, titleModelId, user?.id ?? null).catch((e) => { logger.error("[AGENT-CHAT] title gen failed: %s", e?.message ?? e); });
if (shouldGenerateTitle && assistantText.trim().length > 0) {
if (!user) {
const excerpt = assistantText
.replace(/[#*`_~>\-!\[\]()]/g, "")
.trim()
.replace(/\s+/g, " ")
.slice(0, 20);
logger.info("[%s] [AGENT-TITLE] excerpt attempt: shouldGenerateTitle=%s excerptLen=%d", event.context.requestId ?? "-", shouldGenerateTitle, excerpt.length);
if (excerpt) {
await updateSession(sessionId, { title: excerpt });
logger.info("[%s] [AGENT-TITLE] sessionId=%s title=%s (excerpt)", event.context.requestId ?? "-", sessionId, excerpt);
}
} else if (titleModelId) {
generateSessionTitle(sessionId, content.trim(), assistantText, titleModelId, user.id).catch((e) => { logger.error("[AGENT-CHAT] title gen failed: %s", e?.message ?? e); });
}
} else {
logger.debug("[%s] [AGENT-TITLE] skipped: shouldGenerateTitle=%s assistantTextLen=%d", event.context.requestId ?? "-", shouldGenerateTitle, assistantText.trim().length);
}
unregisterAbortController(sessionId);
} catch (e) {
logger.error("[%s] [AGENT-CHAT] onFinish error: %s", event.context.requestId ?? "-", e?.message ?? e);
}
},
onAbort: async () => {
try {

Loading…
Cancel
Save