mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 04:29:51 +08:00
refactor: simpler streaming preview and small AI SDK cleanups
- useChat throttles streamed message updates (experimental_throttle, 150 ms), replacing the two hand-written 150 ms timers of the display_diagram and edit_diagram previews (94 lines less). The preview now only runs while the input streams; once it is complete the tool handler takes over, so a queued preview can no longer redraw an edit the handler rejected and rolled back. Measured on a streamed 60-cell diagram: 41 redraws at least 97 ms apart, before 37 with gaps down to 48 ms - The diagram check endpoint uses streamText with Output.object instead of the deprecated streamObject, and returns its fixed result as a plain text response; new route test - Import createGateway/gateway from ai and drop the direct @ai-sdk/gateway dependency - The per-request message structure logs only print with DEBUG_LLM_PAYLOAD=true - Remove an empty onFinish callback
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* Accepts a PNG image and streams validation results using useObject-compatible format.
|
||||
*/
|
||||
|
||||
import { streamObject } from "ai"
|
||||
import { Output, streamText } from "ai"
|
||||
import { checkAccessCode } from "@/lib/access-code"
|
||||
import { getValidationModel } from "@/lib/ai-providers"
|
||||
import { VALIDATION_SYSTEM_PROMPT } from "@/lib/validation-prompts"
|
||||
@@ -29,20 +29,9 @@ const DEFAULT_VALID_RESULT: ValidationResult = {
|
||||
suggestions: [],
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a streaming response for useObject compatibility.
|
||||
* useObject expects text stream format, not plain JSON.
|
||||
*/
|
||||
/** A fixed result in the text format useObject reads */
|
||||
function createStreamingResponse(result: ValidationResult): Response {
|
||||
const encoder = new TextEncoder()
|
||||
const stream = new ReadableStream({
|
||||
start(controller) {
|
||||
// Stream the JSON as text (useObject parses this)
|
||||
controller.enqueue(encoder.encode(JSON.stringify(result)))
|
||||
controller.close()
|
||||
},
|
||||
})
|
||||
return new Response(stream, {
|
||||
return new Response(JSON.stringify(result), {
|
||||
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
||||
})
|
||||
}
|
||||
@@ -108,9 +97,9 @@ export async function POST(req: Request): Promise<Response> {
|
||||
) || 10000
|
||||
|
||||
// Stream the VLM response for useObject consumption
|
||||
const result = streamObject({
|
||||
const result = streamText({
|
||||
model,
|
||||
schema: ValidationResultSchema,
|
||||
output: Output.object({ schema: ValidationResultSchema }),
|
||||
system: VALIDATION_SYSTEM_PROMPT,
|
||||
messages: [
|
||||
{
|
||||
@@ -129,10 +118,10 @@ export async function POST(req: Request): Promise<Response> {
|
||||
],
|
||||
maxOutputTokens: 1024,
|
||||
abortSignal: AbortSignal.timeout(timeout),
|
||||
onFinish: ({ object }) => {
|
||||
if (sessionId && object) {
|
||||
onFinish: ({ output }) => {
|
||||
if (sessionId && output) {
|
||||
console.log(
|
||||
`[validate-diagram] Session ${sessionId}: valid=${object.valid}, issues=${object.issues?.length ?? 0}`,
|
||||
`[validate-diagram] Session ${sessionId}: valid=${output.valid}, issues=${output.issues?.length ?? 0}`,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user