From 16b59b3e51257bdc1d36d87c50e047ff4df95857 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Tue, 14 Jul 2026 18:22:15 -0700 Subject: [PATCH 1/3] Add Completion Endpoint --- src/index.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 2379805..b0c9e02 100644 --- a/src/index.ts +++ b/src/index.ts @@ -61,7 +61,7 @@ app.listen(port, () => console.log(`Listening on PORT: ${port}`)) // app.get('/app-health-check', (_req, res) => res.sendStatus(200)) -app.post('/', async (req: Request, res: Response) => { +app.post(['/', '/chat'], async (req: Request, res: Response) => { // console.log('req.headers:', req.headers) // console.log('authorization:', req.headers.authorization) const { messages, system } = req.body @@ -84,6 +84,30 @@ app.post('/', async (req: Request, res: Response) => { pipeUIMessageStreamToResponse({ response: res, stream }) }) +app.post('/completion', async (req: Request, res: Response) => { + const { prompt, system } = req.body + console.log('prompt:', prompt.length, 'system:', system.length) + const result = streamText({ + model: model, + prompt, + system: system || process.env.COMPLETION_INSTRUCTIONS, + maxOutputTokens, + providerOptions, + onEnd({ finishReason, finalStep, text, usage }) { + console.log('finishReason:', finishReason) + console.log('usage:', usage) + console.log('reasoning:', finalStep.reasoningText) + console.log('response:', text) + }, + }) + const stream = createUIMessageStream({ + execute: ({ writer }) => { + writer.merge(toUIMessageStream({ stream: result.stream })) + }, + }) + pipeUIMessageStreamToResponse({ response: res, stream }) +}) + function corsCallback( origin: string | undefined, callback: (err: Error | null, origin?: boolean) => void, From 5161b933dd16ecd4b30be084d0f7f24dd255069c Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Tue, 14 Jul 2026 20:36:49 -0700 Subject: [PATCH 2/3] Cleanup --- src/index.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/index.ts b/src/index.ts index b0c9e02..b7c8ac4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ import { google } from '@ai-sdk/google' import { openai } from '@ai-sdk/openai' import { createOpenAICompatible } from '@ai-sdk/openai-compatible' import { + consumeStream, streamText, createUIMessageStream, pipeUIMessageStreamToResponse, @@ -85,19 +86,23 @@ app.post(['/', '/chat'], async (req: Request, res: Response) => { }) app.post('/completion', async (req: Request, res: Response) => { - const { prompt, system } = req.body - console.log('prompt:', prompt.length, 'system:', system.length) + const { prompt, system, signal } = req.body + console.log('prompt:', prompt?.length, 'system:', system?.length) const result = streamText({ model: model, prompt, system: system || process.env.COMPLETION_INSTRUCTIONS, maxOutputTokens, providerOptions, - onEnd({ finishReason, finalStep, text, usage }) { - console.log('finishReason:', finishReason) - console.log('usage:', usage) + abortSignal: signal, + onError({ error }) { + console.log('error:', error) + }, + onEnd({ finalStep, finishReason, text, usage }) { console.log('reasoning:', finalStep.reasoningText) console.log('response:', text) + console.log('usage:', usage) + console.log('finishReason:', finishReason) }, }) const stream = createUIMessageStream({ @@ -105,7 +110,11 @@ app.post('/completion', async (req: Request, res: Response) => { writer.merge(toUIMessageStream({ stream: result.stream })) }, }) - pipeUIMessageStreamToResponse({ response: res, stream }) + pipeUIMessageStreamToResponse({ + response: res, + stream, + consumeSseStream: consumeStream, + }) }) function corsCallback( From 091be2300fa2e01606e58a86f24065e48c2cf7db Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Tue, 14 Jul 2026 21:57:42 -0700 Subject: [PATCH 3/3] Add /object --- src/index.ts | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index b7c8ac4..7bd2e39 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,11 +7,14 @@ import { google } from '@ai-sdk/google' import { openai } from '@ai-sdk/openai' import { createOpenAICompatible } from '@ai-sdk/openai-compatible' import { + Output, consumeStream, + pipeTextStreamToResponse, streamText, createUIMessageStream, pipeUIMessageStreamToResponse, convertToModelMessages, + toTextStream, toUIMessageStream, } from 'ai' @@ -43,7 +46,11 @@ const maxOutputTokens = process.env.MAX_TOKENS ? Number.parseInt(process.env.MAX_TOKENS) : undefined console.log(`maxOutputTokens: ${maxOutputTokens}`) -console.log(`INSTRUCTIONS: ${process.env.INSTRUCTIONS}`) +console.log( + `CHAT_INSTRUCTIONS: ${process.env.INSTRUCTIONS || process.env.CHAT_INSTRUCTIONS}`, // NOSONAR +) +console.log(`COMPLETION_INSTRUCTIONS: ${process.env.COMPLETION_INSTRUCTIONS}`) +console.log(`OBJECT_INSTRUCTIONS: ${process.env.OBJECT_INSTRUCTIONS}`) const model = getModel() console.log(`Loaded modelId: ${model.modelId}`) @@ -74,7 +81,7 @@ app.post(['/', '/chat'], async (req: Request, res: Response) => { const result = streamText({ model: model, messages: modelMessages, - system: system || process.env.INSTRUCTIONS, + system: system || process.env.INSTRUCTIONS || process.env.CHAT_INSTRUCTIONS, maxOutputTokens, providerOptions, }) @@ -86,7 +93,7 @@ app.post(['/', '/chat'], async (req: Request, res: Response) => { }) app.post('/completion', async (req: Request, res: Response) => { - const { prompt, system, signal } = req.body + const { prompt, system } = req.body console.log('prompt:', prompt?.length, 'system:', system?.length) const result = streamText({ model: model, @@ -94,8 +101,7 @@ app.post('/completion', async (req: Request, res: Response) => { system: system || process.env.COMPLETION_INSTRUCTIONS, maxOutputTokens, providerOptions, - abortSignal: signal, - onError({ error }) { + onError(error) { console.log('error:', error) }, onEnd({ finalStep, finishReason, text, usage }) { @@ -117,6 +123,32 @@ app.post('/completion', async (req: Request, res: Response) => { }) }) +app.post('/object', async (req: Request, res: Response) => { + const { outputSchema, prompt, system } = req.body + console.log('prompt:', prompt?.length, 'system:', system?.length) + const result = streamText({ + model: model, + prompt, + system: system || process.env.OBJECT_INSTRUCTIONS, + maxOutputTokens, + providerOptions, + output: outputSchema ? Output.object({ schema: outputSchema }) : Output.json(), + onError(error) { + console.log('error:', error) + }, + onEnd({ finalStep, finishReason, text, usage }) { + console.log('reasoning:', finalStep.reasoningText) + console.log('response:', text) + console.log('usage:', usage) + console.log('finishReason:', finishReason) + }, + }) + pipeTextStreamToResponse({ + response: res, + stream: toTextStream({ stream: result.stream }), + }) +}) + function corsCallback( origin: string | undefined, callback: (err: Error | null, origin?: boolean) => void,