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:
Lilith 2026-02-16 09:31:13 -08:00
parent d16243cf20
commit f7886ed7d1
4 changed files with 46 additions and 9 deletions

View file

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

View file

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

View file

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

View file

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