UNPKG

@copilotkit/runtime

Version:

<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />

282 lines (280 loc) 10.2 kB
import "reflect-metadata"; import { InMemoryAgentRunner } from "../../runner/in-memory.mjs"; import { isIntelligenceRuntime } from "../../core/runtime.mjs"; import { errorResponse, isHandlerResponse } from "../shared/json-response.mjs"; import { isValidIdentifier } from "../shared/intelligence-utils.mjs"; import { resolveIntelligenceUser } from "../shared/resolve-intelligence-user.mjs"; import { logger } from "@copilotkit/shared"; //#region src/v2/runtime/handlers/intelligence/threads.ts async function parseJsonBody(request) { try { return await request.json(); } catch (error) { logger.error({ err: error }, "Malformed JSON in request body"); return errorResponse("Invalid request body", 400); } } function requireIntelligenceRuntime(runtime) { if (!isIntelligenceRuntime(runtime)) return errorResponse("Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.", 422); return runtime; } async function resolveThreadMutationContext(runtime, request) { const body = await parseJsonBody(request); if (isHandlerResponse(body)) return body; const user = await resolveIntelligenceUser({ runtime, request }); if (isHandlerResponse(user)) return user; const agentId = body.agentId; if (!isValidIdentifier(agentId)) return errorResponse("Valid agentId is required", 400); return { body, userId: user.id, agentId }; } async function handleListThreads({ runtime, request }) { if (isIntelligenceRuntime(runtime)) try { const url = new URL(request.url); const agentId = url.searchParams.get("agentId"); const includeArchived = url.searchParams.get("includeArchived") === "true"; const limitParam = url.searchParams.get("limit"); const cursor = url.searchParams.get("cursor"); const user = await resolveIntelligenceUser({ runtime, request }); if (isHandlerResponse(user)) return user; if (!isValidIdentifier(agentId)) return errorResponse("Valid agentId query param is required", 400); const data = await runtime.intelligence.listThreads({ userId: user.id, agentId, ...includeArchived ? { includeArchived: true } : {}, ...limitParam ? { limit: Number(limitParam) } : {}, ...cursor ? { cursor } : {} }); return Response.json(data); } catch (error) { logger.error({ err: error }, "Error listing threads"); return errorResponse("Failed to list threads", 500); } if (runtime.runner instanceof InMemoryAgentRunner) { const agentId = new URL(request.url).searchParams.get("agentId"); let threads = runtime.runner.listThreads(); if (agentId) threads = threads.filter((t) => t.agentId === agentId); return Response.json({ threads, nextCursor: null }); } return errorResponse("Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.", 422); } /** * Clears all in-memory thread history for the local-dev InMemory fallback. * * The local-dev fallback exposes this so consumers (e.g. the demo's Clear * button) can wipe in-memory thread history without restarting the runtime. * Intentionally a no-op when the Intelligence platform is configured: real * thread history lives in the database and must not be wiped by a * client-side page load. */ function handleClearThreads({ runtime }) { if (runtime.runner instanceof InMemoryAgentRunner) runtime.runner.clearThreads(); return new Response(null, { status: 204 }); } async function handleUpdateThread({ runtime, request, threadId }) { const intelligenceRuntime = requireIntelligenceRuntime(runtime); if (isHandlerResponse(intelligenceRuntime)) return intelligenceRuntime; try { const mutation = await resolveThreadMutationContext(intelligenceRuntime, request); if (isHandlerResponse(mutation)) return mutation; const updates = { ...mutation.body }; delete updates.agentId; delete updates.userId; const thread = await intelligenceRuntime.intelligence.updateThread({ threadId, userId: mutation.userId, agentId: mutation.agentId, updates }); return Response.json(thread); } catch (error) { logger.error({ err: error, threadId }, "Error updating thread"); return errorResponse("Failed to update thread", 500); } } async function handleSubscribeToThreads({ runtime, request }) { const intelligenceRuntime = requireIntelligenceRuntime(runtime); if (isHandlerResponse(intelligenceRuntime)) return intelligenceRuntime; try { const user = await resolveIntelligenceUser({ runtime: intelligenceRuntime, request }); if (isHandlerResponse(user)) return user; const credentials = await intelligenceRuntime.intelligence.ɵsubscribeToThreads({ userId: user.id }); return Response.json({ joinToken: credentials.joinToken }); } catch (error) { logger.error({ err: error }, "Error subscribing to threads"); return errorResponse("Failed to subscribe to threads", 500); } } async function handleArchiveThread({ runtime, request, threadId }) { const intelligenceRuntime = requireIntelligenceRuntime(runtime); if (isHandlerResponse(intelligenceRuntime)) return intelligenceRuntime; try { const mutation = await resolveThreadMutationContext(intelligenceRuntime, request); if (isHandlerResponse(mutation)) return mutation; await intelligenceRuntime.intelligence.archiveThread({ threadId, userId: mutation.userId, agentId: mutation.agentId }); return Response.json({ threadId, archived: true }); } catch (error) { logger.error({ err: error, threadId }, "Error archiving thread"); return errorResponse("Failed to archive thread", 500); } } async function handleDeleteThread({ runtime, request, threadId }) { const intelligenceRuntime = requireIntelligenceRuntime(runtime); if (isHandlerResponse(intelligenceRuntime)) return intelligenceRuntime; try { const mutation = await resolveThreadMutationContext(intelligenceRuntime, request); if (isHandlerResponse(mutation)) return mutation; await intelligenceRuntime.intelligence.deleteThread({ threadId, userId: mutation.userId, agentId: mutation.agentId }); return Response.json({ threadId, deleted: true }); } catch (error) { logger.error({ err: error, threadId }, "Error deleting thread"); return errorResponse("Failed to delete thread", 500); } } async function handleGetThreadMessages({ runtime, request, threadId }) { if (isIntelligenceRuntime(runtime)) try { const user = await resolveIntelligenceUser({ runtime, request }); if (isHandlerResponse(user)) return user; const data = await runtime.intelligence.getThreadMessages({ threadId }); return Response.json(data); } catch (error) { logger.error({ err: error, threadId }, "Error fetching thread messages"); return errorResponse("Failed to fetch thread messages", 500); } if (runtime.runner instanceof InMemoryAgentRunner) { const mapped = runtime.runner.getThreadMessages(threadId).map((msg) => { switch (msg.role) { case "assistant": { const toolCalls = msg.toolCalls ?? []; return { id: msg.id, role: msg.role, ...msg.content !== void 0 ? { content: msg.content } : {}, ...toolCalls.length > 0 ? { toolCalls: toolCalls.map((tc) => ({ id: tc.id, name: tc.function.name, args: tc.function.arguments })) } : {} }; } case "tool": return { id: msg.id, role: msg.role, content: msg.content, toolCallId: msg.toolCallId }; default: return { id: msg.id, role: msg.role, ..."content" in msg && msg.content !== void 0 ? { content: msg.content } : {} }; } }); return Response.json({ messages: mapped }); } return errorResponse("Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.", 422); } async function handleGetThreadEvents({ runtime, request, threadId }) { if (isIntelligenceRuntime(runtime)) try { const user = await resolveIntelligenceUser({ runtime, request }); if (isHandlerResponse(user)) return user; const data = await runtime.intelligence.getThreadEvents({ threadId }); return Response.json({ events: data.events }); } catch (error) { logger.error({ err: error, threadId }, "Error fetching thread events"); return errorResponse("Failed to fetch thread events", 500); } if (runtime.runner instanceof InMemoryAgentRunner) try { const events = runtime.runner.getThreadEvents(threadId); return Response.json({ events }); } catch (error) { logger.error({ err: error, threadId }, "Error fetching thread events"); return errorResponse("Failed to fetch thread events", 500); } return errorResponse("Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.", 422); } async function handleGetThreadState({ runtime, request, threadId }) { if (isIntelligenceRuntime(runtime)) try { const user = await resolveIntelligenceUser({ runtime, request }); if (isHandlerResponse(user)) return user; const data = await runtime.intelligence.getThreadState({ threadId }); const state = data.kind === "snapshot" ? data.state : null; return Response.json({ state }); } catch (error) { logger.error({ err: error, threadId }, "Error fetching thread state"); return errorResponse("Failed to fetch thread state", 500); } if (runtime.runner instanceof InMemoryAgentRunner) try { const state = runtime.runner.getThreadState(threadId); return Response.json({ state }); } catch (error) { logger.error({ err: error, threadId }, "Error fetching thread state"); return errorResponse("Failed to fetch thread state", 500); } return errorResponse("Missing CopilotKitIntelligence configuration. Thread operations require a CopilotKitIntelligence instance to be provided in CopilotRuntime options.", 422); } //#endregion export { handleArchiveThread, handleClearThreads, handleDeleteThread, handleGetThreadEvents, handleGetThreadMessages, handleGetThreadState, handleListThreads, handleSubscribeToThreads, handleUpdateThread }; //# sourceMappingURL=threads.mjs.map