@chrishdx/llm-dev-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +164 -0
- package/backend/bin/llm-dev-server.js +3 -0
- package/backend/dist/cli.d.ts +15 -0
- package/backend/dist/cli.d.ts.map +1 -0
- package/backend/dist/cli.js +326 -0
- package/backend/dist/cli.js.map +1 -0
- package/backend/dist/config/database.d.ts +10 -0
- package/backend/dist/config/database.d.ts.map +1 -0
- package/backend/dist/config/database.js +61 -0
- package/backend/dist/config/database.js.map +1 -0
- package/backend/dist/config/environment.d.ts +20 -0
- package/backend/dist/config/environment.d.ts.map +1 -0
- package/backend/dist/config/environment.js +77 -0
- package/backend/dist/config/environment.js.map +1 -0
- package/backend/dist/controllers/AuthController.d.ts +18 -0
- package/backend/dist/controllers/AuthController.d.ts.map +1 -0
- package/backend/dist/controllers/AuthController.js +282 -0
- package/backend/dist/controllers/AuthController.js.map +1 -0
- package/backend/dist/controllers/ConversationController.d.ts +44 -0
- package/backend/dist/controllers/ConversationController.d.ts.map +1 -0
- package/backend/dist/controllers/ConversationController.js +193 -0
- package/backend/dist/controllers/ConversationController.js.map +1 -0
- package/backend/dist/controllers/JobController.d.ts +49 -0
- package/backend/dist/controllers/JobController.d.ts.map +1 -0
- package/backend/dist/controllers/JobController.js +227 -0
- package/backend/dist/controllers/JobController.js.map +1 -0
- package/backend/dist/index.d.ts +2 -0
- package/backend/dist/index.d.ts.map +1 -0
- package/backend/dist/index.js +160 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/middleware/auth.middleware.d.ts +25 -0
- package/backend/dist/middleware/auth.middleware.d.ts.map +1 -0
- package/backend/dist/middleware/auth.middleware.js +116 -0
- package/backend/dist/middleware/auth.middleware.js.map +1 -0
- package/backend/dist/middleware/authelia.middleware.d.ts +26 -0
- package/backend/dist/middleware/authelia.middleware.d.ts.map +1 -0
- package/backend/dist/middleware/authelia.middleware.js +165 -0
- package/backend/dist/middleware/authelia.middleware.js.map +1 -0
- package/backend/dist/middleware/error.middleware.d.ts +23 -0
- package/backend/dist/middleware/error.middleware.d.ts.map +1 -0
- package/backend/dist/middleware/error.middleware.js +59 -0
- package/backend/dist/middleware/error.middleware.js.map +1 -0
- package/backend/dist/models/AuthToken.d.ts +42 -0
- package/backend/dist/models/AuthToken.d.ts.map +1 -0
- package/backend/dist/models/AuthToken.js +97 -0
- package/backend/dist/models/AuthToken.js.map +1 -0
- package/backend/dist/models/Conversation.d.ts +36 -0
- package/backend/dist/models/Conversation.d.ts.map +1 -0
- package/backend/dist/models/Conversation.js +100 -0
- package/backend/dist/models/Conversation.js.map +1 -0
- package/backend/dist/models/FileOperation.d.ts +36 -0
- package/backend/dist/models/FileOperation.d.ts.map +1 -0
- package/backend/dist/models/FileOperation.js +117 -0
- package/backend/dist/models/FileOperation.js.map +1 -0
- package/backend/dist/models/Job.d.ts +48 -0
- package/backend/dist/models/Job.d.ts.map +1 -0
- package/backend/dist/models/Job.js +87 -0
- package/backend/dist/models/Job.js.map +1 -0
- package/backend/dist/models/Message.d.ts +38 -0
- package/backend/dist/models/Message.d.ts.map +1 -0
- package/backend/dist/models/Message.js +87 -0
- package/backend/dist/models/Message.js.map +1 -0
- package/backend/dist/models/User.d.ts +26 -0
- package/backend/dist/models/User.d.ts.map +1 -0
- package/backend/dist/models/User.js +67 -0
- package/backend/dist/models/User.js.map +1 -0
- package/backend/dist/models/index.d.ts +13 -0
- package/backend/dist/models/index.d.ts.map +1 -0
- package/backend/dist/models/index.js +24 -0
- package/backend/dist/models/index.js.map +1 -0
- package/backend/dist/routes/auth.routes.d.ts +3 -0
- package/backend/dist/routes/auth.routes.d.ts.map +1 -0
- package/backend/dist/routes/auth.routes.js +27 -0
- package/backend/dist/routes/auth.routes.js.map +1 -0
- package/backend/dist/routes/conversation.routes.d.ts +3 -0
- package/backend/dist/routes/conversation.routes.d.ts.map +1 -0
- package/backend/dist/routes/conversation.routes.js +17 -0
- package/backend/dist/routes/conversation.routes.js.map +1 -0
- package/backend/dist/routes/filesystem.routes.d.ts +3 -0
- package/backend/dist/routes/filesystem.routes.d.ts.map +1 -0
- package/backend/dist/routes/filesystem.routes.js +64 -0
- package/backend/dist/routes/filesystem.routes.js.map +1 -0
- package/backend/dist/routes/index.d.ts +3 -0
- package/backend/dist/routes/index.d.ts.map +1 -0
- package/backend/dist/routes/index.js +27 -0
- package/backend/dist/routes/index.js.map +1 -0
- package/backend/dist/routes/job.routes.d.ts +3 -0
- package/backend/dist/routes/job.routes.d.ts.map +1 -0
- package/backend/dist/routes/job.routes.js +18 -0
- package/backend/dist/routes/job.routes.js.map +1 -0
- package/backend/dist/services/auth/BaseAuthService.d.ts +49 -0
- package/backend/dist/services/auth/BaseAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/BaseAuthService.js +97 -0
- package/backend/dist/services/auth/BaseAuthService.js.map +1 -0
- package/backend/dist/services/auth/ClaudeAuthService.d.ts +69 -0
- package/backend/dist/services/auth/ClaudeAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/ClaudeAuthService.js +401 -0
- package/backend/dist/services/auth/ClaudeAuthService.js.map +1 -0
- package/backend/dist/services/auth/CodexAuthService.d.ts +37 -0
- package/backend/dist/services/auth/CodexAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/CodexAuthService.js +186 -0
- package/backend/dist/services/auth/CodexAuthService.js.map +1 -0
- package/backend/dist/services/auth/GeminiAuthService.d.ts +50 -0
- package/backend/dist/services/auth/GeminiAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/GeminiAuthService.js +284 -0
- package/backend/dist/services/auth/GeminiAuthService.js.map +1 -0
- package/backend/dist/services/auth/JwtService.d.ts +27 -0
- package/backend/dist/services/auth/JwtService.d.ts.map +1 -0
- package/backend/dist/services/auth/JwtService.js +65 -0
- package/backend/dist/services/auth/JwtService.js.map +1 -0
- package/backend/dist/services/auth/TokenRefreshService.d.ts +36 -0
- package/backend/dist/services/auth/TokenRefreshService.d.ts.map +1 -0
- package/backend/dist/services/auth/TokenRefreshService.js +178 -0
- package/backend/dist/services/auth/TokenRefreshService.js.map +1 -0
- package/backend/dist/services/conversation/ConversationService.d.ts +89 -0
- package/backend/dist/services/conversation/ConversationService.d.ts.map +1 -0
- package/backend/dist/services/conversation/ConversationService.js +255 -0
- package/backend/dist/services/conversation/ConversationService.js.map +1 -0
- package/backend/dist/services/job/JobService.d.ts +83 -0
- package/backend/dist/services/job/JobService.d.ts.map +1 -0
- package/backend/dist/services/job/JobService.js +213 -0
- package/backend/dist/services/job/JobService.js.map +1 -0
- package/backend/dist/services/job/WorkingDirectoryService.d.ts +73 -0
- package/backend/dist/services/job/WorkingDirectoryService.d.ts.map +1 -0
- package/backend/dist/services/job/WorkingDirectoryService.js +289 -0
- package/backend/dist/services/job/WorkingDirectoryService.js.map +1 -0
- package/backend/dist/services/llm/ClaudeProvider.d.ts +16 -0
- package/backend/dist/services/llm/ClaudeProvider.d.ts.map +1 -0
- package/backend/dist/services/llm/ClaudeProvider.js +229 -0
- package/backend/dist/services/llm/ClaudeProvider.js.map +1 -0
- package/backend/dist/services/llm/CodexProvider.d.ts +15 -0
- package/backend/dist/services/llm/CodexProvider.d.ts.map +1 -0
- package/backend/dist/services/llm/CodexProvider.js +301 -0
- package/backend/dist/services/llm/CodexProvider.js.map +1 -0
- package/backend/dist/services/llm/GeminiProvider.d.ts +17 -0
- package/backend/dist/services/llm/GeminiProvider.d.ts.map +1 -0
- package/backend/dist/services/llm/GeminiProvider.js +190 -0
- package/backend/dist/services/llm/GeminiProvider.js.map +1 -0
- package/backend/dist/services/llm/LLMProviderBase.d.ts +76 -0
- package/backend/dist/services/llm/LLMProviderBase.d.ts.map +1 -0
- package/backend/dist/services/llm/LLMProviderBase.js +34 -0
- package/backend/dist/services/llm/LLMProviderBase.js.map +1 -0
- package/backend/dist/services/llm/ProviderFactory.d.ts +17 -0
- package/backend/dist/services/llm/ProviderFactory.d.ts.map +1 -0
- package/backend/dist/services/llm/ProviderFactory.js +58 -0
- package/backend/dist/services/llm/ProviderFactory.js.map +1 -0
- package/backend/dist/utils/crypto.d.ts +33 -0
- package/backend/dist/utils/crypto.d.ts.map +1 -0
- package/backend/dist/utils/crypto.js +165 -0
- package/backend/dist/utils/crypto.js.map +1 -0
- package/backend/dist/utils/logger.d.ts +4 -0
- package/backend/dist/utils/logger.d.ts.map +1 -0
- package/backend/dist/utils/logger.js +44 -0
- package/backend/dist/utils/logger.js.map +1 -0
- package/backend/dist/utils/validators.d.ts +22 -0
- package/backend/dist/utils/validators.d.ts.map +1 -0
- package/backend/dist/utils/validators.js +127 -0
- package/backend/dist/utils/validators.js.map +1 -0
- package/backend/package.json +45 -0
- package/backend/public/assets/index-C207-KqP.js +188 -0
- package/backend/public/index.html +12 -0
- package/package.json +96 -0
- package/shared/dist/index.d.ts +5 -0
- package/shared/dist/index.d.ts.map +1 -0
- package/shared/dist/index.js +25 -0
- package/shared/dist/index.js.map +1 -0
- package/shared/dist/types/api.d.ts +27 -0
- package/shared/dist/types/api.d.ts.map +1 -0
- package/shared/dist/types/api.js +3 -0
- package/shared/dist/types/api.js.map +1 -0
- package/shared/dist/types/auth.d.ts +62 -0
- package/shared/dist/types/auth.d.ts.map +1 -0
- package/shared/dist/types/auth.js +3 -0
- package/shared/dist/types/auth.js.map +1 -0
- package/shared/dist/types/conversation.d.ts +98 -0
- package/shared/dist/types/conversation.d.ts.map +1 -0
- package/shared/dist/types/conversation.js +3 -0
- package/shared/dist/types/conversation.js.map +1 -0
- package/shared/dist/types/job.d.ts +93 -0
- package/shared/dist/types/job.d.ts.map +1 -0
- package/shared/dist/types/job.js +3 -0
- package/shared/dist/types/job.js.map +1 -0
- package/shared/package.json +15 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.config = void 0;
|
|
7
|
+
const dotenv_1 = __importDefault(require("dotenv"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const crypto_1 = require("../utils/crypto");
|
|
12
|
+
// Determine home directory for persistent data
|
|
13
|
+
const DEV_SERVER_HOME = process.env.DEV_SERVER_HOME || path_1.default.join(os_1.default.homedir(), ".dev_server");
|
|
14
|
+
const DEFAULT_DATA_DIR = path_1.default.join(DEV_SERVER_HOME, "data");
|
|
15
|
+
const DEFAULT_WORKSPACES_DIR = path_1.default.join(DEV_SERVER_HOME, "workspaces");
|
|
16
|
+
const ENV_FILE = path_1.default.join(DEV_SERVER_HOME, ".env");
|
|
17
|
+
// Load environment variables from home directory first, then local .env
|
|
18
|
+
if (fs_1.default.existsSync(ENV_FILE)) {
|
|
19
|
+
dotenv_1.default.config({ path: ENV_FILE });
|
|
20
|
+
}
|
|
21
|
+
// Also load local .env for development override
|
|
22
|
+
dotenv_1.default.config();
|
|
23
|
+
/**
|
|
24
|
+
* Parse TRUST_PROXY value - can be boolean, number, or string
|
|
25
|
+
*/
|
|
26
|
+
function parseTrustProxy(value) {
|
|
27
|
+
if (!value)
|
|
28
|
+
return false;
|
|
29
|
+
if (value === "true")
|
|
30
|
+
return true;
|
|
31
|
+
if (value === "false")
|
|
32
|
+
return false;
|
|
33
|
+
const num = parseInt(value, 10);
|
|
34
|
+
if (!isNaN(num))
|
|
35
|
+
return num;
|
|
36
|
+
return value; // e.g., 'loopback', 'linklocal', 'uniquelocal'
|
|
37
|
+
}
|
|
38
|
+
function validateEnvironment() {
|
|
39
|
+
const env = process.env;
|
|
40
|
+
// Generate secrets if missing (both dev and first-time production)
|
|
41
|
+
if (!env.JWT_SECRET) {
|
|
42
|
+
env.JWT_SECRET = (0, crypto_1.generateRandomHex)(64);
|
|
43
|
+
console.warn("[WARN] Generated JWT_SECRET. Set it in ~/.dev_server/.env for persistence!");
|
|
44
|
+
}
|
|
45
|
+
if (!env.ENCRYPTION_KEY) {
|
|
46
|
+
env.ENCRYPTION_KEY = (0, crypto_1.generateRandomHex)(32);
|
|
47
|
+
console.warn("[WARN] Generated ENCRYPTION_KEY. Set it in ~/.dev_server/.env for persistence!");
|
|
48
|
+
}
|
|
49
|
+
// Use home directory defaults
|
|
50
|
+
const dataDir = env.DATA_DIR || DEFAULT_DATA_DIR;
|
|
51
|
+
const databaseUrl = env.DATABASE_URL || path_1.default.join(dataDir, "dev-server.db");
|
|
52
|
+
return {
|
|
53
|
+
NODE_ENV: env.NODE_ENV || "development",
|
|
54
|
+
PORT: parseInt(env.PORT || "3000", 10),
|
|
55
|
+
DATABASE_URL: databaseUrl,
|
|
56
|
+
JWT_SECRET: env.JWT_SECRET,
|
|
57
|
+
ENCRYPTION_KEY: env.ENCRYPTION_KEY,
|
|
58
|
+
ALLOWED_ORIGINS: env.ALLOWED_ORIGINS
|
|
59
|
+
? env.ALLOWED_ORIGINS.split(",")
|
|
60
|
+
: ["http://localhost:3000", "http://localhost:5173"],
|
|
61
|
+
DATA_DIR: dataDir,
|
|
62
|
+
WORKING_DIR_BASE: env.WORKING_DIR_BASE || DEFAULT_WORKSPACES_DIR,
|
|
63
|
+
CLAUDE_CLI_PATH: env.CLAUDE_CLI_PATH,
|
|
64
|
+
CODEX_CLI_PATH: env.CODEX_CLI_PATH,
|
|
65
|
+
GEMINI_CLI_PATH: env.GEMINI_CLI_PATH,
|
|
66
|
+
LOG_LEVEL: env.LOG_LEVEL || "info",
|
|
67
|
+
// Proxy & Authelia
|
|
68
|
+
TRUST_PROXY: parseTrustProxy(env.TRUST_PROXY),
|
|
69
|
+
AUTHELIA_ENABLED: env.AUTHELIA_ENABLED === "true",
|
|
70
|
+
AUTHELIA_ADMIN_GROUPS: env.AUTHELIA_ADMIN_GROUPS
|
|
71
|
+
? env.AUTHELIA_ADMIN_GROUPS.split(",")
|
|
72
|
+
: ["admins"],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
exports.config = validateEnvironment();
|
|
76
|
+
exports.default = exports.config;
|
|
77
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Request, Response } from "express";
|
|
2
|
+
export declare class AuthController {
|
|
3
|
+
static register(req: Request, res: Response): Promise<void>;
|
|
4
|
+
static login(req: Request, res: Response): Promise<void>;
|
|
5
|
+
static me(req: Request, res: Response): Promise<void>;
|
|
6
|
+
static claudeLoginRedirect(req: Request, res: Response): Promise<void>;
|
|
7
|
+
static claudeCallback(req: Request, res: Response): Promise<void>;
|
|
8
|
+
static claudeStatus(req: Request, res: Response): Promise<void>;
|
|
9
|
+
static claudeManualLoginStart(req: Request, res: Response): Promise<void>;
|
|
10
|
+
static claudeManualLoginComplete(req: Request, res: Response): Promise<void>;
|
|
11
|
+
static codexLoginStart(req: Request, res: Response): Promise<void>;
|
|
12
|
+
static codexLoginPoll(req: Request, res: Response): Promise<void>;
|
|
13
|
+
static codexStatus(req: Request, res: Response): Promise<void>;
|
|
14
|
+
static geminiLoginStart(req: Request, res: Response): Promise<void>;
|
|
15
|
+
static geminiLoginComplete(req: Request, res: Response): Promise<void>;
|
|
16
|
+
static geminiStatus(req: Request, res: Response): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=AuthController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthController.d.ts","sourceRoot":"","sources":["../../src/controllers/AuthController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAW5C,qBAAa,cAAc;WAEZ,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAyBpC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAwCjC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAY9B,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAmB/C,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAiC1C,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAaxC,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAgClD,yBAAyB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAuCrD,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAW3C,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAW1C,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAavC,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WAsB5C,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;WA2B/C,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ;CAUtD"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AuthController = void 0;
|
|
7
|
+
const models_1 = require("../models");
|
|
8
|
+
const JwtService_1 = require("../services/auth/JwtService");
|
|
9
|
+
const ClaudeAuthService_1 = require("../services/auth/ClaudeAuthService");
|
|
10
|
+
const CodexAuthService_1 = require("../services/auth/CodexAuthService");
|
|
11
|
+
const GeminiAuthService_1 = require("../services/auth/GeminiAuthService");
|
|
12
|
+
const TokenRefreshService_1 = require("../services/auth/TokenRefreshService");
|
|
13
|
+
const crypto_1 = require("../utils/crypto");
|
|
14
|
+
const validators_1 = require("../utils/validators");
|
|
15
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
16
|
+
class AuthController {
|
|
17
|
+
// User Registration
|
|
18
|
+
static async register(req, res) {
|
|
19
|
+
try {
|
|
20
|
+
const { username, password } = (0, validators_1.validate)(validators_1.userCreateSchema, req.body);
|
|
21
|
+
const passwordHash = await (0, crypto_1.hashPassword)(password);
|
|
22
|
+
const user = await models_1.User.create({ username, passwordHash, role: "user" });
|
|
23
|
+
res.status(201).json({
|
|
24
|
+
data: {
|
|
25
|
+
id: user.id,
|
|
26
|
+
username: user.username,
|
|
27
|
+
role: user.role,
|
|
28
|
+
createdAt: user.createdAt.toISOString(),
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34
|
+
res.status(400).json({ error: "Registration failed", message });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// User Login
|
|
38
|
+
static async login(req, res) {
|
|
39
|
+
try {
|
|
40
|
+
const { username, password } = (0, validators_1.validate)(validators_1.loginSchema, req.body);
|
|
41
|
+
const user = await models_1.User.findOne({ where: { username } });
|
|
42
|
+
// Check if user exists and has a password (Authelia users don't have passwords)
|
|
43
|
+
if (!user || !user.passwordHash) {
|
|
44
|
+
res.status(401).json({ error: "Invalid credentials" });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (!(await (0, crypto_1.comparePassword)(password, user.passwordHash))) {
|
|
48
|
+
res.status(401).json({ error: "Invalid credentials" });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const token = JwtService_1.JwtService.generateToken(user);
|
|
52
|
+
res.json({
|
|
53
|
+
data: {
|
|
54
|
+
token,
|
|
55
|
+
expiresIn: JwtService_1.JwtService.getExpiresIn(),
|
|
56
|
+
user: {
|
|
57
|
+
id: user.id,
|
|
58
|
+
username: user.username,
|
|
59
|
+
role: user.role,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
66
|
+
res.status(400).json({ error: "Login failed", message });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Get current user
|
|
70
|
+
static async me(req, res) {
|
|
71
|
+
try {
|
|
72
|
+
const user = await models_1.User.findByPk(req.user.userId);
|
|
73
|
+
res.json({ data: user });
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
77
|
+
res.status(500).json({ error: "Failed to get user", message });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ==================== Claude OAuth with Redirects ====================
|
|
81
|
+
static async claudeLoginRedirect(req, res) {
|
|
82
|
+
try {
|
|
83
|
+
const service = new ClaudeAuthService_1.ClaudeAuthService();
|
|
84
|
+
// Get server base URL from request
|
|
85
|
+
const protocol = req.protocol;
|
|
86
|
+
const host = req.get("host");
|
|
87
|
+
const redirectUri = `${protocol}://${host}/api/auth/claude/callback`;
|
|
88
|
+
const result = await service.startLoginWithRedirect(redirectUri);
|
|
89
|
+
// Redirect user to OAuth provider
|
|
90
|
+
res.redirect(result.loginUrl);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
94
|
+
res.status(500).send(`Failed to start Claude login: ${message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
static async claudeCallback(req, res) {
|
|
98
|
+
try {
|
|
99
|
+
const { code, state, session_state } = req.query;
|
|
100
|
+
if (!code || !state) {
|
|
101
|
+
res.status(400).send("Missing code or state parameter");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const service = new ClaudeAuthService_1.ClaudeAuthService();
|
|
105
|
+
const token = await service.completeLoginFromCallback(code, state);
|
|
106
|
+
TokenRefreshService_1.TokenRefreshService.getInstance().start(token.id);
|
|
107
|
+
// Redirect back to frontend with success
|
|
108
|
+
const frontendUrl = req.get("origin") || "http://localhost:5174";
|
|
109
|
+
res.redirect(`${frontendUrl}/?auth=claude&status=success`);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
113
|
+
logger_1.default.error("Claude callback error:", message);
|
|
114
|
+
const frontendUrl = req.get("origin") || "http://localhost:5174";
|
|
115
|
+
res.redirect(`${frontendUrl}/?auth=claude&status=error&message=${encodeURIComponent(message)}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
static async claudeStatus(req, res) {
|
|
119
|
+
try {
|
|
120
|
+
const service = new ClaudeAuthService_1.ClaudeAuthService();
|
|
121
|
+
const status = await service.getStatus();
|
|
122
|
+
res.json({ data: status });
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
+
res.status(500).json({ error: "Failed to get Claude status", message });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// ==================== Claude Manual Code Entry Flow ====================
|
|
130
|
+
static async claudeManualLoginStart(req, res) {
|
|
131
|
+
try {
|
|
132
|
+
const service = new ClaudeAuthService_1.ClaudeAuthService();
|
|
133
|
+
const { loginWithClaudeAi } = req.body;
|
|
134
|
+
const result = await service.startLoginWithRedirect(undefined, loginWithClaudeAi !== false);
|
|
135
|
+
// Return login URL and state to frontend
|
|
136
|
+
// Frontend will open URL in new tab and show code input
|
|
137
|
+
res.json({
|
|
138
|
+
data: {
|
|
139
|
+
loginUrl: result.loginUrl,
|
|
140
|
+
state: result.state,
|
|
141
|
+
redirectUri: "https://console.anthropic.com/oauth/code/callback",
|
|
142
|
+
scopes: [
|
|
143
|
+
"org:create_api_key",
|
|
144
|
+
"user:profile",
|
|
145
|
+
"user:inference",
|
|
146
|
+
"user:sessions:claude_code",
|
|
147
|
+
],
|
|
148
|
+
instructions: "After authenticating, copy the entire callback URL from the browser and paste it in the application.",
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
154
|
+
res.status(500).json({ error: "Failed to start Claude login", message });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
static async claudeManualLoginComplete(req, res) {
|
|
158
|
+
try {
|
|
159
|
+
let { code, state } = req.body;
|
|
160
|
+
if (!code || !state) {
|
|
161
|
+
res.status(400).json({ error: "Missing code or state parameter" });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Parse callback input (user might paste full URL)
|
|
165
|
+
const parsed = ClaudeAuthService_1.ClaudeAuthService.parseCallbackInput(code);
|
|
166
|
+
if (parsed.code) {
|
|
167
|
+
code = parsed.code;
|
|
168
|
+
}
|
|
169
|
+
if (parsed.state && !state) {
|
|
170
|
+
state = parsed.state;
|
|
171
|
+
}
|
|
172
|
+
const service = new ClaudeAuthService_1.ClaudeAuthService();
|
|
173
|
+
const token = await service.completeLoginFromCallback(code, state);
|
|
174
|
+
res.json({
|
|
175
|
+
data: {
|
|
176
|
+
tokenId: token.id,
|
|
177
|
+
email: token.email,
|
|
178
|
+
expiresAt: token.expiresAt?.toISOString(),
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
184
|
+
logger_1.default.error("Claude login complete error:", message);
|
|
185
|
+
res
|
|
186
|
+
.status(500)
|
|
187
|
+
.json({ error: "Failed to complete Claude login", message });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// ==================== Codex Device Auth (unchanged) ====================
|
|
191
|
+
static async codexLoginStart(req, res) {
|
|
192
|
+
try {
|
|
193
|
+
const service = new CodexAuthService_1.CodexAuthService();
|
|
194
|
+
const result = await service.startLogin();
|
|
195
|
+
res.json({ data: result });
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
199
|
+
res.status(500).json({ error: "Failed to start Codex login", message });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
static async codexLoginPoll(req, res) {
|
|
203
|
+
try {
|
|
204
|
+
const service = new CodexAuthService_1.CodexAuthService();
|
|
205
|
+
const token = await service.pollForToken(req.body);
|
|
206
|
+
res.json({ data: { tokenId: token.id, email: token.email } });
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
210
|
+
res.status(400).json({ error: "Device auth not yet approved", message });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
static async codexStatus(req, res) {
|
|
214
|
+
try {
|
|
215
|
+
const service = new CodexAuthService_1.CodexAuthService();
|
|
216
|
+
const status = await service.getStatus();
|
|
217
|
+
res.json({ data: status });
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
221
|
+
res.status(500).json({ error: "Failed to get Codex status", message });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// ==================== Gemini OAuth with Manual Code ====================
|
|
225
|
+
static async geminiLoginStart(req, res) {
|
|
226
|
+
try {
|
|
227
|
+
const service = new GeminiAuthService_1.GeminiAuthService();
|
|
228
|
+
const result = await service.startLoginWithRedirect("");
|
|
229
|
+
// Return login URL and state to frontend
|
|
230
|
+
// Frontend will open URL in new tab and show code input
|
|
231
|
+
res.json({
|
|
232
|
+
data: {
|
|
233
|
+
loginUrl: result.loginUrl,
|
|
234
|
+
state: result.state,
|
|
235
|
+
verificationUrl: "https://codeassist.google.com/authcode",
|
|
236
|
+
instructions: "After authenticating, Google will show you an authorization code. Copy it and paste it in the application.",
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
242
|
+
res.status(500).json({ error: "Failed to start Gemini login", message });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
static async geminiLoginComplete(req, res) {
|
|
246
|
+
try {
|
|
247
|
+
const { code, state } = req.body;
|
|
248
|
+
if (!code || !state) {
|
|
249
|
+
res.status(400).json({ error: "Missing code or state parameter" });
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const service = new GeminiAuthService_1.GeminiAuthService();
|
|
253
|
+
const token = await service.completeLoginFromCallback(code, state);
|
|
254
|
+
res.json({
|
|
255
|
+
data: {
|
|
256
|
+
tokenId: token.id,
|
|
257
|
+
email: token.email,
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
263
|
+
logger_1.default.error("Gemini login complete error:", message);
|
|
264
|
+
res
|
|
265
|
+
.status(500)
|
|
266
|
+
.json({ error: "Failed to complete Gemini login", message });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
static async geminiStatus(req, res) {
|
|
270
|
+
try {
|
|
271
|
+
const service = new GeminiAuthService_1.GeminiAuthService();
|
|
272
|
+
const status = await service.getStatus();
|
|
273
|
+
res.json({ data: status });
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
277
|
+
res.status(500).json({ error: "Failed to get Gemini status", message });
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
exports.AuthController = AuthController;
|
|
282
|
+
//# sourceMappingURL=AuthController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthController.js","sourceRoot":"","sources":["../../src/controllers/AuthController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Request, Response } from "express";
|
|
2
|
+
export declare class ConversationController {
|
|
3
|
+
/**
|
|
4
|
+
* Create a new conversation
|
|
5
|
+
* POST /api/conversations
|
|
6
|
+
*/
|
|
7
|
+
static create(req: Request, res: Response): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Get a conversation by ID
|
|
10
|
+
* GET /api/conversations/:conversationId
|
|
11
|
+
*/
|
|
12
|
+
static get(req: Request, res: Response): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Update a conversation
|
|
15
|
+
* PATCH /api/conversations/:conversationId
|
|
16
|
+
*/
|
|
17
|
+
static update(req: Request, res: Response): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Get available providers
|
|
20
|
+
* GET /api/conversations/providers
|
|
21
|
+
*/
|
|
22
|
+
static getProviders(req: Request, res: Response): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Get conversation messages
|
|
25
|
+
* GET /api/conversations/:conversationId/messages
|
|
26
|
+
*/
|
|
27
|
+
static getMessages(req: Request, res: Response): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Send a message in a conversation
|
|
30
|
+
* POST /api/conversations/:conversationId/messages
|
|
31
|
+
*/
|
|
32
|
+
static sendMessage(req: Request, res: Response): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Stream a conversation (SSE)
|
|
35
|
+
* GET /api/conversations/:conversationId/stream
|
|
36
|
+
*/
|
|
37
|
+
static stream(req: Request, res: Response): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Delete a conversation
|
|
40
|
+
* DELETE /api/conversations/:conversationId
|
|
41
|
+
*/
|
|
42
|
+
static delete(req: Request, res: Response): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ConversationController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversationController.d.ts","sourceRoot":"","sources":["../../src/controllers/ConversationController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAS5C,qBAAa,sBAAsB;IACjC;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC/D;;;OAGG;WACU,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB5D;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB/D;;;OAGG;WACU,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrE;;;OAGG;WACU,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBpE;;;OAGG;WACU,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BpE;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC/D;;;OAGG;WACU,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAahE"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ConversationController = void 0;
|
|
7
|
+
const ConversationService_1 = require("../services/conversation/ConversationService");
|
|
8
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
9
|
+
class ConversationController {
|
|
10
|
+
/**
|
|
11
|
+
* Create a new conversation
|
|
12
|
+
* POST /api/conversations
|
|
13
|
+
*/
|
|
14
|
+
static async create(req, res) {
|
|
15
|
+
try {
|
|
16
|
+
const { jobId, provider, model, title, systemPrompt } = req.body;
|
|
17
|
+
if (!jobId || !provider) {
|
|
18
|
+
res.status(400).json({ error: "jobId and provider are required" });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const { conversation, provider: llmProvider } = await ConversationService_1.ConversationService.createConversation({
|
|
22
|
+
jobId,
|
|
23
|
+
provider,
|
|
24
|
+
model,
|
|
25
|
+
title,
|
|
26
|
+
systemPrompt,
|
|
27
|
+
});
|
|
28
|
+
res.status(201).json({
|
|
29
|
+
conversation,
|
|
30
|
+
providerInfo: {
|
|
31
|
+
type: llmProvider.constructor.name,
|
|
32
|
+
model: llmProvider.model,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
38
|
+
logger_1.default.error("Error creating conversation:", message);
|
|
39
|
+
res.status(500).json({ error: message });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get a conversation by ID
|
|
44
|
+
* GET /api/conversations/:conversationId
|
|
45
|
+
*/
|
|
46
|
+
static async get(req, res) {
|
|
47
|
+
try {
|
|
48
|
+
const { conversationId } = req.params;
|
|
49
|
+
const conversation = await ConversationService_1.ConversationService.getConversation(conversationId);
|
|
50
|
+
if (!conversation) {
|
|
51
|
+
res.status(404).json({ error: "Conversation not found" });
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
res.json(conversation);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
58
|
+
logger_1.default.error("Error getting conversation:", message);
|
|
59
|
+
res.status(500).json({ error: message });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Update a conversation
|
|
64
|
+
* PATCH /api/conversations/:conversationId
|
|
65
|
+
*/
|
|
66
|
+
static async update(req, res) {
|
|
67
|
+
try {
|
|
68
|
+
const { conversationId } = req.params;
|
|
69
|
+
const params = req.body;
|
|
70
|
+
const conversation = await ConversationService_1.ConversationService.updateConversation(conversationId, params);
|
|
71
|
+
res.json(conversation);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
75
|
+
logger_1.default.error("Error updating conversation:", message);
|
|
76
|
+
res.status(500).json({ error: message });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get available providers
|
|
81
|
+
* GET /api/conversations/providers
|
|
82
|
+
*/
|
|
83
|
+
static async getProviders(req, res) {
|
|
84
|
+
try {
|
|
85
|
+
const providers = await ConversationService_1.ConversationService.getAvailableProviders();
|
|
86
|
+
res.json({ providers });
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
90
|
+
logger_1.default.error("Error getting providers:", message);
|
|
91
|
+
res.status(500).json({ error: message });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get conversation messages
|
|
96
|
+
* GET /api/conversations/:conversationId/messages
|
|
97
|
+
*/
|
|
98
|
+
static async getMessages(req, res) {
|
|
99
|
+
try {
|
|
100
|
+
const { conversationId } = req.params;
|
|
101
|
+
const limit = req.query.limit
|
|
102
|
+
? parseInt(req.query.limit, 10)
|
|
103
|
+
: undefined;
|
|
104
|
+
const offset = req.query.offset
|
|
105
|
+
? parseInt(req.query.offset, 10)
|
|
106
|
+
: undefined;
|
|
107
|
+
const result = await ConversationService_1.ConversationService.getMessages(conversationId, {
|
|
108
|
+
limit,
|
|
109
|
+
offset,
|
|
110
|
+
});
|
|
111
|
+
res.json(result);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
115
|
+
logger_1.default.error("Error getting messages:", message);
|
|
116
|
+
res.status(500).json({ error: message });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Send a message in a conversation
|
|
121
|
+
* POST /api/conversations/:conversationId/messages
|
|
122
|
+
*/
|
|
123
|
+
static async sendMessage(req, res) {
|
|
124
|
+
try {
|
|
125
|
+
const { conversationId } = req.params;
|
|
126
|
+
const { content, attachments } = req.body;
|
|
127
|
+
if (!content) {
|
|
128
|
+
res.status(400).json({ error: "content is required" });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const result = await ConversationService_1.ConversationService.sendMessage({
|
|
132
|
+
conversationId,
|
|
133
|
+
content,
|
|
134
|
+
attachments,
|
|
135
|
+
});
|
|
136
|
+
res.json(result);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
140
|
+
logger_1.default.error("Error sending message:", message);
|
|
141
|
+
res.status(500).json({ error: message });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Stream a conversation (SSE)
|
|
146
|
+
* GET /api/conversations/:conversationId/stream
|
|
147
|
+
*/
|
|
148
|
+
static async stream(req, res) {
|
|
149
|
+
try {
|
|
150
|
+
const { conversationId } = req.params;
|
|
151
|
+
// Set up SSE
|
|
152
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
153
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
154
|
+
res.setHeader("Connection", "keep-alive");
|
|
155
|
+
// Send chunks as SSE events
|
|
156
|
+
const result = await ConversationService_1.ConversationService.sendMessage({
|
|
157
|
+
conversationId,
|
|
158
|
+
content: req.body.content,
|
|
159
|
+
attachments: req.body.attachments,
|
|
160
|
+
onChunk: (chunk) => {
|
|
161
|
+
res.write(`data: ${JSON.stringify({ type: "chunk", content: chunk })}\n\n`);
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
// Send final message
|
|
165
|
+
res.write(`data: ${JSON.stringify({ type: "done", result })}\n\n`);
|
|
166
|
+
res.end();
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
170
|
+
logger_1.default.error("Error streaming conversation:", message);
|
|
171
|
+
res.write(`data: ${JSON.stringify({ type: "error", error: message })}\n\n`);
|
|
172
|
+
res.end();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Delete a conversation
|
|
177
|
+
* DELETE /api/conversations/:conversationId
|
|
178
|
+
*/
|
|
179
|
+
static async delete(req, res) {
|
|
180
|
+
try {
|
|
181
|
+
const { conversationId } = req.params;
|
|
182
|
+
await ConversationService_1.ConversationService.deleteConversation(conversationId);
|
|
183
|
+
res.status(204).send();
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
187
|
+
logger_1.default.error("Error deleting conversation:", message);
|
|
188
|
+
res.status(500).json({ error: message });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.ConversationController = ConversationController;
|
|
193
|
+
//# sourceMappingURL=ConversationController.js.map
|