Spaces:
Sleeping
Sleeping
done
Browse files
app/api/vision-agent/route.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { getPresignedUrl } from '@/lib/aws';
|
|
| 11 |
// export const runtime = 'edge';
|
| 12 |
export const dynamic = 'force-dynamic';
|
| 13 |
export const maxDuration = 300; // This function can run for a maximum of 5 minutes
|
|
|
|
| 14 |
|
| 15 |
const uploadBase64 = async (
|
| 16 |
base64: string,
|
|
@@ -92,7 +93,7 @@ export const POST = withLogging(
|
|
| 92 |
const fetchResponse = await fetch(
|
| 93 |
// `https://api.dev.landing.ai/v1/agent/chat?agent_class=vision_agent&self_reflection=false`,
|
| 94 |
`https://api.landing.ai/v1/agent/chat?agent_class=vision_agent&self_reflection=false`,
|
| 95 |
-
// `http://localhost:5001/v1/agent/chat?agent_class=vision_agent&self_reflection
|
| 96 |
{
|
| 97 |
method: 'POST',
|
| 98 |
headers: {
|
|
@@ -150,6 +151,7 @@ export const POST = withLogging(
|
|
| 150 |
const decoder = new TextDecoder('utf-8');
|
| 151 |
let maxChunkSize = 0;
|
| 152 |
let buffer = '';
|
|
|
|
| 153 |
const stream = new ReadableStream({
|
| 154 |
async start(controller) {
|
| 155 |
// const parser = createParser(streamParser);
|
|
@@ -160,6 +162,23 @@ export const POST = withLogging(
|
|
| 160 |
const lines = buffer
|
| 161 |
.split('\n')
|
| 162 |
.filter(line => line.trim().length > 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
buffer = lines.pop() ?? ''; // Save the last incomplete line back to the buffer
|
| 164 |
let done = false;
|
| 165 |
const parseLine = async (
|
|
@@ -168,9 +187,32 @@ export const POST = withLogging(
|
|
| 168 |
) => {
|
| 169 |
try {
|
| 170 |
const msg = JSON.parse(line);
|
| 171 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
return line;
|
| 173 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
const result = JSON.parse(msg.payload.result) as ResultPayload;
|
| 175 |
for (let index = 0; index < result.results.length; index++) {
|
| 176 |
const png = result.results[index].png ?? '';
|
|
|
|
| 11 |
// export const runtime = 'edge';
|
| 12 |
export const dynamic = 'force-dynamic';
|
| 13 |
export const maxDuration = 300; // This function can run for a maximum of 5 minutes
|
| 14 |
+
const TIMEOUT_MILI_SECONDS = 5 * 60 * 1000;
|
| 15 |
|
| 16 |
const uploadBase64 = async (
|
| 17 |
base64: string,
|
|
|
|
| 93 |
const fetchResponse = await fetch(
|
| 94 |
// `https://api.dev.landing.ai/v1/agent/chat?agent_class=vision_agent&self_reflection=false`,
|
| 95 |
`https://api.landing.ai/v1/agent/chat?agent_class=vision_agent&self_reflection=false`,
|
| 96 |
+
// `http://localhost:5001/v1/agent/chat?agent_class=vision_agent&self_reflection=false`,
|
| 97 |
{
|
| 98 |
method: 'POST',
|
| 99 |
headers: {
|
|
|
|
| 151 |
const decoder = new TextDecoder('utf-8');
|
| 152 |
let maxChunkSize = 0;
|
| 153 |
let buffer = '';
|
| 154 |
+
let time = Date.now();
|
| 155 |
const stream = new ReadableStream({
|
| 156 |
async start(controller) {
|
| 157 |
// const parser = createParser(streamParser);
|
|
|
|
| 162 |
const lines = buffer
|
| 163 |
.split('\n')
|
| 164 |
.filter(line => line.trim().length > 0);
|
| 165 |
+
if (lines.length === 0) {
|
| 166 |
+
if (Date.now() - time > TIMEOUT_MILI_SECONDS) {
|
| 167 |
+
logger.info(
|
| 168 |
+
session,
|
| 169 |
+
{
|
| 170 |
+
message: 'Agent timed out',
|
| 171 |
+
},
|
| 172 |
+
request,
|
| 173 |
+
'__Agent_timeout__',
|
| 174 |
+
);
|
| 175 |
+
controller.error(
|
| 176 |
+
`Haven't received any response in last ${TIMEOUT_MILI_SECONDS / 60000} minutes, agent timed out.`,
|
| 177 |
+
);
|
| 178 |
+
}
|
| 179 |
+
} else {
|
| 180 |
+
time = Date.now();
|
| 181 |
+
}
|
| 182 |
buffer = lines.pop() ?? ''; // Save the last incomplete line back to the buffer
|
| 183 |
let done = false;
|
| 184 |
const parseLine = async (
|
|
|
|
| 187 |
) => {
|
| 188 |
try {
|
| 189 |
const msg = JSON.parse(line);
|
| 190 |
+
if (
|
| 191 |
+
msg.type !== 'final_code' &&
|
| 192 |
+
(msg.type !== 'code' ||
|
| 193 |
+
msg.status === 'started' ||
|
| 194 |
+
msg.status === 'running')
|
| 195 |
+
) {
|
| 196 |
return line;
|
| 197 |
}
|
| 198 |
+
if (msg.type === 'code') {
|
| 199 |
+
const result = JSON.parse(
|
| 200 |
+
msg.payload.result,
|
| 201 |
+
) as ResultPayload;
|
| 202 |
+
if (result && result.results) {
|
| 203 |
+
msg.payload.result = JSON.stringify({
|
| 204 |
+
...result,
|
| 205 |
+
results: result.results.map((_result: any) => {
|
| 206 |
+
return {
|
| 207 |
+
..._result,
|
| 208 |
+
png: undefined,
|
| 209 |
+
mp4: undefined,
|
| 210 |
+
};
|
| 211 |
+
}),
|
| 212 |
+
});
|
| 213 |
+
}
|
| 214 |
+
return JSON.stringify(msg);
|
| 215 |
+
}
|
| 216 |
const result = JSON.parse(msg.payload.result) as ResultPayload;
|
| 217 |
for (let index = 0; index < result.results.length; index++) {
|
| 218 |
const png = result.results[index].png ?? '';
|
components/chat/ChatMessage.tsx
CHANGED
|
@@ -29,7 +29,6 @@ import { selectedMessageId } from '@/state/chat';
|
|
| 29 |
import { Message } from '@prisma/client';
|
| 30 |
import { Separator } from '../ui/Separator';
|
| 31 |
import { cn } from '@/lib/utils';
|
| 32 |
-
import { usePrevious } from '@/lib/hooks/usePrevious';
|
| 33 |
|
| 34 |
export interface ChatMessageProps {
|
| 35 |
message: Message;
|
|
|
|
| 29 |
import { Message } from '@prisma/client';
|
| 30 |
import { Separator } from '../ui/Separator';
|
| 31 |
import { cn } from '@/lib/utils';
|
|
|
|
| 32 |
|
| 33 |
export interface ChatMessageProps {
|
| 34 |
message: Message;
|