UNPKG

@genkit-ai/next

Version:
255 lines (254 loc) 8.14 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var index_exports = {}; __export(index_exports, { NextRequest: () => import_server.NextRequest, NextResponse: () => import_server.NextResponse, appRoute: () => appRoute, default: () => index_default }); module.exports = __toCommonJS(index_exports); var import_crypto = require("crypto"); var import_beta = require("genkit/beta"); var import_context = require("genkit/context"); var import_server = require("next/server.js"); const delimiter = "\n\n"; async function subscribeToStream(streamManager, streamId) { try { const encoder = new TextEncoder(); const { readable, writable } = new TransformStream(); const writer = writable.getWriter(); await streamManager.subscribe(streamId, { onChunk: (chunk) => { writer.write( encoder.encode( "data: " + JSON.stringify({ message: chunk }) + delimiter ) ); }, onDone: (output) => { writer.write( encoder.encode( "data: " + JSON.stringify({ result: output }) + delimiter ) ); writer.write(encoder.encode("END")); writer.close(); }, onError: (err) => { console.error( `Streaming request failed with error: ${err.message} ${err.stack}` ); writer.write( encoder.encode( `error: ${JSON.stringify({ error: (0, import_context.getCallableJSON)(err) })}${delimiter}` ) ); writer.write(encoder.encode("END")); writer.close(); } }); return new import_server.NextResponse(readable, { status: 200, headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive", "Transfer-Encoding": "chunked", "x-genkit-stream-id": streamId } }); } catch (e) { if (e instanceof import_beta.StreamNotFoundError) { return new import_server.NextResponse(null, { status: 204 }); } if (e.status === "DEADLINE_EXCEEDED") { const encoder = new TextEncoder(); const { readable, writable } = new TransformStream(); const writer = writable.getWriter(); writer.write( encoder.encode( `error: ${JSON.stringify({ error: (0, import_context.getCallableJSON)(e) })}${delimiter}` ) ); writer.write(encoder.encode("END")); writer.close(); return new import_server.NextResponse(readable, { status: 200, headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive", "Transfer-Encoding": "chunked" } }); } throw e; } } async function getContext(request, input, provider) { const context = {}; if (!provider) { return context; } const r = { method: request.method, headers: {}, input }; request.headers.forEach((val, key) => { r.headers[key.toLowerCase()] = val; }); return await provider(r); } function appRoute(action, opts) { return async (req) => { let context = {}; const { data: input } = await req.json(); const streamId = req.headers.get("x-genkit-stream-id"); if (req.headers.get("accept") !== "text/event-stream") { try { context = await getContext(req, input, opts?.contextProvider); } catch (e) { console.error("Error gathering context for running action:", e); return import_server.NextResponse.json( { error: (0, import_context.getCallableJSON)(e) }, { status: (0, import_context.getHttpStatus)(e) } ); } try { const resp = await action.run(input, { context, abortSignal: req.signal }); const response = import_server.NextResponse.json({ result: resp.result }); if (opts?.streamManager && streamId) { response.headers.set("x-genkit-stream-id", streamId); } return response; } catch (e) { console.error("Error calling action:", e); return import_server.NextResponse.json( { error: (0, import_context.getCallableJSON)(e) }, { status: (0, import_context.getHttpStatus)(e) } ); } } try { context = await getContext(req, input, opts?.contextProvider); } catch (e) { console.error("Error gathering context for streaming action:", e); return new import_server.NextResponse( `error: ${JSON.stringify((0, import_context.getCallableJSON)(e))}${delimiter}END`, { status: (0, import_context.getHttpStatus)(e) } ); } const streamManager = opts?.streamManager; if (streamManager && streamId) { const response = await subscribeToStream(streamManager, streamId); if (response) { return response; } } const streamIdToUse = (0, import_crypto.randomUUID)(); const encoder = new TextEncoder(); const { readable, writable } = new TransformStream(); (async () => { const writer = writable.getWriter(); const taskQueue = new import_beta.AsyncTaskQueue(); let durableStream = void 0; if (streamManager) { durableStream = await streamManager.open(streamIdToUse); } try { const output = action.run(input, { context, abortSignal: req.signal, onChunk: (chunk) => { if (durableStream) { taskQueue.enqueue(() => durableStream.write(chunk)); } taskQueue.enqueue( () => writer.write( encoder.encode( `data: ${JSON.stringify({ message: chunk })}${delimiter}` ) ) ); } }); const finalOutput = await output; if (durableStream) { taskQueue.enqueue(() => durableStream.done(finalOutput.result)); } taskQueue.enqueue( () => writer.write( encoder.encode( `data: ${JSON.stringify({ result: finalOutput.result })}${delimiter}` ) ) ); taskQueue.enqueue(() => writer.write(encoder.encode("END"))); } catch (err) { if (durableStream) { taskQueue.enqueue(() => durableStream.error(err)); } console.error("Error streaming action:", err); taskQueue.enqueue( () => writer.write( encoder.encode( `error: ${JSON.stringify((0, import_context.getCallableJSON)(err))} ` ) ) ); taskQueue.enqueue(() => writer.write(encoder.encode("END"))); } finally { await taskQueue.merge(); await writer.close(); } })(); const headers = { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", Connection: "keep-alive", "Transfer-Encoding": "chunked" }; if (streamManager) { headers["x-genkit-stream-id"] = streamIdToUse; } return new import_server.NextResponse(readable, { status: 200, headers }); }; } var index_default = appRoute; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { NextRequest, NextResponse, appRoute }); //# sourceMappingURL=index.js.map