Spaces:
Build error
Build error
Colab User commited on
Commit ·
eab050b
1
Parent(s): 51ffef2
Initial commit: Deploy rasa-engine API server
Browse files- .dockerignore +7 -0
- Dockerfile +28 -0
- artifacts/api-server/build.mjs +125 -0
- artifacts/api-server/package.json +33 -0
- artifacts/api-server/src/app.ts +34 -0
- artifacts/api-server/src/index.ts +25 -0
- artifacts/api-server/src/lib/logger.ts +20 -0
- artifacts/api-server/src/routes/health.ts +11 -0
- artifacts/api-server/src/routes/index.ts +10 -0
- artifacts/api-server/src/routes/rasa/index.ts +153 -0
- artifacts/api-server/tsconfig.json +20 -0
- lib/api-spec/openapi.yaml +207 -0
- lib/api-spec/orval.config.ts +72 -0
- lib/api-spec/package.json +11 -0
- lib/db/drizzle.config.ts +14 -0
- lib/db/package.json +25 -0
- lib/db/src/index.ts +16 -0
- lib/db/src/schema/index.ts +20 -0
- lib/db/src/schema/rasa_analyses.ts +21 -0
- lib/db/tsconfig.json +12 -0
- package.json +16 -0
- pnpm-workspace.yaml +159 -0
- tsconfig.base.json +25 -0
- tsconfig.json +19 -0
.dockerignore
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
build
|
| 3 |
+
.env
|
| 4 |
+
.git
|
| 5 |
+
.vscode
|
| 6 |
+
*.log
|
| 7 |
+
*.tgz
|
Dockerfile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Use an official Node.js runtime as a parent image
|
| 2 |
+
FROM node:18-alpine
|
| 3 |
+
|
| 4 |
+
# Set the working directory in the container
|
| 5 |
+
WORKDIR /app
|
| 6 |
+
|
| 7 |
+
# Install pnpm
|
| 8 |
+
RUN npm install -g pnpm
|
| 9 |
+
|
| 10 |
+
# Copy package.json and pnpm-workspace.yaml to leverage Docker cache
|
| 11 |
+
COPY package.json pnpm-workspace.yaml ./
|
| 12 |
+
COPY artifacts/api-server/package.json artifacts/api-server/
|
| 13 |
+
COPY lib/db/package.json lib/db/
|
| 14 |
+
|
| 15 |
+
# Install dependencies
|
| 16 |
+
RUN pnpm install --frozen-lockfile
|
| 17 |
+
|
| 18 |
+
# Copy the rest of the application code
|
| 19 |
+
COPY . .
|
| 20 |
+
|
| 21 |
+
# Build the api-server project
|
| 22 |
+
RUN pnpm run build --filter=@workspace/api-server
|
| 23 |
+
|
| 24 |
+
# Expose the port the app runs on
|
| 25 |
+
EXPOSE 3000
|
| 26 |
+
|
| 27 |
+
# Define the command to run the app
|
| 28 |
+
CMD ["node", "./artifacts/api-server/build/index.mjs"]
|
artifacts/api-server/build.mjs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createRequire } from "node:module";
|
| 2 |
+
import path from "node:path";
|
| 3 |
+
import { fileURLToPath } from "node:url";
|
| 4 |
+
import { build as esbuild } from "esbuild";
|
| 5 |
+
import esbuildPluginPino from "esbuild-plugin-pino";
|
| 6 |
+
import { rm } from "node:fs/promises";
|
| 7 |
+
|
| 8 |
+
// Plugins (e.g. 'esbuild-plugin-pino') may use `require` to resolve dependencies
|
| 9 |
+
globalThis.require = createRequire(import.meta.url);
|
| 10 |
+
|
| 11 |
+
const artifactDir = path.dirname(fileURLToPath(import.meta.url));
|
| 12 |
+
|
| 13 |
+
async function buildAll() {
|
| 14 |
+
const distDir = path.resolve(artifactDir, "dist");
|
| 15 |
+
await rm(distDir, { recursive: true, force: true });
|
| 16 |
+
|
| 17 |
+
await esbuild({
|
| 18 |
+
entryPoints: [path.resolve(artifactDir, "src/index.ts")],
|
| 19 |
+
platform: "node",
|
| 20 |
+
bundle: true,
|
| 21 |
+
format: "esm",
|
| 22 |
+
outdir: distDir,
|
| 23 |
+
outExtension: { ".js": ".mjs" },
|
| 24 |
+
logLevel: "info",
|
| 25 |
+
// Some packages may not be bundleable, so we externalize them, we can add more here as needed.
|
| 26 |
+
// Some of the packages below may not be imported or installed, but we're adding them in case they are in the future.
|
| 27 |
+
// Examples of unbundleable packages:
|
| 28 |
+
// - uses native modules and loads them dynamically (e.g. sharp)
|
| 29 |
+
// - use path traversal to read files (e.g. @google-cloud/secret-manager loads sibling .proto files)
|
| 30 |
+
external: [
|
| 31 |
+
"*.node",
|
| 32 |
+
"sharp",
|
| 33 |
+
"better-sqlite3",
|
| 34 |
+
"sqlite3",
|
| 35 |
+
"canvas",
|
| 36 |
+
"bcrypt",
|
| 37 |
+
"argon2",
|
| 38 |
+
"fsevents",
|
| 39 |
+
"re2",
|
| 40 |
+
"farmhash",
|
| 41 |
+
"xxhash-addon",
|
| 42 |
+
"bufferutil",
|
| 43 |
+
"utf-8-validate",
|
| 44 |
+
"ssh2",
|
| 45 |
+
"cpu-features",
|
| 46 |
+
"dtrace-provider",
|
| 47 |
+
"isolated-vm",
|
| 48 |
+
"lightningcss",
|
| 49 |
+
"pg-native",
|
| 50 |
+
"oracledb",
|
| 51 |
+
"mongodb-client-encryption",
|
| 52 |
+
"nodemailer",
|
| 53 |
+
"handlebars",
|
| 54 |
+
"knex",
|
| 55 |
+
"typeorm",
|
| 56 |
+
"protobufjs",
|
| 57 |
+
"onnxruntime-node",
|
| 58 |
+
"@tensorflow/*",
|
| 59 |
+
"@prisma/client",
|
| 60 |
+
"@mikro-orm/*",
|
| 61 |
+
"@grpc/*",
|
| 62 |
+
"@swc/*",
|
| 63 |
+
"@aws-sdk/*",
|
| 64 |
+
"@azure/*",
|
| 65 |
+
"@opentelemetry/*",
|
| 66 |
+
"@google-cloud/*",
|
| 67 |
+
"googleapis",
|
| 68 |
+
"firebase-admin",
|
| 69 |
+
"@parcel/watcher",
|
| 70 |
+
"@sentry/profiling-node",
|
| 71 |
+
"@tree-sitter/*",
|
| 72 |
+
"aws-sdk",
|
| 73 |
+
"classic-level",
|
| 74 |
+
"dd-trace",
|
| 75 |
+
"ffi-napi",
|
| 76 |
+
"grpc",
|
| 77 |
+
"hiredis",
|
| 78 |
+
"kerberos",
|
| 79 |
+
"leveldown",
|
| 80 |
+
"miniflare",
|
| 81 |
+
"mysql2",
|
| 82 |
+
"newrelic",
|
| 83 |
+
"odbc",
|
| 84 |
+
"piscina",
|
| 85 |
+
"realm",
|
| 86 |
+
"ref-napi",
|
| 87 |
+
"rocksdb",
|
| 88 |
+
"sass-embedded",
|
| 89 |
+
"sequelize",
|
| 90 |
+
"serialport",
|
| 91 |
+
"snappy",
|
| 92 |
+
"tinypool",
|
| 93 |
+
"usb",
|
| 94 |
+
"workerd",
|
| 95 |
+
"wrangler",
|
| 96 |
+
"zeromq",
|
| 97 |
+
"zeromq-prebuilt",
|
| 98 |
+
"playwright",
|
| 99 |
+
"puppeteer",
|
| 100 |
+
"puppeteer-core",
|
| 101 |
+
"electron",
|
| 102 |
+
],
|
| 103 |
+
sourcemap: "linked",
|
| 104 |
+
plugins: [
|
| 105 |
+
// pino relies on workers to handle logging, instead of externalizing it we use a plugin to handle it
|
| 106 |
+
esbuildPluginPino({ transports: ["pino-pretty"] })
|
| 107 |
+
],
|
| 108 |
+
// Make sure packages that are cjs only (e.g. express) but are bundled continue to work in our esm output file
|
| 109 |
+
banner: {
|
| 110 |
+
js: `import { createRequire as __bannerCrReq } from 'node:module';
|
| 111 |
+
import __bannerPath from 'node:path';
|
| 112 |
+
import __bannerUrl from 'node:url';
|
| 113 |
+
|
| 114 |
+
globalThis.require = __bannerCrReq(import.meta.url);
|
| 115 |
+
globalThis.__filename = __bannerUrl.fileURLToPath(import.meta.url);
|
| 116 |
+
globalThis.__dirname = __bannerPath.dirname(globalThis.__filename);
|
| 117 |
+
`,
|
| 118 |
+
},
|
| 119 |
+
});
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
buildAll().catch((err) => {
|
| 123 |
+
console.error(err);
|
| 124 |
+
process.exit(1);
|
| 125 |
+
});
|
artifacts/api-server/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "@workspace/api-server",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"type": "module",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"dev": "export NODE_ENV=development && pnpm run build && pnpm run start",
|
| 8 |
+
"build": "node ./build.mjs",
|
| 9 |
+
"start": "node --enable-source-maps ./dist/index.mjs",
|
| 10 |
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
| 11 |
+
},
|
| 12 |
+
"dependencies": {
|
| 13 |
+
"@workspace/api-zod": "workspace:*",
|
| 14 |
+
"@workspace/db": "workspace:*",
|
| 15 |
+
"@workspace/integrations-gemini-ai": "workspace:*",
|
| 16 |
+
"cookie-parser": "^1.4.7",
|
| 17 |
+
"cors": "^2",
|
| 18 |
+
"drizzle-orm": "catalog:",
|
| 19 |
+
"express": "^5",
|
| 20 |
+
"pino": "^9",
|
| 21 |
+
"pino-http": "^10"
|
| 22 |
+
},
|
| 23 |
+
"devDependencies": {
|
| 24 |
+
"@types/cookie-parser": "^1.4.10",
|
| 25 |
+
"@types/cors": "^2.8.19",
|
| 26 |
+
"@types/express": "^5.0.6",
|
| 27 |
+
"@types/node": "catalog:",
|
| 28 |
+
"esbuild": "^0.27.3",
|
| 29 |
+
"esbuild-plugin-pino": "^2.3.3",
|
| 30 |
+
"pino-pretty": "^13",
|
| 31 |
+
"thread-stream": "3.1.0"
|
| 32 |
+
}
|
| 33 |
+
}
|
artifacts/api-server/src/app.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import express, { type Express } from "express";
|
| 2 |
+
import cors from "cors";
|
| 3 |
+
import pinoHttp from "pino-http";
|
| 4 |
+
import router from "./routes";
|
| 5 |
+
import { logger } from "./lib/logger";
|
| 6 |
+
|
| 7 |
+
const app: Express = express();
|
| 8 |
+
|
| 9 |
+
app.use(
|
| 10 |
+
pinoHttp({
|
| 11 |
+
logger,
|
| 12 |
+
serializers: {
|
| 13 |
+
req(req) {
|
| 14 |
+
return {
|
| 15 |
+
id: req.id,
|
| 16 |
+
method: req.method,
|
| 17 |
+
url: req.url?.split("?")[0],
|
| 18 |
+
};
|
| 19 |
+
},
|
| 20 |
+
res(res) {
|
| 21 |
+
return {
|
| 22 |
+
statusCode: res.statusCode,
|
| 23 |
+
};
|
| 24 |
+
},
|
| 25 |
+
},
|
| 26 |
+
}),
|
| 27 |
+
);
|
| 28 |
+
app.use(cors());
|
| 29 |
+
app.use(express.json());
|
| 30 |
+
app.use(express.urlencoded({ extended: true }));
|
| 31 |
+
|
| 32 |
+
app.use("/api", router);
|
| 33 |
+
|
| 34 |
+
export default app;
|
artifacts/api-server/src/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import app from "./app";
|
| 2 |
+
import { logger } from "./lib/logger";
|
| 3 |
+
|
| 4 |
+
const rawPort = process.env["PORT"];
|
| 5 |
+
|
| 6 |
+
if (!rawPort) {
|
| 7 |
+
throw new Error(
|
| 8 |
+
"PORT environment variable is required but was not provided.",
|
| 9 |
+
);
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
const port = Number(rawPort);
|
| 13 |
+
|
| 14 |
+
if (Number.isNaN(port) || port <= 0) {
|
| 15 |
+
throw new Error(`Invalid PORT value: "${rawPort}"`);
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
app.listen(port, (err) => {
|
| 19 |
+
if (err) {
|
| 20 |
+
logger.error({ err }, "Error listening on port");
|
| 21 |
+
process.exit(1);
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
logger.info({ port }, "Server listening");
|
| 25 |
+
});
|
artifacts/api-server/src/lib/logger.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pino from "pino";
|
| 2 |
+
|
| 3 |
+
const isProduction = process.env.NODE_ENV === "production";
|
| 4 |
+
|
| 5 |
+
export const logger = pino({
|
| 6 |
+
level: process.env.LOG_LEVEL ?? "info",
|
| 7 |
+
redact: [
|
| 8 |
+
"req.headers.authorization",
|
| 9 |
+
"req.headers.cookie",
|
| 10 |
+
"res.headers['set-cookie']",
|
| 11 |
+
],
|
| 12 |
+
...(isProduction
|
| 13 |
+
? {}
|
| 14 |
+
: {
|
| 15 |
+
transport: {
|
| 16 |
+
target: "pino-pretty",
|
| 17 |
+
options: { colorize: true },
|
| 18 |
+
},
|
| 19 |
+
}),
|
| 20 |
+
});
|
artifacts/api-server/src/routes/health.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Router, type IRouter } from "express";
|
| 2 |
+
import { HealthCheckResponse } from "@workspace/api-zod";
|
| 3 |
+
|
| 4 |
+
const router: IRouter = Router();
|
| 5 |
+
|
| 6 |
+
router.get("/healthz", (_req, res) => {
|
| 7 |
+
const data = HealthCheckResponse.parse({ status: "ok" });
|
| 8 |
+
res.json(data);
|
| 9 |
+
});
|
| 10 |
+
|
| 11 |
+
export default router;
|
artifacts/api-server/src/routes/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Router, type IRouter } from "express";
|
| 2 |
+
import healthRouter from "./health";
|
| 3 |
+
import rasaRouter from "./rasa";
|
| 4 |
+
|
| 5 |
+
const router: IRouter = Router();
|
| 6 |
+
|
| 7 |
+
router.use(healthRouter);
|
| 8 |
+
router.use("/rasa", rasaRouter);
|
| 9 |
+
|
| 10 |
+
export default router;
|
artifacts/api-server/src/routes/rasa/index.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { Router } from "express";
|
| 2 |
+
import { db } from "@workspace/db";
|
| 3 |
+
import { rasaAnalysesTable } from "@workspace/db";
|
| 4 |
+
import { AnalyzeRasaBody, DeleteRasaHistoryParams, GetRasaHistoryQueryParams } from "@workspace/api-zod";
|
| 5 |
+
import { ai } from "@workspace/integrations-gemini-ai";
|
| 6 |
+
import { desc, eq } from "drizzle-orm";
|
| 7 |
+
|
| 8 |
+
const router = Router();
|
| 9 |
+
|
| 10 |
+
const SYSTEM_PROMPT = `You are a Vedic Rasa Analysis engine built on three ancient sutras from the Vedic Sutras Framework:
|
| 11 |
+
|
| 12 |
+
1. **Natya Shastra / Rasa Sutras (Sutra 13)** — The Sentiment Analysis framework by Bharata Muni. The 9 primary Rasas (emotional essences) and their extended forms encode all human emotion into a deterministic matrix.
|
| 13 |
+
|
| 14 |
+
2. **Yoga Sutras of Patanjali (Sutra 10)** — The Attention & Memory framework. Dharana (focused attention) enables precise analysis by eliminating noise (Vritti) and isolating the core emotional signal.
|
| 15 |
+
|
| 16 |
+
3. **Nyaya Sutras (Sutra 3)** — The AI Logic & Inference framework by Akshapada Gautama. Apply the 5-step Pramana: Pratijna (hypothesis), Hetu (reason), Udaharana (example), Upanaya (application), Nigamana (conclusion).
|
| 17 |
+
|
| 18 |
+
**Rasa Detection:**
|
| 19 |
+
Identify the dominant Rasa from this extended set: Love, Laughter, Compassion, Fury, Heroism, Fear, Disgust, Wonder, Peace, Surprise, Sadness, Calm, Courage, Mystery, Wisdom
|
| 20 |
+
|
| 21 |
+
**Hallucination Detection:**
|
| 22 |
+
Analyze the text for factual inaccuracies, unsupported claims, logical fallacies, or fabricated information. Score from 0.0 (fully grounded) to 1.0 (completely hallucinated).
|
| 23 |
+
|
| 24 |
+
Return ONLY valid JSON with this exact structure (no markdown, no extra text):
|
| 25 |
+
{
|
| 26 |
+
"rasa": {
|
| 27 |
+
"name": "<one of the 15 Rasas>",
|
| 28 |
+
"confidence": <float 0.0-1.0>,
|
| 29 |
+
"explanation": "<brief Vedic-informed explanation of why this Rasa dominates>"
|
| 30 |
+
},
|
| 31 |
+
"hallucination": {
|
| 32 |
+
"score": <float 0.0-1.0>,
|
| 33 |
+
"severity": "<none|low|medium|high|critical>",
|
| 34 |
+
"problematic_statements": ["<statement1>", "<statement2>"]
|
| 35 |
+
},
|
| 36 |
+
"summary": "<1-2 sentence synthesis of the text's essence through the Vedic lens>"
|
| 37 |
+
}`;
|
| 38 |
+
|
| 39 |
+
router.post("/analyze", async (req, res) => {
|
| 40 |
+
const parsed = AnalyzeRasaBody.safeParse(req.body);
|
| 41 |
+
if (!parsed.success) {
|
| 42 |
+
return res.status(400).json({ error: "Invalid request body" });
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
const { text } = parsed.data;
|
| 46 |
+
|
| 47 |
+
if (!text || text.trim().length === 0) {
|
| 48 |
+
return res.status(400).json({ error: "Text is required" });
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
if (text.length > 10000) {
|
| 52 |
+
return res.status(400).json({ error: "Text must be 10,000 characters or less" });
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
try {
|
| 56 |
+
const response = await ai.models.generateContent({
|
| 57 |
+
model: "gemini-2.5-flash",
|
| 58 |
+
contents: [
|
| 59 |
+
{
|
| 60 |
+
role: "user",
|
| 61 |
+
parts: [{ text: `Analyze this text using the Vedic Rasa and Nyaya Sutra frameworks:\n\n${text}` }],
|
| 62 |
+
},
|
| 63 |
+
],
|
| 64 |
+
config: {
|
| 65 |
+
systemInstruction: SYSTEM_PROMPT,
|
| 66 |
+
responseMimeType: "application/json",
|
| 67 |
+
maxOutputTokens: 8192,
|
| 68 |
+
},
|
| 69 |
+
});
|
| 70 |
+
|
| 71 |
+
const rawText = response.text ?? "{}";
|
| 72 |
+
|
| 73 |
+
let analysis: {
|
| 74 |
+
rasa: { name: string; confidence: number; explanation: string };
|
| 75 |
+
hallucination: { score: number; severity: string; problematic_statements: string[] };
|
| 76 |
+
summary: string;
|
| 77 |
+
};
|
| 78 |
+
|
| 79 |
+
try {
|
| 80 |
+
analysis = JSON.parse(rawText);
|
| 81 |
+
} catch {
|
| 82 |
+
return res.status(500).json({ error: "Failed to parse AI response" });
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
const timestamp = Date.now();
|
| 86 |
+
|
| 87 |
+
await db.insert(rasaAnalysesTable).values({
|
| 88 |
+
text,
|
| 89 |
+
rasa_name: analysis.rasa.name,
|
| 90 |
+
rasa_confidence: analysis.rasa.confidence,
|
| 91 |
+
rasa_explanation: analysis.rasa.explanation,
|
| 92 |
+
hallucination_score: analysis.hallucination.score,
|
| 93 |
+
hallucination_severity: analysis.hallucination.severity,
|
| 94 |
+
hallucination_problematic_statements: analysis.hallucination.problematic_statements,
|
| 95 |
+
summary: analysis.summary,
|
| 96 |
+
timestamp,
|
| 97 |
+
});
|
| 98 |
+
|
| 99 |
+
return res.json({
|
| 100 |
+
rasa: analysis.rasa,
|
| 101 |
+
hallucination: analysis.hallucination,
|
| 102 |
+
summary: analysis.summary,
|
| 103 |
+
text,
|
| 104 |
+
timestamp,
|
| 105 |
+
});
|
| 106 |
+
} catch (err) {
|
| 107 |
+
req.log.error({ err }, "Rasa analysis failed");
|
| 108 |
+
return res.status(500).json({ error: "Analysis failed. Please try again." });
|
| 109 |
+
}
|
| 110 |
+
});
|
| 111 |
+
|
| 112 |
+
router.get("/history", async (req, res) => {
|
| 113 |
+
const parsed = GetRasaHistoryQueryParams.safeParse(req.query);
|
| 114 |
+
const limit = parsed.success && parsed.data.limit ? parsed.data.limit : 50;
|
| 115 |
+
|
| 116 |
+
const records = await db
|
| 117 |
+
.select()
|
| 118 |
+
.from(rasaAnalysesTable)
|
| 119 |
+
.orderBy(desc(rasaAnalysesTable.created_at))
|
| 120 |
+
.limit(limit);
|
| 121 |
+
|
| 122 |
+
return res.json(
|
| 123 |
+
records.map((r) => ({
|
| 124 |
+
...r,
|
| 125 |
+
created_at: r.created_at.toISOString(),
|
| 126 |
+
}))
|
| 127 |
+
);
|
| 128 |
+
});
|
| 129 |
+
|
| 130 |
+
router.delete("/history/:id", async (req, res) => {
|
| 131 |
+
const parsed = DeleteRasaHistoryParams.safeParse(req.params);
|
| 132 |
+
if (!parsed.success) {
|
| 133 |
+
return res.status(400).json({ error: "Invalid id" });
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
const { id } = parsed.data;
|
| 137 |
+
|
| 138 |
+
const existing = await db
|
| 139 |
+
.select()
|
| 140 |
+
.from(rasaAnalysesTable)
|
| 141 |
+
.where(eq(rasaAnalysesTable.id, id))
|
| 142 |
+
.limit(1);
|
| 143 |
+
|
| 144 |
+
if (existing.length === 0) {
|
| 145 |
+
return res.status(404).json({ error: "Record not found" });
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
await db.delete(rasaAnalysesTable).where(eq(rasaAnalysesTable.id, id));
|
| 149 |
+
|
| 150 |
+
return res.status(204).send();
|
| 151 |
+
});
|
| 152 |
+
|
| 153 |
+
export default router;
|
artifacts/api-server/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"extends": "../../tsconfig.base.json",
|
| 3 |
+
"compilerOptions": {
|
| 4 |
+
"outDir": "dist",
|
| 5 |
+
"rootDir": "src",
|
| 6 |
+
"types": ["node"]
|
| 7 |
+
},
|
| 8 |
+
"include": ["src"],
|
| 9 |
+
"references": [
|
| 10 |
+
{
|
| 11 |
+
"path": "../../lib/db"
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"path": "../../lib/api-zod"
|
| 15 |
+
},
|
| 16 |
+
{
|
| 17 |
+
"path": "../../lib/integrations-gemini-ai"
|
| 18 |
+
}
|
| 19 |
+
]
|
| 20 |
+
}
|
lib/api-spec/openapi.yaml
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
openapi: 3.1.0
|
| 2 |
+
info:
|
| 3 |
+
# Do not change the title, if the title changes, the import paths will be broken
|
| 4 |
+
title: Api
|
| 5 |
+
version: 0.1.0
|
| 6 |
+
description: API specification
|
| 7 |
+
servers:
|
| 8 |
+
- url: /api
|
| 9 |
+
description: Base API path
|
| 10 |
+
tags:
|
| 11 |
+
- name: health
|
| 12 |
+
description: Health operations
|
| 13 |
+
- name: rasa
|
| 14 |
+
description: Vedic Rasa analysis operations
|
| 15 |
+
paths:
|
| 16 |
+
/healthz:
|
| 17 |
+
get:
|
| 18 |
+
operationId: healthCheck
|
| 19 |
+
tags: [health]
|
| 20 |
+
summary: Health check
|
| 21 |
+
description: Returns server health status
|
| 22 |
+
responses:
|
| 23 |
+
"200":
|
| 24 |
+
description: Healthy
|
| 25 |
+
content:
|
| 26 |
+
application/json:
|
| 27 |
+
schema:
|
| 28 |
+
$ref: "#/components/schemas/HealthStatus"
|
| 29 |
+
/rasa/analyze:
|
| 30 |
+
post:
|
| 31 |
+
operationId: analyzeRasa
|
| 32 |
+
tags: [rasa]
|
| 33 |
+
summary: Analyze text for Vedic Rasa and hallucination detection
|
| 34 |
+
requestBody:
|
| 35 |
+
required: true
|
| 36 |
+
content:
|
| 37 |
+
application/json:
|
| 38 |
+
schema:
|
| 39 |
+
$ref: "#/components/schemas/AnalyzeRasaBody"
|
| 40 |
+
responses:
|
| 41 |
+
"200":
|
| 42 |
+
description: Analysis result
|
| 43 |
+
content:
|
| 44 |
+
application/json:
|
| 45 |
+
schema:
|
| 46 |
+
$ref: "#/components/schemas/AnalysisResult"
|
| 47 |
+
"400":
|
| 48 |
+
description: Bad request
|
| 49 |
+
content:
|
| 50 |
+
application/json:
|
| 51 |
+
schema:
|
| 52 |
+
$ref: "#/components/schemas/ApiError"
|
| 53 |
+
"500":
|
| 54 |
+
description: Server error
|
| 55 |
+
content:
|
| 56 |
+
application/json:
|
| 57 |
+
schema:
|
| 58 |
+
$ref: "#/components/schemas/ApiError"
|
| 59 |
+
/rasa/history:
|
| 60 |
+
get:
|
| 61 |
+
operationId: getRasaHistory
|
| 62 |
+
tags: [rasa]
|
| 63 |
+
summary: Get analysis history
|
| 64 |
+
parameters:
|
| 65 |
+
- name: limit
|
| 66 |
+
in: query
|
| 67 |
+
required: false
|
| 68 |
+
schema:
|
| 69 |
+
type: integer
|
| 70 |
+
responses:
|
| 71 |
+
"200":
|
| 72 |
+
description: List of past analyses
|
| 73 |
+
content:
|
| 74 |
+
application/json:
|
| 75 |
+
schema:
|
| 76 |
+
type: array
|
| 77 |
+
items:
|
| 78 |
+
$ref: "#/components/schemas/AnalysisRecord"
|
| 79 |
+
/rasa/history/{id}:
|
| 80 |
+
delete:
|
| 81 |
+
operationId: deleteRasaHistory
|
| 82 |
+
tags: [rasa]
|
| 83 |
+
summary: Delete a history entry
|
| 84 |
+
parameters:
|
| 85 |
+
- name: id
|
| 86 |
+
in: path
|
| 87 |
+
required: true
|
| 88 |
+
schema:
|
| 89 |
+
type: integer
|
| 90 |
+
responses:
|
| 91 |
+
"204":
|
| 92 |
+
description: Deleted
|
| 93 |
+
"404":
|
| 94 |
+
description: Not found
|
| 95 |
+
content:
|
| 96 |
+
application/json:
|
| 97 |
+
schema:
|
| 98 |
+
$ref: "#/components/schemas/ApiError"
|
| 99 |
+
components:
|
| 100 |
+
schemas:
|
| 101 |
+
HealthStatus:
|
| 102 |
+
type: object
|
| 103 |
+
properties:
|
| 104 |
+
status:
|
| 105 |
+
type: string
|
| 106 |
+
required:
|
| 107 |
+
- status
|
| 108 |
+
AnalyzeRasaBody:
|
| 109 |
+
type: object
|
| 110 |
+
properties:
|
| 111 |
+
text:
|
| 112 |
+
type: string
|
| 113 |
+
required:
|
| 114 |
+
- text
|
| 115 |
+
RasaResult:
|
| 116 |
+
type: object
|
| 117 |
+
properties:
|
| 118 |
+
name:
|
| 119 |
+
type: string
|
| 120 |
+
confidence:
|
| 121 |
+
type: number
|
| 122 |
+
explanation:
|
| 123 |
+
type: string
|
| 124 |
+
required:
|
| 125 |
+
- name
|
| 126 |
+
- confidence
|
| 127 |
+
- explanation
|
| 128 |
+
HallucinationResult:
|
| 129 |
+
type: object
|
| 130 |
+
properties:
|
| 131 |
+
score:
|
| 132 |
+
type: number
|
| 133 |
+
severity:
|
| 134 |
+
type: string
|
| 135 |
+
problematic_statements:
|
| 136 |
+
type: array
|
| 137 |
+
items:
|
| 138 |
+
type: string
|
| 139 |
+
required:
|
| 140 |
+
- score
|
| 141 |
+
- severity
|
| 142 |
+
- problematic_statements
|
| 143 |
+
AnalysisResult:
|
| 144 |
+
type: object
|
| 145 |
+
properties:
|
| 146 |
+
rasa:
|
| 147 |
+
$ref: "#/components/schemas/RasaResult"
|
| 148 |
+
hallucination:
|
| 149 |
+
$ref: "#/components/schemas/HallucinationResult"
|
| 150 |
+
summary:
|
| 151 |
+
type: string
|
| 152 |
+
text:
|
| 153 |
+
type: string
|
| 154 |
+
timestamp:
|
| 155 |
+
type: number
|
| 156 |
+
required:
|
| 157 |
+
- rasa
|
| 158 |
+
- hallucination
|
| 159 |
+
- summary
|
| 160 |
+
- text
|
| 161 |
+
- timestamp
|
| 162 |
+
AnalysisRecord:
|
| 163 |
+
type: object
|
| 164 |
+
properties:
|
| 165 |
+
id:
|
| 166 |
+
type: integer
|
| 167 |
+
text:
|
| 168 |
+
type: string
|
| 169 |
+
rasa_name:
|
| 170 |
+
type: string
|
| 171 |
+
rasa_confidence:
|
| 172 |
+
type: number
|
| 173 |
+
rasa_explanation:
|
| 174 |
+
type: string
|
| 175 |
+
hallucination_score:
|
| 176 |
+
type: number
|
| 177 |
+
hallucination_severity:
|
| 178 |
+
type: string
|
| 179 |
+
hallucination_problematic_statements:
|
| 180 |
+
type: array
|
| 181 |
+
items:
|
| 182 |
+
type: string
|
| 183 |
+
summary:
|
| 184 |
+
type: string
|
| 185 |
+
timestamp:
|
| 186 |
+
type: number
|
| 187 |
+
created_at:
|
| 188 |
+
type: string
|
| 189 |
+
required:
|
| 190 |
+
- id
|
| 191 |
+
- text
|
| 192 |
+
- rasa_name
|
| 193 |
+
- rasa_confidence
|
| 194 |
+
- rasa_explanation
|
| 195 |
+
- hallucination_score
|
| 196 |
+
- hallucination_severity
|
| 197 |
+
- hallucination_problematic_statements
|
| 198 |
+
- summary
|
| 199 |
+
- timestamp
|
| 200 |
+
- created_at
|
| 201 |
+
ApiError:
|
| 202 |
+
type: object
|
| 203 |
+
properties:
|
| 204 |
+
error:
|
| 205 |
+
type: string
|
| 206 |
+
required:
|
| 207 |
+
- error
|
lib/api-spec/orval.config.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig, InputTransformerFn } from "orval";
|
| 2 |
+
import path from "path";
|
| 3 |
+
|
| 4 |
+
const root = path.resolve(__dirname, "..", "..");
|
| 5 |
+
const apiClientReactSrc = path.resolve(root, "lib", "api-client-react", "src");
|
| 6 |
+
const apiZodSrc = path.resolve(root, "lib", "api-zod", "src");
|
| 7 |
+
|
| 8 |
+
// Our exports make assumptions about the title of the API being "Api" (i.e. generated output is `api.ts`).
|
| 9 |
+
const titleTransformer: InputTransformerFn = (config) => {
|
| 10 |
+
config.info ??= {};
|
| 11 |
+
config.info.title = "Api";
|
| 12 |
+
|
| 13 |
+
return config;
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
export default defineConfig({
|
| 17 |
+
"api-client-react": {
|
| 18 |
+
input: {
|
| 19 |
+
target: "./openapi.yaml",
|
| 20 |
+
override: {
|
| 21 |
+
transformer: titleTransformer,
|
| 22 |
+
},
|
| 23 |
+
},
|
| 24 |
+
output: {
|
| 25 |
+
workspace: apiClientReactSrc,
|
| 26 |
+
target: "generated",
|
| 27 |
+
client: "react-query",
|
| 28 |
+
mode: "split",
|
| 29 |
+
baseUrl: "/api",
|
| 30 |
+
clean: true,
|
| 31 |
+
prettier: true,
|
| 32 |
+
override: {
|
| 33 |
+
fetch: {
|
| 34 |
+
includeHttpResponseReturnType: false,
|
| 35 |
+
},
|
| 36 |
+
mutator: {
|
| 37 |
+
path: path.resolve(apiClientReactSrc, "custom-fetch.ts"),
|
| 38 |
+
name: "customFetch",
|
| 39 |
+
},
|
| 40 |
+
},
|
| 41 |
+
},
|
| 42 |
+
},
|
| 43 |
+
zod: {
|
| 44 |
+
input: {
|
| 45 |
+
target: "./openapi.yaml",
|
| 46 |
+
override: {
|
| 47 |
+
transformer: titleTransformer,
|
| 48 |
+
},
|
| 49 |
+
},
|
| 50 |
+
output: {
|
| 51 |
+
workspace: apiZodSrc,
|
| 52 |
+
client: "zod",
|
| 53 |
+
target: "generated",
|
| 54 |
+
schemas: { path: "generated/types", type: "typescript" },
|
| 55 |
+
mode: "split",
|
| 56 |
+
clean: true,
|
| 57 |
+
prettier: true,
|
| 58 |
+
override: {
|
| 59 |
+
zod: {
|
| 60 |
+
coerce: {
|
| 61 |
+
query: ['boolean', 'number', 'string'],
|
| 62 |
+
param: ['boolean', 'number', 'string'],
|
| 63 |
+
body: ['bigint', 'date'],
|
| 64 |
+
response: ['bigint', 'date'],
|
| 65 |
+
},
|
| 66 |
+
},
|
| 67 |
+
useDates: true,
|
| 68 |
+
useBigInt: true,
|
| 69 |
+
},
|
| 70 |
+
},
|
| 71 |
+
},
|
| 72 |
+
});
|
lib/api-spec/package.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "@workspace/api-spec",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"scripts": {
|
| 6 |
+
"codegen": "orval --config ./orval.config.ts"
|
| 7 |
+
},
|
| 8 |
+
"devDependencies": {
|
| 9 |
+
"orval": "^8.5.2"
|
| 10 |
+
}
|
| 11 |
+
}
|
lib/db/drizzle.config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { defineConfig } from "drizzle-kit";
|
| 2 |
+
import path from "path";
|
| 3 |
+
|
| 4 |
+
if (!process.env.DATABASE_URL) {
|
| 5 |
+
throw new Error("DATABASE_URL, ensure the database is provisioned");
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
export default defineConfig({
|
| 9 |
+
schema: path.join(__dirname, "./src/schema/index.ts"),
|
| 10 |
+
dialect: "postgresql",
|
| 11 |
+
dbCredentials: {
|
| 12 |
+
url: process.env.DATABASE_URL,
|
| 13 |
+
},
|
| 14 |
+
});
|
lib/db/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "@workspace/db",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"type": "module",
|
| 6 |
+
"exports": {
|
| 7 |
+
".": "./src/index.ts",
|
| 8 |
+
"./schema": "./src/schema/index.ts"
|
| 9 |
+
},
|
| 10 |
+
"scripts": {
|
| 11 |
+
"push": "drizzle-kit push --config ./drizzle.config.ts",
|
| 12 |
+
"push-force": "drizzle-kit push --force --config ./drizzle.config.ts"
|
| 13 |
+
},
|
| 14 |
+
"dependencies": {
|
| 15 |
+
"drizzle-orm": "catalog:",
|
| 16 |
+
"drizzle-zod": "^0.8.3",
|
| 17 |
+
"pg": "^8.20.0",
|
| 18 |
+
"zod": "catalog:"
|
| 19 |
+
},
|
| 20 |
+
"devDependencies": {
|
| 21 |
+
"@types/node": "catalog:",
|
| 22 |
+
"@types/pg": "^8.18.0",
|
| 23 |
+
"drizzle-kit": "^0.31.9"
|
| 24 |
+
}
|
| 25 |
+
}
|
lib/db/src/index.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { drizzle } from "drizzle-orm/node-postgres";
|
| 2 |
+
import pg from "pg";
|
| 3 |
+
import * as schema from "./schema";
|
| 4 |
+
|
| 5 |
+
const { Pool } = pg;
|
| 6 |
+
|
| 7 |
+
if (!process.env.DATABASE_URL) {
|
| 8 |
+
throw new Error(
|
| 9 |
+
"DATABASE_URL must be set. Did you forget to provision a database?",
|
| 10 |
+
);
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
export const pool = new Pool({ connectionString: process.env.DATABASE_URL });
|
| 14 |
+
export const db = drizzle(pool, { schema });
|
| 15 |
+
|
| 16 |
+
export * from "./schema";
|
lib/db/src/schema/index.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Export your models here. Add one export per file
|
| 2 |
+
// export * from "./posts";
|
| 3 |
+
//
|
| 4 |
+
// Each model/table should ideally be split into different files.
|
| 5 |
+
// Each model/table should define a Drizzle table, insert schema, and types:
|
| 6 |
+
//
|
| 7 |
+
// import { pgTable, text, serial } from "drizzle-orm/pg-core";
|
| 8 |
+
// import { createInsertSchema } from "drizzle-zod";
|
| 9 |
+
// import { z } from "zod/v4";
|
| 10 |
+
//
|
| 11 |
+
// export const postsTable = pgTable("posts", {
|
| 12 |
+
// id: serial("id").primaryKey(),
|
| 13 |
+
// title: text("title").notNull(),
|
| 14 |
+
// });
|
| 15 |
+
//
|
| 16 |
+
// export const insertPostSchema = createInsertSchema(postsTable).omit({ id: true });
|
| 17 |
+
// export type InsertPost = z.infer<typeof insertPostSchema>;
|
| 18 |
+
// export type Post = typeof postsTable.$inferSelect;
|
| 19 |
+
|
| 20 |
+
export * from "./rasa_analyses";
|
lib/db/src/schema/rasa_analyses.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { pgTable, serial, text, real, jsonb, timestamp, bigint } from "drizzle-orm/pg-core";
|
| 2 |
+
import { createInsertSchema } from "drizzle-zod";
|
| 3 |
+
import { z } from "zod/v4";
|
| 4 |
+
|
| 5 |
+
export const rasaAnalysesTable = pgTable("rasa_analyses", {
|
| 6 |
+
id: serial("id").primaryKey(),
|
| 7 |
+
text: text("text").notNull(),
|
| 8 |
+
rasa_name: text("rasa_name").notNull(),
|
| 9 |
+
rasa_confidence: real("rasa_confidence").notNull(),
|
| 10 |
+
rasa_explanation: text("rasa_explanation").notNull(),
|
| 11 |
+
hallucination_score: real("hallucination_score").notNull(),
|
| 12 |
+
hallucination_severity: text("hallucination_severity").notNull(),
|
| 13 |
+
hallucination_problematic_statements: jsonb("hallucination_problematic_statements").$type<string[]>().notNull().default([]),
|
| 14 |
+
summary: text("summary").notNull(),
|
| 15 |
+
timestamp: bigint("timestamp", { mode: "number" }).notNull(),
|
| 16 |
+
created_at: timestamp("created_at").defaultNow().notNull(),
|
| 17 |
+
});
|
| 18 |
+
|
| 19 |
+
export const insertRasaAnalysisSchema = createInsertSchema(rasaAnalysesTable).omit({ id: true, created_at: true });
|
| 20 |
+
export type InsertRasaAnalysis = z.infer<typeof insertRasaAnalysisSchema>;
|
| 21 |
+
export type RasaAnalysis = typeof rasaAnalysesTable.$inferSelect;
|
lib/db/tsconfig.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"extends": "../../tsconfig.base.json",
|
| 3 |
+
"compilerOptions": {
|
| 4 |
+
"composite": true,
|
| 5 |
+
"declarationMap": true,
|
| 6 |
+
"emitDeclarationOnly": true,
|
| 7 |
+
"outDir": "dist",
|
| 8 |
+
"rootDir": "src",
|
| 9 |
+
"types": ["node"]
|
| 10 |
+
},
|
| 11 |
+
"include": ["src"]
|
| 12 |
+
}
|
package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "workspace",
|
| 3 |
+
"version": "0.0.0",
|
| 4 |
+
"license": "MIT",
|
| 5 |
+
"scripts": {
|
| 6 |
+
"preinstall": "sh -c 'rm -f package-lock.json yarn.lock; case \"$npm_config_user_agent\" in pnpm/*) ;; *) echo \"Use pnpm instead\" >&2; exit 1 ;; esac'",
|
| 7 |
+
"build": "pnpm run typecheck && pnpm -r --if-present run build",
|
| 8 |
+
"typecheck:libs": "tsc --build",
|
| 9 |
+
"typecheck": "pnpm run typecheck:libs && pnpm -r --filter \"./artifacts/**\" --filter \"./scripts\" --if-present run typecheck"
|
| 10 |
+
},
|
| 11 |
+
"private": true,
|
| 12 |
+
"devDependencies": {
|
| 13 |
+
"typescript": "~5.9.2",
|
| 14 |
+
"prettier": "^3.8.1"
|
| 15 |
+
}
|
| 16 |
+
}
|
pnpm-workspace.yaml
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ============================================================================
|
| 2 |
+
# SECURITY: Minimum release age for npm packages (supply-chain attack defense)
|
| 3 |
+
# ============================================================================
|
| 4 |
+
#
|
| 5 |
+
# This setting requires that any npm package version must have been published
|
| 6 |
+
# for at least 1 day (1440 minutes) before pnpm will allow installing it.
|
| 7 |
+
# This is a critical defense against supply-chain attacks. In most cases,
|
| 8 |
+
# malicious npm releases are discovered and pulled within hours, so a 1-day
|
| 9 |
+
# delay provides a strong safety buffer.
|
| 10 |
+
#
|
| 11 |
+
# DO NOT DISABLE THIS SETTING. Removing or setting it to 0 is considered
|
| 12 |
+
# extremely dangerous and leaves the entire workspace vulnerable to supply-
|
| 13 |
+
# chain attacks, which have been the #1 vector for npm ecosystem compromises.
|
| 14 |
+
#
|
| 15 |
+
# If you absolutely need to install a package before the 1-day window has
|
| 16 |
+
# passed (e.g. an urgent security bugfix), you can add it to the
|
| 17 |
+
# `minimumReleaseAgeExclude` allowlist below. Only consider doing this for
|
| 18 |
+
# packages released by trusted organizations with an impeccable security
|
| 19 |
+
# posture (e.g. Replit packsges, react from Meta, typescript from Microsoft). Even then,
|
| 20 |
+
# remove the exclusion once the 1-day window has passed.
|
| 21 |
+
#
|
| 22 |
+
# Example:
|
| 23 |
+
# minimumReleaseAgeExclude:
|
| 24 |
+
# - react
|
| 25 |
+
# - typescript
|
| 26 |
+
#
|
| 27 |
+
# ============================================================================
|
| 28 |
+
minimumReleaseAge: 1440
|
| 29 |
+
|
| 30 |
+
minimumReleaseAgeExclude:
|
| 31 |
+
# Exclude @replit scoped packages from the minimum release age check.
|
| 32 |
+
# These are published by Replit and trusted — the supply-chain attack vector
|
| 33 |
+
# this setting guards against does not apply to our own packages.
|
| 34 |
+
- '@replit/*'
|
| 35 |
+
- stripe-replit-sync
|
| 36 |
+
|
| 37 |
+
packages:
|
| 38 |
+
- artifacts/*
|
| 39 |
+
- lib/*
|
| 40 |
+
- lib/integrations/*
|
| 41 |
+
- scripts
|
| 42 |
+
|
| 43 |
+
catalog:
|
| 44 |
+
'@replit/vite-plugin-cartographer': ^0.5.1
|
| 45 |
+
'@replit/vite-plugin-dev-banner': ^0.1.1
|
| 46 |
+
'@replit/vite-plugin-runtime-error-modal': ^0.0.6
|
| 47 |
+
'@tailwindcss/vite': ^4.1.14
|
| 48 |
+
'@tanstack/react-query': ^5.90.21
|
| 49 |
+
'@types/node': ^25.3.3
|
| 50 |
+
'@types/react': ^19.2.0
|
| 51 |
+
'@types/react-dom': ^19.2.0
|
| 52 |
+
'@vitejs/plugin-react': ^5.0.4
|
| 53 |
+
class-variance-authority: ^0.7.1
|
| 54 |
+
clsx: ^2.1.1
|
| 55 |
+
drizzle-orm: ^0.45.1
|
| 56 |
+
framer-motion: ^12.23.24
|
| 57 |
+
lucide-react: ^0.545.0
|
| 58 |
+
# Must be this exact version because expo requires it
|
| 59 |
+
react: 19.1.0
|
| 60 |
+
# Must be this exact version because expo requires it
|
| 61 |
+
react-dom: 19.1.0
|
| 62 |
+
tailwind-merge: ^3.3.1
|
| 63 |
+
tailwindcss: ^4.1.14
|
| 64 |
+
tsx: ^4.21.0
|
| 65 |
+
vite: ^7.3.0
|
| 66 |
+
zod: ^3.25.76
|
| 67 |
+
|
| 68 |
+
autoInstallPeers: false
|
| 69 |
+
|
| 70 |
+
onlyBuiltDependencies:
|
| 71 |
+
- '@swc/core'
|
| 72 |
+
- esbuild
|
| 73 |
+
- msw
|
| 74 |
+
- unrs-resolver
|
| 75 |
+
|
| 76 |
+
overrides:
|
| 77 |
+
# replit uses linux-x64 only, we can exclude all other platforms
|
| 78 |
+
"esbuild>@esbuild/darwin-arm64": "-"
|
| 79 |
+
"esbuild>@esbuild/darwin-x64": "-"
|
| 80 |
+
"esbuild>@esbuild/freebsd-arm64": "-"
|
| 81 |
+
"esbuild>@esbuild/freebsd-x64": "-"
|
| 82 |
+
"esbuild>@esbuild/linux-arm": "-"
|
| 83 |
+
"esbuild>@esbuild/linux-arm64": "-"
|
| 84 |
+
"esbuild>@esbuild/linux-ia32": "-"
|
| 85 |
+
"esbuild>@esbuild/linux-loong64": "-"
|
| 86 |
+
"esbuild>@esbuild/linux-mips64el": "-"
|
| 87 |
+
"esbuild>@esbuild/linux-ppc64": "-"
|
| 88 |
+
"esbuild>@esbuild/linux-riscv64": "-"
|
| 89 |
+
"esbuild>@esbuild/linux-s390x": "-"
|
| 90 |
+
"esbuild>@esbuild/netbsd-arm64": "-"
|
| 91 |
+
"esbuild>@esbuild/netbsd-x64": "-"
|
| 92 |
+
"esbuild>@esbuild/openbsd-arm64": "-"
|
| 93 |
+
"esbuild>@esbuild/openbsd-x64": "-"
|
| 94 |
+
"esbuild>@esbuild/sunos-x64": "-"
|
| 95 |
+
"esbuild>@esbuild/win32-arm64": "-"
|
| 96 |
+
"esbuild>@esbuild/win32-ia32": "-"
|
| 97 |
+
"esbuild>@esbuild/win32-x64": "-"
|
| 98 |
+
"esbuild>@esbuild/aix-ppc64": '-'
|
| 99 |
+
"esbuild>@esbuild/android-arm": '-'
|
| 100 |
+
"esbuild>@esbuild/android-arm64": '-'
|
| 101 |
+
"esbuild>@esbuild/android-x64": '-'
|
| 102 |
+
"esbuild>@esbuild/openharmony-arm64": '-'
|
| 103 |
+
"lightningcss>lightningcss-android-arm64": "-"
|
| 104 |
+
"lightningcss>lightningcss-darwin-arm64": "-"
|
| 105 |
+
"lightningcss>lightningcss-darwin-x64": "-"
|
| 106 |
+
"lightningcss>lightningcss-freebsd-x64": "-"
|
| 107 |
+
"lightningcss>lightningcss-linux-arm-gnueabihf": "-"
|
| 108 |
+
"lightningcss>lightningcss-linux-arm64-gnu": "-"
|
| 109 |
+
"lightningcss>lightningcss-linux-arm64-musl": "-"
|
| 110 |
+
"lightningcss>lightningcss-linux-x64-musl": "-"
|
| 111 |
+
"lightningcss>lightningcss-win32-arm64-msvc": "-"
|
| 112 |
+
"lightningcss>lightningcss-win32-x64-msvc": "-"
|
| 113 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-android-arm64": "-"
|
| 114 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-darwin-arm64": "-"
|
| 115 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-darwin-x64": "-"
|
| 116 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-freebsd-x64": "-"
|
| 117 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-linux-arm-gnueabihf": "-"
|
| 118 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-linux-arm64-gnu": "-"
|
| 119 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-linux-arm64-musl": "-"
|
| 120 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-win32-arm64-msvc": "-"
|
| 121 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-win32-x64-msvc": "-"
|
| 122 |
+
"@tailwindcss/oxide>@tailwindcss/oxide-linux-x64-musl": "-"
|
| 123 |
+
"rollup>@rollup/rollup-android-arm-eabi": "-"
|
| 124 |
+
"rollup>@rollup/rollup-android-arm64": "-"
|
| 125 |
+
"rollup>@rollup/rollup-darwin-arm64": "-"
|
| 126 |
+
"rollup>@rollup/rollup-darwin-x64": "-"
|
| 127 |
+
"rollup>@rollup/rollup-freebsd-arm64": "-"
|
| 128 |
+
"rollup>@rollup/rollup-freebsd-x64": "-"
|
| 129 |
+
"rollup>@rollup/rollup-linux-arm-gnueabihf": "-"
|
| 130 |
+
"rollup>@rollup/rollup-linux-arm-musleabihf": "-"
|
| 131 |
+
"rollup>@rollup/rollup-linux-arm64-gnu": "-"
|
| 132 |
+
"rollup>@rollup/rollup-linux-arm64-musl": "-"
|
| 133 |
+
"rollup>@rollup/rollup-linux-loong64-gnu": "-"
|
| 134 |
+
"rollup>@rollup/rollup-linux-loong64-musl": "-"
|
| 135 |
+
"rollup>@rollup/rollup-linux-ppc64-gnu": "-"
|
| 136 |
+
"rollup>@rollup/rollup-linux-ppc64-musl": "-"
|
| 137 |
+
"rollup>@rollup/rollup-linux-riscv64-gnu": "-"
|
| 138 |
+
"rollup>@rollup/rollup-linux-riscv64-musl": "-"
|
| 139 |
+
"rollup>@rollup/rollup-linux-s390x-gnu": "-"
|
| 140 |
+
"rollup>@rollup/rollup-linux-x64-musl": "-"
|
| 141 |
+
"rollup>@rollup/rollup-openbsd-x64": "-"
|
| 142 |
+
"rollup>@rollup/rollup-openharmony-arm64": "-"
|
| 143 |
+
"rollup>@rollup/rollup-win32-arm64-msvc": "-"
|
| 144 |
+
"rollup>@rollup/rollup-win32-ia32-msvc": "-"
|
| 145 |
+
"rollup>@rollup/rollup-win32-x64-gnu": "-"
|
| 146 |
+
"rollup>@rollup/rollup-win32-x64-msvc": "-"
|
| 147 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-darwin-arm64": "-"
|
| 148 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-darwin-x64": "-"
|
| 149 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-freebsd-ia32": "-"
|
| 150 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-freebsd-x64": "-"
|
| 151 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-linux-arm64": "-"
|
| 152 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-linux-arm": "-"
|
| 153 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-linux-ia32": "-"
|
| 154 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-sunos-x64": "-"
|
| 155 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-win32-ia32": "-"
|
| 156 |
+
"@expo/ngrok-bin>@expo/ngrok-bin-win32-x64": "-"
|
| 157 |
+
# drizzle-kit uses esbuild internally on an older version that's vulnerable, this overrides it
|
| 158 |
+
"@esbuild-kit/esm-loader": "npm:tsx@^4.21.0"
|
| 159 |
+
esbuild: "0.27.3"
|
tsconfig.base.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"isolatedModules": true,
|
| 4 |
+
"lib": ["es2022"],
|
| 5 |
+
"module": "esnext",
|
| 6 |
+
"moduleResolution": "bundler",
|
| 7 |
+
"noEmitOnError": true,
|
| 8 |
+
"noFallthroughCasesInSwitch": true,
|
| 9 |
+
"noImplicitOverride": false,
|
| 10 |
+
"noImplicitReturns": true,
|
| 11 |
+
"noUnusedLocals": false,
|
| 12 |
+
"noImplicitAny": true,
|
| 13 |
+
"noImplicitThis": true,
|
| 14 |
+
"strictNullChecks": true,
|
| 15 |
+
"strictFunctionTypes": false,
|
| 16 |
+
"strictBindCallApply": true,
|
| 17 |
+
"strictPropertyInitialization": true,
|
| 18 |
+
"useUnknownInCatchVariables": true,
|
| 19 |
+
"alwaysStrict": true,
|
| 20 |
+
"skipLibCheck": true,
|
| 21 |
+
"target": "es2022",
|
| 22 |
+
"types": [],
|
| 23 |
+
"customConditions": ["workspace"]
|
| 24 |
+
}
|
| 25 |
+
}
|
tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"extends": "./tsconfig.base.json",
|
| 3 |
+
"compileOnSave": false,
|
| 4 |
+
"files": [],
|
| 5 |
+
"references": [
|
| 6 |
+
{
|
| 7 |
+
"path": "./lib/db"
|
| 8 |
+
},
|
| 9 |
+
{
|
| 10 |
+
"path": "./lib/api-client-react"
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"path": "./lib/api-zod"
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"path": "./lib/integrations-gemini-ai"
|
| 17 |
+
}
|
| 18 |
+
]
|
| 19 |
+
}
|