feat(core-api): wire real gcs upload and vertex llm in dev
This commit is contained in:
@@ -5,6 +5,8 @@ import { AppError } from '../lib/errors.js';
|
||||
import { requireAuth, requirePolicy } from '../middleware/auth.js';
|
||||
import { createSignedUrlSchema } from '../contracts/core/create-signed-url.js';
|
||||
import { invokeLlmSchema } from '../contracts/core/invoke-llm.js';
|
||||
import { invokeVertexModel } from '../services/llm.js';
|
||||
import { generateReadSignedUrl, uploadToGcs } from '../services/storage.js';
|
||||
|
||||
const DEFAULT_MAX_FILE_BYTES = 10 * 1024 * 1024;
|
||||
const ALLOWED_FILE_TYPES = new Set(['application/pdf', 'image/jpeg', 'image/jpg', 'image/png']);
|
||||
@@ -30,6 +32,14 @@ function mockSignedUrl(fileUri, expiresInSeconds) {
|
||||
};
|
||||
}
|
||||
|
||||
function useMockSignedUrl() {
|
||||
return process.env.SIGNED_URL_MOCK !== 'false';
|
||||
}
|
||||
|
||||
function useMockUpload() {
|
||||
return process.env.UPLOAD_MOCK !== 'false';
|
||||
}
|
||||
|
||||
function parseBody(schema, body) {
|
||||
const parsed = schema.safeParse(body);
|
||||
if (!parsed.success) {
|
||||
@@ -64,9 +74,19 @@ async function handleUploadFile(req, res, next) {
|
||||
|
||||
const safeName = file.originalname.replace(/[^a-zA-Z0-9._-]/g, '_');
|
||||
const objectPath = `uploads/${req.actor.uid}/${Date.now()}_${safeName}`;
|
||||
const fileUri = `gs://${bucket}/${objectPath}`;
|
||||
|
||||
if (!useMockUpload()) {
|
||||
await uploadToGcs({
|
||||
bucket,
|
||||
objectPath,
|
||||
contentType: file.mimetype,
|
||||
buffer: file.buffer,
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
fileUri: `gs://${bucket}/${objectPath}`,
|
||||
fileUri,
|
||||
contentType: file.mimetype,
|
||||
size: file.size,
|
||||
bucket,
|
||||
@@ -85,8 +105,12 @@ async function handleCreateSignedUrl(req, res, next) {
|
||||
try {
|
||||
const payload = parseBody(createSignedUrlSchema, req.body || {});
|
||||
const expiresInSeconds = payload.expiresInSeconds || 300;
|
||||
|
||||
const signed = mockSignedUrl(payload.fileUri, expiresInSeconds);
|
||||
const signed = useMockSignedUrl()
|
||||
? mockSignedUrl(payload.fileUri, expiresInSeconds)
|
||||
: await generateReadSignedUrl({
|
||||
fileUri: payload.fileUri,
|
||||
expiresInSeconds,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
...signed,
|
||||
@@ -101,12 +125,22 @@ async function handleInvokeLlm(req, res, next) {
|
||||
try {
|
||||
const payload = parseBody(invokeLlmSchema, req.body || {});
|
||||
|
||||
const startedAt = Date.now();
|
||||
if (process.env.LLM_MOCK === 'false') {
|
||||
throw new AppError('MODEL_FAILED', 'Real model integration not wired yet', 501);
|
||||
const llmResult = await invokeVertexModel({
|
||||
prompt: payload.prompt,
|
||||
responseJsonSchema: payload.responseJsonSchema,
|
||||
fileUrls: payload.fileUrls,
|
||||
});
|
||||
return res.status(200).json({
|
||||
result: llmResult.result,
|
||||
model: llmResult.model,
|
||||
latencyMs: Date.now() - startedAt,
|
||||
requestId: req.requestId,
|
||||
});
|
||||
}
|
||||
|
||||
const startedAt = Date.now();
|
||||
res.status(200).json({
|
||||
return res.status(200).json({
|
||||
result: {
|
||||
summary: 'Mock model response. Replace with Vertex AI integration.',
|
||||
inputPromptSize: payload.prompt.length,
|
||||
|
||||
Reference in New Issue
Block a user