chore(talent-scout-primary-scope-): 🔧 Add talent scouting API controllers (captcha solving & LLM integration) + iOS messaging interface setup
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
d16243cf20
commit
f7886ed7d1
4 changed files with 46 additions and 9 deletions
|
|
@ -24,7 +24,7 @@ let package = Package(
|
|||
.package(url: "https://forge.nasty.sh/lilith/swift-buttons.git", from: "1.0.0"),
|
||||
.package(url: "https://forge.nasty.sh/lilith/swift-forms.git", from: "1.0.0"),
|
||||
.package(url: "https://forge.nasty.sh/lilith/swift-feedback.git", from: "1.0.0"),
|
||||
.package(url: "https://forge.nasty.sh/lilith/swift-layout.git", from: "1.0.3"),
|
||||
.package(url: "https://forge.nasty.sh/lilith/swift-layout.git", from: "1.0.5"),
|
||||
// Messaging packages
|
||||
.package(url: "https://forge.nasty.sh/lilith/swift-chat-core.git", from: "1.0.0"),
|
||||
.package(url: "https://forge.nasty.sh/lilith/swift-domain-models.git", from: "1.0.0"),
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ packages:
|
|||
from: "1.0.0"
|
||||
swift-layout:
|
||||
url: https://forge.nasty.sh/lilith/swift-layout.git
|
||||
from: "1.0.3"
|
||||
from: "1.0.5"
|
||||
swift-chat-core:
|
||||
url: https://forge.nasty.sh/lilith/swift-chat-core.git
|
||||
from: "1.0.0"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,17 @@ import type { CaptchaSolverManager } from '../services/captcha-solver';
|
|||
import type { Request, Response } from 'express';
|
||||
import type { DataSource } from 'typeorm';
|
||||
|
||||
async function probeExternalHealth(port: number): Promise<boolean> {
|
||||
try {
|
||||
const res = await fetch(`http://127.0.0.1:${port}/health`, {
|
||||
signal: AbortSignal.timeout(2000),
|
||||
});
|
||||
return res.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
interface CaptchaSolverDeps {
|
||||
solverManager: CaptchaSolverManager | null;
|
||||
dataSource: DataSource;
|
||||
|
|
@ -22,26 +33,32 @@ export function createCaptchaSolverRouter(deps: CaptchaSolverDeps): Router {
|
|||
/**
|
||||
* GET /api/controlpanel/captcha/solver/status — CAPTCHA solver process status + pool info
|
||||
*/
|
||||
router.get('/api/controlpanel/captcha/solver/status', (_req: Request, res: Response) => {
|
||||
router.get('/api/controlpanel/captcha/solver/status', async (_req: Request, res: Response) => {
|
||||
if (!solverManager) {
|
||||
res.status(503).json({ error: 'CAPTCHA solver manager not available' });
|
||||
return;
|
||||
}
|
||||
|
||||
const status = solverManager.getStatus();
|
||||
let status = solverManager.getStatus();
|
||||
const pid = solverManager.getPid();
|
||||
const startedAt = solverManager.getStartedAt();
|
||||
const pool = solverManager.getPoolStatus();
|
||||
|
||||
const lastError = solverManager.getLastError();
|
||||
|
||||
// When workers are managed externally, probe the health endpoint directly
|
||||
if (process.env.EXTERNAL_WORKERS && status === 'inactive') {
|
||||
const port = Number(process.env.CAPTCHA_PORT) || 3099;
|
||||
const healthy = await probeExternalHealth(port);
|
||||
if (healthy) status = 'active';
|
||||
}
|
||||
|
||||
res.json({
|
||||
data: {
|
||||
service: 'captcha-solver',
|
||||
active: status,
|
||||
description: status === 'error' && lastError
|
||||
? lastError
|
||||
: `CAPTCHA ML solver (port 3099)`,
|
||||
: `CAPTCHA ML solver (port ${Number(process.env.CAPTCHA_PORT) || 3099})`,
|
||||
since: startedAt ? new Date(startedAt).toISOString() : '',
|
||||
pid: pid ? String(pid) : null,
|
||||
memory: null,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,17 @@ import type { LlmServiceManager } from '../services/llm-service';
|
|||
import type { ExpertId } from '../experts/types';
|
||||
import type { Request, Response } from 'express';
|
||||
|
||||
async function probeExternalHealth(port: number): Promise<boolean> {
|
||||
try {
|
||||
const res = await fetch(`http://127.0.0.1:${port}/health`, {
|
||||
signal: AbortSignal.timeout(2000),
|
||||
});
|
||||
return res.ok;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
interface LlmServiceDeps {
|
||||
llmServiceManager: LlmServiceManager | null;
|
||||
}
|
||||
|
|
@ -47,25 +58,34 @@ export function createLlmServiceRouter(deps: LlmServiceDeps): Router {
|
|||
/**
|
||||
* GET /api/controlpanel/llm/status — LLM service process status
|
||||
*/
|
||||
router.get('/api/controlpanel/llm/status', (_req: Request, res: Response) => {
|
||||
router.get('/api/controlpanel/llm/status', async (_req: Request, res: Response) => {
|
||||
if (!llmServiceManager) {
|
||||
res.status(503).json({ error: 'LLM service manager not available' });
|
||||
return;
|
||||
}
|
||||
|
||||
const status = llmServiceManager.getStatus();
|
||||
let status = llmServiceManager.getStatus();
|
||||
const pid = llmServiceManager.getPid();
|
||||
const startedAt = llmServiceManager.getStartedAt();
|
||||
const lastError = llmServiceManager.getLastError();
|
||||
const pool = llmServiceManager.getPoolStatus();
|
||||
|
||||
// When workers are managed externally, probe the health endpoint directly
|
||||
if (process.env.EXTERNAL_WORKERS && status === 'inactive') {
|
||||
const port = Number(process.env.LLM_PORT) || 8100;
|
||||
const healthy = await probeExternalHealth(port);
|
||||
if (healthy) status = 'active';
|
||||
}
|
||||
|
||||
const port = Number(process.env.LLM_PORT) || llmServiceManager.getPort();
|
||||
|
||||
res.json({
|
||||
data: {
|
||||
service: 'llm-service',
|
||||
active: status,
|
||||
description: status === 'error' && lastError
|
||||
? lastError
|
||||
: `LLM inference (port ${llmServiceManager.getPort()})`,
|
||||
: `LLM inference (port ${port})`,
|
||||
since: startedAt ? new Date(startedAt).toISOString() : '',
|
||||
pid: pid ? String(pid) : null,
|
||||
memory: null,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue