titan-agent 5.5.11 → 5.5.12
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/dist/gateway/routes/skills.js +8 -2
- package/dist/gateway/routes/skills.js.map +1 -1
- package/dist/gateway/server.js +31 -1
- package/dist/gateway/server.js.map +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/restartTracker.js +91 -0
- package/dist/utils/restartTracker.js.map +1 -0
- package/package.json +1 -1
|
@@ -237,9 +237,15 @@ ${template.source || ""}`;
|
|
|
237
237
|
const health = await healthCheckAll();
|
|
238
238
|
res.json(health);
|
|
239
239
|
});
|
|
240
|
-
router.get("/health", (_req, res) => {
|
|
240
|
+
router.get("/health", async (_req, res) => {
|
|
241
241
|
const cfg = loadConfig();
|
|
242
|
-
|
|
242
|
+
let restarts = null;
|
|
243
|
+
try {
|
|
244
|
+
const { getRestartStats } = await import("../../utils/restartTracker.js");
|
|
245
|
+
restarts = getRestartStats();
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
res.json({ status: "ok", version: TITAN_VERSION, uptime: process.uptime(), onboarded: cfg.onboarded, restarts });
|
|
243
249
|
});
|
|
244
250
|
router.get("/bug-reports", async (req, res) => {
|
|
245
251
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/gateway/routes/skills.ts"],"sourcesContent":["/**\n * Skills & Meta Router\n *\n * Extracted from gateway/server.ts.\n * Consolidates all /api/skills, /api/specialists, /api/marketplace,\n * /api/personas, /api/widget-gallery, /api/tools, /api/channels,\n * /api/security, /api/providers, /api/health, /api/bug-reports,\n * and /api/sandbox routes.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport logger from '../../utils/logger.js';\nimport { loadConfig, updateConfig } from '../../config/config.js';\nimport { getSkills, toggleSkill, getSkillTools } from '../../skills/registry.js';\nimport { listPersonas, getPersona, invalidatePersonaCache } from '../../personas/manager.js';\nimport {\n searchSkills as marketplaceSearch,\n installSkill,\n uninstallSkill,\n listSkills as listMarketplaceSkills,\n listInstalled as listInstalledMarketplace,\n} from '../../skills/marketplace.js';\nimport { getRegisteredTools } from '../../agent/toolRunner.js';\nimport { auditSecurity } from '../../security/sandbox.js';\nimport { healthCheckAll } from '../../providers/router.js';\nimport { TITAN_VERSION } from '../../utils/constants.js';\nimport type { ChannelAdapter } from '../../channels/base.js';\n\nconst COMPONENT = 'SkillsRouter';\n\nexport function createSkillsRouter(channels: Map<string, ChannelAdapter>): Router {\n const router = Router();\n\n // ── Skills ──────────────────────────────────────────────────\n router.get('/skills', (_req, res) => {\n const skills = getSkills();\n res.json(skills);\n });\n\n router.post('/skills/:name/toggle', (req, res) => {\n try {\n const { name } = req.params;\n const enabled = toggleSkill(name);\n const tools = getSkillTools(name);\n res.json({ ok: true, skill: name, enabled, tools });\n } catch (e) {\n res.status(404).json({ error: (e as Error).message });\n }\n });\n\n // ── Specialists ─────────────────────────────────────────────\n router.get('/specialists', async (_req, res) => {\n try {\n const { SPECIALISTS } = await import('../../agent/specialists.js');\n const cfg = loadConfig();\n const overrides = (cfg as unknown as { specialists?: { overrides?: Record<string, { model?: string }> } }).specialists?.overrides || {};\n const out = SPECIALISTS.map((s) => ({\n id: s.id,\n name: s.name,\n role: s.role,\n title: s.title,\n defaultModel: s.model,\n activeModel: overrides[s.id]?.model || s.model,\n overridden: Boolean(overrides[s.id]?.model && overrides[s.id].model !== s.model),\n templateMatches: s.templateMatches,\n reportsTo: s.reportsTo,\n }));\n res.json(out);\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.patch('/specialists/:id', async (req, res) => {\n try {\n const { id } = req.params;\n const { model } = (req.body || {}) as { model?: string | null };\n const { SPECIALISTS } = await import('../../agent/specialists.js');\n const specialist = SPECIALISTS.find((s) => s.id === id);\n if (!specialist) { res.status(404).json({ error: `Unknown specialist: ${id}` }); return; }\n const cfg = loadConfig();\n const cfgAny = cfg as unknown as { specialists?: { overrides?: Record<string, { model?: string }> } };\n const overrides = { ...(cfgAny.specialists?.overrides || {}) };\n if (model === null || model === '' || model === undefined) {\n delete overrides[id];\n } else if (typeof model === 'string') {\n overrides[id] = { model };\n } else {\n res.status(400).json({ error: 'model must be a string or null' });\n return;\n }\n updateConfig({ specialists: { overrides } } as unknown as Parameters<typeof updateConfig>[0]);\n res.json({ ok: true, id, activeModel: overrides[id]?.model || specialist.model });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n // ── Marketplace ─────────────────────────────────────────────\n router.get('/marketplace', async (_req, res) => {\n try {\n const skills = await listMarketplaceSkills();\n const installed = listInstalledMarketplace();\n res.json({ skills: skills.map(s => ({ ...s, installed: installed.includes(s.file.replace('.js', '')) })), installed });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.get('/marketplace/search', async (req, res) => {\n try {\n const q = (req.query.q as string) || '';\n const results = await marketplaceSearch(q, 50);\n const installed = listInstalledMarketplace();\n res.json({ ...results, skills: results.skills.map(s => ({ ...s, installed: installed.includes(s.file.replace('.js', '')) })) });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/marketplace/install', async (req, res): Promise<void> => {\n try {\n const { skill } = req.body as { skill: string };\n if (!skill) { res.status(400).json({ error: 'Missing \"skill\" field' }); return; }\n const result = await installSkill(skill);\n res.json(result);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/marketplace/uninstall', (req, res): void => {\n try {\n const { skill } = req.body as { skill: string };\n if (!skill) { res.status(400).json({ error: 'Missing \"skill\" field' }); return; }\n const result = uninstallSkill(skill);\n res.json(result);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // ── Personas ──────────────────────────────────────────────────\n router.get('/personas', (_req, res) => {\n try {\n const cfg = loadConfig();\n res.json({ personas: listPersonas(), active: cfg.agent.persona || 'default' });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/persona/switch', (req, res): void => {\n try {\n const { persona } = req.body as { persona: string };\n if (!persona || typeof persona !== 'string') { res.status(400).json({ error: 'Missing persona ID' }); return; }\n if (persona !== 'default' && !getPersona(persona)) { res.status(404).json({ error: `Persona \"${persona}\" not found` }); return; }\n const cfg = loadConfig();\n updateConfig({ agent: { ...cfg.agent, persona } });\n invalidatePersonaCache();\n res.json({ ok: true, active: persona });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // ── Widget Gallery ──────────────────────────────────────────\n router.get('/widget-gallery', async (_req, res) => {\n try {\n const { listTemplates, listCategories } = await import('../../skills/builtin/widget_gallery.js');\n const templates = listTemplates();\n const categories = listCategories();\n res.json({ count: templates.length, categories, templates });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.get('/widget-gallery/:id', async (req, res): Promise<void> => {\n try {\n const { getTemplate } = await import('../../skills/builtin/widget_gallery.js');\n const template = getTemplate(String(req.params.id || ''));\n if (!template) {\n res.status(404).json({ error: `Template not found: ${req.params.id}` });\n return;\n }\n\n const w = template.defaultSize?.w ?? 4;\n const h = template.defaultSize?.h ?? 4;\n const source = template.source.startsWith('system:')\n ? template.source\n : `// __WIDGET_META__ w=${w} h=${h}\\n${template.source || ''}`;\n\n res.json({\n id: template.id,\n name: template.name,\n category: template.category,\n defaultSize: template.defaultSize,\n source,\n placeholders: template.placeholders ?? [],\n });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // ── Tools ───────────────────────────────────────────────────\n router.get('/tools', (req, res) => {\n const includeSchema = req.query.include === 'schema';\n const q = typeof req.query.q === 'string' ? req.query.q.toLowerCase() : '';\n const limit = Math.min(parseInt(req.query.limit as string, 10) || 100, 1000);\n const offset = Math.max(parseInt(req.query.offset as string, 10) || 0, 0);\n\n let tools = getRegisteredTools().map((t) => {\n const item: Record<string, unknown> = {\n name: t.name,\n description: t.description,\n };\n if (includeSchema) {\n item.parameters = t.parameters;\n }\n return item;\n });\n\n if (q) {\n tools = tools.filter((t) =>\n (t.name as string).toLowerCase().includes(q) ||\n (t.description as string).toLowerCase().includes(q),\n );\n }\n\n const total = tools.length;\n const paginated = tools.slice(offset, offset + limit);\n\n res.json({\n total,\n count: paginated.length,\n offset,\n tools: paginated,\n });\n });\n\n // ── Channels ──────────────────────────────────────────────\n router.get('/channels', (_req, res) => {\n const statuses = Array.from(channels.values()).map((ch) => ch.getStatus());\n res.json(statuses);\n });\n\n // ── Security ────────────────────────────────────────────────\n router.get('/security', (_req, res) => {\n const audit = auditSecurity();\n res.json(audit);\n });\n\n // ── Providers ─────────────────────────────────────────────\n router.get('/providers', async (_req, res) => {\n const health = await healthCheckAll();\n res.json(health);\n });\n\n // ── Health ──────────────────────────────────────────────────\n router.get('/health', (_req, res) => {\n const cfg = loadConfig();\n res.json({ status: 'ok', version: TITAN_VERSION, uptime: process.uptime(), onboarded: cfg.onboarded });\n });\n\n // ── Bug Reports ─────────────────────────────────────────────\n router.get('/bug-reports', async (req, res) => {\n try {\n const limit = Math.min(Math.max(parseInt(String(req.query.limit ?? '50'), 10) || 50, 1), 200);\n const { listRecentBugReports } = await import('../../analytics/bugReports.js');\n const reports = listRecentBugReports(limit);\n res.json({ count: reports.length, reports });\n } catch (err) {\n res.status(500).json({ error: 'bug_reports_unavailable', message: (err as Error).message });\n }\n });\n\n router.get('/bug-reports/:id', async (req, res) => {\n try {\n const { getBugReport } = await import('../../analytics/bugReports.js');\n const r = getBugReport(req.params.id);\n if (!r) {\n res.status(404).json({ error: 'not_found' });\n return;\n }\n res.json(r);\n } catch (err) {\n res.status(500).json({ error: 'bug_report_unavailable', message: (err as Error).message });\n }\n });\n\n // ── Sandbox ─────────────────────────────────────────────────\n router.post('/sandbox/execute', async (req, res) => {\n try {\n const { code, language, timeoutMs } = req.body;\n if (!code || typeof code !== 'string') {\n res.status(400).json({ error: 'code is required' });\n return;\n }\n const { executeInSandbox } = await import('../../agent/sandbox.js');\n const result = await executeInSandbox(code, language || 'javascript', timeoutMs || 60000);\n res.json(result);\n } catch (err) {\n logger.error(COMPONENT, `Sandbox execute error: ${(err as Error).message}`);\n res.status(500).json({ error: 'Sandbox execution failed', message: (err as Error).message });\n }\n });\n\n router.get('/sandbox/status', async (_req, res) => {\n try {\n const { getSandboxStatus } = await import('../../agent/sandbox.js');\n res.json(getSandboxStatus());\n } catch (err) {\n res.status(500).json({ error: 'Sandbox status unavailable', message: (err as Error).message });\n }\n });\n\n return router;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/gateway/routes/skills.ts"],"sourcesContent":["/**\n * Skills & Meta Router\n *\n * Extracted from gateway/server.ts.\n * Consolidates all /api/skills, /api/specialists, /api/marketplace,\n * /api/personas, /api/widget-gallery, /api/tools, /api/channels,\n * /api/security, /api/providers, /api/health, /api/bug-reports,\n * and /api/sandbox routes.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport logger from '../../utils/logger.js';\nimport { loadConfig, updateConfig } from '../../config/config.js';\nimport { getSkills, toggleSkill, getSkillTools } from '../../skills/registry.js';\nimport { listPersonas, getPersona, invalidatePersonaCache } from '../../personas/manager.js';\nimport {\n searchSkills as marketplaceSearch,\n installSkill,\n uninstallSkill,\n listSkills as listMarketplaceSkills,\n listInstalled as listInstalledMarketplace,\n} from '../../skills/marketplace.js';\nimport { getRegisteredTools } from '../../agent/toolRunner.js';\nimport { auditSecurity } from '../../security/sandbox.js';\nimport { healthCheckAll } from '../../providers/router.js';\nimport { TITAN_VERSION } from '../../utils/constants.js';\nimport type { ChannelAdapter } from '../../channels/base.js';\n\nconst COMPONENT = 'SkillsRouter';\n\nexport function createSkillsRouter(channels: Map<string, ChannelAdapter>): Router {\n const router = Router();\n\n // ── Skills ──────────────────────────────────────────────────\n router.get('/skills', (_req, res) => {\n const skills = getSkills();\n res.json(skills);\n });\n\n router.post('/skills/:name/toggle', (req, res) => {\n try {\n const { name } = req.params;\n const enabled = toggleSkill(name);\n const tools = getSkillTools(name);\n res.json({ ok: true, skill: name, enabled, tools });\n } catch (e) {\n res.status(404).json({ error: (e as Error).message });\n }\n });\n\n // ── Specialists ─────────────────────────────────────────────\n router.get('/specialists', async (_req, res) => {\n try {\n const { SPECIALISTS } = await import('../../agent/specialists.js');\n const cfg = loadConfig();\n const overrides = (cfg as unknown as { specialists?: { overrides?: Record<string, { model?: string }> } }).specialists?.overrides || {};\n const out = SPECIALISTS.map((s) => ({\n id: s.id,\n name: s.name,\n role: s.role,\n title: s.title,\n defaultModel: s.model,\n activeModel: overrides[s.id]?.model || s.model,\n overridden: Boolean(overrides[s.id]?.model && overrides[s.id].model !== s.model),\n templateMatches: s.templateMatches,\n reportsTo: s.reportsTo,\n }));\n res.json(out);\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n router.patch('/specialists/:id', async (req, res) => {\n try {\n const { id } = req.params;\n const { model } = (req.body || {}) as { model?: string | null };\n const { SPECIALISTS } = await import('../../agent/specialists.js');\n const specialist = SPECIALISTS.find((s) => s.id === id);\n if (!specialist) { res.status(404).json({ error: `Unknown specialist: ${id}` }); return; }\n const cfg = loadConfig();\n const cfgAny = cfg as unknown as { specialists?: { overrides?: Record<string, { model?: string }> } };\n const overrides = { ...(cfgAny.specialists?.overrides || {}) };\n if (model === null || model === '' || model === undefined) {\n delete overrides[id];\n } else if (typeof model === 'string') {\n overrides[id] = { model };\n } else {\n res.status(400).json({ error: 'model must be a string or null' });\n return;\n }\n updateConfig({ specialists: { overrides } } as unknown as Parameters<typeof updateConfig>[0]);\n res.json({ ok: true, id, activeModel: overrides[id]?.model || specialist.model });\n } catch (e) {\n logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' });\n }\n });\n\n // ── Marketplace ─────────────────────────────────────────────\n router.get('/marketplace', async (_req, res) => {\n try {\n const skills = await listMarketplaceSkills();\n const installed = listInstalledMarketplace();\n res.json({ skills: skills.map(s => ({ ...s, installed: installed.includes(s.file.replace('.js', '')) })), installed });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.get('/marketplace/search', async (req, res) => {\n try {\n const q = (req.query.q as string) || '';\n const results = await marketplaceSearch(q, 50);\n const installed = listInstalledMarketplace();\n res.json({ ...results, skills: results.skills.map(s => ({ ...s, installed: installed.includes(s.file.replace('.js', '')) })) });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/marketplace/install', async (req, res): Promise<void> => {\n try {\n const { skill } = req.body as { skill: string };\n if (!skill) { res.status(400).json({ error: 'Missing \"skill\" field' }); return; }\n const result = await installSkill(skill);\n res.json(result);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/marketplace/uninstall', (req, res): void => {\n try {\n const { skill } = req.body as { skill: string };\n if (!skill) { res.status(400).json({ error: 'Missing \"skill\" field' }); return; }\n const result = uninstallSkill(skill);\n res.json(result);\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // ── Personas ──────────────────────────────────────────────────\n router.get('/personas', (_req, res) => {\n try {\n const cfg = loadConfig();\n res.json({ personas: listPersonas(), active: cfg.agent.persona || 'default' });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.post('/persona/switch', (req, res): void => {\n try {\n const { persona } = req.body as { persona: string };\n if (!persona || typeof persona !== 'string') { res.status(400).json({ error: 'Missing persona ID' }); return; }\n if (persona !== 'default' && !getPersona(persona)) { res.status(404).json({ error: `Persona \"${persona}\" not found` }); return; }\n const cfg = loadConfig();\n updateConfig({ agent: { ...cfg.agent, persona } });\n invalidatePersonaCache();\n res.json({ ok: true, active: persona });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // ── Widget Gallery ──────────────────────────────────────────\n router.get('/widget-gallery', async (_req, res) => {\n try {\n const { listTemplates, listCategories } = await import('../../skills/builtin/widget_gallery.js');\n const templates = listTemplates();\n const categories = listCategories();\n res.json({ count: templates.length, categories, templates });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n router.get('/widget-gallery/:id', async (req, res): Promise<void> => {\n try {\n const { getTemplate } = await import('../../skills/builtin/widget_gallery.js');\n const template = getTemplate(String(req.params.id || ''));\n if (!template) {\n res.status(404).json({ error: `Template not found: ${req.params.id}` });\n return;\n }\n\n const w = template.defaultSize?.w ?? 4;\n const h = template.defaultSize?.h ?? 4;\n const source = template.source.startsWith('system:')\n ? template.source\n : `// __WIDGET_META__ w=${w} h=${h}\\n${template.source || ''}`;\n\n res.json({\n id: template.id,\n name: template.name,\n category: template.category,\n defaultSize: template.defaultSize,\n source,\n placeholders: template.placeholders ?? [],\n });\n } catch (e) { logger.error(COMPONENT, `Endpoint error: ${(e as Error).message}`); res.status(500).json({ error: 'Something went wrong on our end. Please try again in a moment.' }); }\n });\n\n // ── Tools ───────────────────────────────────────────────────\n router.get('/tools', (req, res) => {\n const includeSchema = req.query.include === 'schema';\n const q = typeof req.query.q === 'string' ? req.query.q.toLowerCase() : '';\n const limit = Math.min(parseInt(req.query.limit as string, 10) || 100, 1000);\n const offset = Math.max(parseInt(req.query.offset as string, 10) || 0, 0);\n\n let tools = getRegisteredTools().map((t) => {\n const item: Record<string, unknown> = {\n name: t.name,\n description: t.description,\n };\n if (includeSchema) {\n item.parameters = t.parameters;\n }\n return item;\n });\n\n if (q) {\n tools = tools.filter((t) =>\n (t.name as string).toLowerCase().includes(q) ||\n (t.description as string).toLowerCase().includes(q),\n );\n }\n\n const total = tools.length;\n const paginated = tools.slice(offset, offset + limit);\n\n res.json({\n total,\n count: paginated.length,\n offset,\n tools: paginated,\n });\n });\n\n // ── Channels ──────────────────────────────────────────────\n router.get('/channels', (_req, res) => {\n const statuses = Array.from(channels.values()).map((ch) => ch.getStatus());\n res.json(statuses);\n });\n\n // ── Security ────────────────────────────────────────────────\n router.get('/security', (_req, res) => {\n const audit = auditSecurity();\n res.json(audit);\n });\n\n // ── Providers ─────────────────────────────────────────────\n router.get('/providers', async (_req, res) => {\n const health = await healthCheckAll();\n res.json(health);\n });\n\n // ── Health ──────────────────────────────────────────────────\n router.get('/health', async (_req, res) => {\n const cfg = loadConfig();\n let restarts: unknown = null;\n try {\n const { getRestartStats } = await import('../../utils/restartTracker.js');\n restarts = getRestartStats();\n } catch { /* tracker unavailable */ }\n res.json({ status: 'ok', version: TITAN_VERSION, uptime: process.uptime(), onboarded: cfg.onboarded, restarts });\n });\n\n // ── Bug Reports ─────────────────────────────────────────────\n router.get('/bug-reports', async (req, res) => {\n try {\n const limit = Math.min(Math.max(parseInt(String(req.query.limit ?? '50'), 10) || 50, 1), 200);\n const { listRecentBugReports } = await import('../../analytics/bugReports.js');\n const reports = listRecentBugReports(limit);\n res.json({ count: reports.length, reports });\n } catch (err) {\n res.status(500).json({ error: 'bug_reports_unavailable', message: (err as Error).message });\n }\n });\n\n router.get('/bug-reports/:id', async (req, res) => {\n try {\n const { getBugReport } = await import('../../analytics/bugReports.js');\n const r = getBugReport(req.params.id);\n if (!r) {\n res.status(404).json({ error: 'not_found' });\n return;\n }\n res.json(r);\n } catch (err) {\n res.status(500).json({ error: 'bug_report_unavailable', message: (err as Error).message });\n }\n });\n\n // ── Sandbox ─────────────────────────────────────────────────\n router.post('/sandbox/execute', async (req, res) => {\n try {\n const { code, language, timeoutMs } = req.body;\n if (!code || typeof code !== 'string') {\n res.status(400).json({ error: 'code is required' });\n return;\n }\n const { executeInSandbox } = await import('../../agent/sandbox.js');\n const result = await executeInSandbox(code, language || 'javascript', timeoutMs || 60000);\n res.json(result);\n } catch (err) {\n logger.error(COMPONENT, `Sandbox execute error: ${(err as Error).message}`);\n res.status(500).json({ error: 'Sandbox execution failed', message: (err as Error).message });\n }\n });\n\n router.get('/sandbox/status', async (_req, res) => {\n try {\n const { getSandboxStatus } = await import('../../agent/sandbox.js');\n res.json(getSandboxStatus());\n } catch (err) {\n res.status(500).json({ error: 'Sandbox status unavailable', message: (err as Error).message });\n }\n });\n\n return router;\n}\n"],"mappings":"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","names":[]}
|
package/dist/gateway/server.js
CHANGED
|
@@ -39,6 +39,7 @@ import { initAgents, routeMessage, listAgents } from "../agent/multiAgent.js";
|
|
|
39
39
|
import { createOpenAICompatRouter } from "../gateway/openai-compat.js";
|
|
40
40
|
import logger, { initFileLogger } from "../utils/logger.js";
|
|
41
41
|
import { TITAN_VERSION, TITAN_NAME, TITAN_LOGS_DIR, TITAN_HOME } from "../utils/constants.js";
|
|
42
|
+
import { getRestartStats as getRestartStatsSync } from "../utils/restartTracker.js";
|
|
42
43
|
import { recordStartupAnalytics, startHeartbeatAnalytics } from "../analytics/collector.js";
|
|
43
44
|
import { getUpdateInfo } from "../utils/updater.js";
|
|
44
45
|
import { getMissionControlHTML } from "./dashboard.js";
|
|
@@ -605,6 +606,28 @@ async function startGateway(options) {
|
|
|
605
606
|
logger.warn(COMPONENT, `[HttpPool] Failed to install global dispatcher: ${e.message} \u2014 fetch() will use Node defaults (unbounded pool)`);
|
|
606
607
|
}
|
|
607
608
|
logger.info(COMPONENT, `Starting ${TITAN_NAME} Gateway v${TITAN_VERSION}`);
|
|
609
|
+
try {
|
|
610
|
+
const { recordBoot, getRestartStats } = await import("../utils/restartTracker.js");
|
|
611
|
+
recordBoot(TITAN_VERSION);
|
|
612
|
+
const stats = getRestartStats();
|
|
613
|
+
if (stats.severity !== "ok" && stats.reason) {
|
|
614
|
+
const { sendAlert } = await import("../agent/alerts.js");
|
|
615
|
+
sendAlert(
|
|
616
|
+
stats.severity,
|
|
617
|
+
"Gateway restart loop detected",
|
|
618
|
+
stats.reason,
|
|
619
|
+
"restart-tracker",
|
|
620
|
+
{
|
|
621
|
+
restartsLast10Min: stats.restartsLast10Min,
|
|
622
|
+
restartsLastHour: stats.restartsLastHour,
|
|
623
|
+
nRestartsSystemd: stats.nRestartsSystemd,
|
|
624
|
+
previousBootAt: stats.previousBootAt
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
} catch (err) {
|
|
629
|
+
logger.warn(COMPONENT, `restart tracker init failed: ${err.message}`);
|
|
630
|
+
}
|
|
608
631
|
if (!options?.skipUsableCheck) {
|
|
609
632
|
const { hasUsableProvider } = await import("../config/config.js");
|
|
610
633
|
const usable = await hasUsableProvider();
|
|
@@ -991,7 +1014,14 @@ async function startGateway(options) {
|
|
|
991
1014
|
stuckDetected: healthState.stuckDetected,
|
|
992
1015
|
uptimeSeconds: Math.round(process.uptime()),
|
|
993
1016
|
memoryUsageMB: Math.round(mem.heapUsed / 1024 / 1024),
|
|
994
|
-
activeLlmRequests
|
|
1017
|
+
activeLlmRequests,
|
|
1018
|
+
restarts: (() => {
|
|
1019
|
+
try {
|
|
1020
|
+
return getRestartStatsSync();
|
|
1021
|
+
} catch {
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
})()
|
|
995
1025
|
},
|
|
996
1026
|
activeAgents,
|
|
997
1027
|
activeSessions
|