feat(core-api): wire real gcs upload and vertex llm in dev

This commit is contained in:
zouantchaw
2026-02-24 09:58:22 -05:00
parent d3aec0da0b
commit e733f36d28
7 changed files with 223 additions and 59 deletions

View File

@@ -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,