titan-agent 6.5.2 → 7.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/README.md +180 -53
- package/assets/agent-skills/NOTICE-ECC.md +39 -0
- package/assets/agent-skills/agent-introspection-debugging/SKILL.md +153 -0
- package/assets/agent-skills/continuous-agent-loop/SKILL.md +45 -0
- package/assets/agent-skills/continuous-learning/SKILL.md +131 -0
- package/assets/agent-skills/continuous-learning/config.json +18 -0
- package/assets/agent-skills/continuous-learning/evaluate-session.sh +69 -0
- package/assets/agent-skills/production-audit/SKILL.md +206 -0
- package/assets/agent-skills/recursive-decision-ledger/SKILL.md +79 -0
- package/assets/agent-skills/scientific-thinking-literature-review/SKILL.md +192 -0
- package/assets/agent-skills/scientific-thinking-scholar-evaluation/SKILL.md +160 -0
- package/assets/agent-skills/verification-loop/SKILL.md +126 -0
- package/dist/agent/agent.js +67 -26
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/agentLoop.js +6 -2
- package/dist/agent/agentLoop.js.map +1 -1
- package/dist/agent/autoModeClassifier.js +26 -2
- package/dist/agent/autoModeClassifier.js.map +1 -1
- package/dist/agent/goalDriver.js +2 -0
- package/dist/agent/goalDriver.js.map +1 -1
- package/dist/agent/goalSpec.js +229 -0
- package/dist/agent/goalSpec.js.map +1 -0
- package/dist/agent/heartbeat.js +130 -0
- package/dist/agent/heartbeat.js.map +1 -0
- package/dist/agent/missionDecompose.js +38 -0
- package/dist/agent/missionDecompose.js.map +1 -0
- package/dist/agent/muscleMemory.js +291 -0
- package/dist/agent/muscleMemory.js.map +1 -0
- package/dist/agent/observationWriter.js +56 -0
- package/dist/agent/observationWriter.js.map +1 -0
- package/dist/agent/promptSectionCaps.js +6 -0
- package/dist/agent/promptSectionCaps.js.map +1 -1
- package/dist/agent/reminders.js +101 -0
- package/dist/agent/reminders.js.map +1 -0
- package/dist/agent/systemWidgets.js +41 -0
- package/dist/agent/systemWidgets.js.map +1 -0
- package/dist/agent/toolRunner.js +24 -0
- package/dist/agent/toolRunner.js.map +1 -1
- package/dist/agent/toolSearch.js +3 -0
- package/dist/agent/toolSearch.js.map +1 -1
- package/dist/channels/messenger.js +39 -0
- package/dist/channels/messenger.js.map +1 -1
- package/dist/config/config.js +7 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/schema.js +18 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/eval/harness.js +13 -3
- package/dist/eval/harness.js.map +1 -1
- package/dist/gateway/onboarding.js +91 -0
- package/dist/gateway/onboarding.js.map +1 -0
- package/dist/gateway/routes/skills.js +2 -1
- package/dist/gateway/routes/skills.js.map +1 -1
- package/dist/gateway/routes/studioRouter.js +88 -0
- package/dist/gateway/routes/studioRouter.js.map +1 -0
- package/dist/gateway/routes/watchRouter.js +4 -4
- package/dist/gateway/routes/watchRouter.js.map +1 -1
- package/dist/gateway/server.js +251 -43
- package/dist/gateway/server.js.map +1 -1
- package/dist/memory/taxonomy.js +117 -0
- package/dist/memory/taxonomy.js.map +1 -0
- package/dist/providers/modelCapabilities.js +13 -0
- package/dist/providers/modelCapabilities.js.map +1 -1
- package/dist/providers/ollama.js +8 -2
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.js +1 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openai_compat.js +38 -2
- package/dist/providers/openai_compat.js.map +1 -1
- package/dist/providers/router.js +14 -0
- package/dist/providers/router.js.map +1 -1
- package/dist/recipes/runner.js +8 -1
- package/dist/recipes/runner.js.map +1 -1
- package/dist/recipes/store.js +2 -1
- package/dist/recipes/store.js.map +1 -1
- package/dist/skills/builtin/codebase_explore.js +214 -0
- package/dist/skills/builtin/codebase_explore.js.map +1 -0
- package/dist/skills/builtin/config_audit.js +160 -0
- package/dist/skills/builtin/config_audit.js.map +1 -0
- package/dist/skills/builtin/delegate_agent.js +107 -0
- package/dist/skills/builtin/delegate_agent.js.map +1 -0
- package/dist/skills/builtin/memory_map.js +38 -0
- package/dist/skills/builtin/memory_map.js.map +1 -0
- package/dist/skills/builtin/reminders.js +67 -0
- package/dist/skills/builtin/reminders.js.map +1 -0
- package/dist/skills/builtin/spec.js +139 -0
- package/dist/skills/builtin/spec.js.map +1 -0
- package/dist/skills/builtin/widget_gallery.js +12 -5
- package/dist/skills/builtin/widget_gallery.js.map +1 -1
- package/dist/skills/frontmatterLoader.js +7 -1
- package/dist/skills/frontmatterLoader.js.map +1 -1
- package/dist/skills/registry.js +12 -0
- package/dist/skills/registry.js.map +1 -1
- package/dist/substrate/traceBus.js.map +1 -1
- package/dist/telemetry/traceStore.js +127 -0
- package/dist/telemetry/traceStore.js.map +1 -0
- package/dist/utils/constants.js +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/contrast.js +69 -0
- package/dist/utils/contrast.js.map +1 -0
- package/dist/watch/sessionContext.js +14 -0
- package/dist/watch/sessionContext.js.map +1 -0
- package/dist/watch/sessionTrace.js +51 -0
- package/dist/watch/sessionTrace.js.map +1 -0
- package/dist/watch/studioBuffer.js +53 -0
- package/dist/watch/studioBuffer.js.map +1 -0
- package/package.json +4 -3
- package/ui/dist/assets/AboutYouMemory-CZKEOd_O.js +11 -0
- package/ui/dist/assets/AuditPanel-Bu71N5Er.js +1 -0
- package/ui/dist/assets/{AutonomyPanel-CmaXJV8d.js → AutonomyPanel-DB-39dX4.js} +2 -2
- package/ui/dist/assets/{AutopilotPanel-CbohPtXW.js → AutopilotPanel-Cj8oKxWv.js} +1 -1
- package/ui/dist/assets/{AutoresearchPanel-DCwiQ2v2.js → AutoresearchPanel-3s8pjm6Z.js} +2 -2
- package/ui/dist/assets/BackupPanel-EUQJMJE7.js +1 -0
- package/ui/dist/assets/{BrowserPanel-D6UaSxap.js → BrowserPanel-Beo4F5Ar.js} +2 -2
- package/ui/dist/assets/Button-MdXmb4_n.js +1 -0
- package/ui/dist/assets/CPActivity-B1Se9VVc.js +1 -0
- package/ui/dist/assets/CPAgentDetail-BYji6tT8.js +1 -0
- package/ui/dist/assets/CPAgents-BSUKucTe.js +1 -0
- package/ui/dist/assets/CPApprovals-B4v0em6e.js +1 -0
- package/ui/dist/assets/CPCosts-9ikh61Kv.js +1 -0
- package/ui/dist/assets/CPDashboard-sOok2T5v.js +1 -0
- package/ui/dist/assets/{CPFiles-BO73EZwJ.js → CPFiles-DB2nY5JE.js} +1 -1
- package/ui/dist/assets/CPGoals-8Z1yOY8e.js +1 -0
- package/ui/dist/assets/CPInbox-Cq6-UY8F.js +11 -0
- package/ui/dist/assets/CPIssueDetail-NAGfmJg8.js +1 -0
- package/ui/dist/assets/CPIssues-BzX6Rckx.js +1 -0
- package/ui/dist/assets/CPLayout-BcRM6QSg.js +2 -0
- package/ui/dist/assets/CPOrg-B7DQ4UQP.js +1 -0
- package/ui/dist/assets/CPRuns-D-cpPw_M.js +1 -0
- package/ui/dist/assets/{CPSocial-Qw5rKy_4.js → CPSocial-DshtmcK0.js} +3 -3
- package/ui/dist/assets/CPVoice-DfXRnQVU.js +1 -0
- package/ui/dist/assets/{ChannelsPanel-DS21E-Iz.js → ChannelsPanel-BnaTOeyf.js} +1 -1
- package/ui/dist/assets/CheckpointsPanel-C62naE4U.js +1 -0
- package/ui/dist/assets/CommandPostHub-B_L1CAss.js +24 -0
- package/ui/dist/assets/ConfirmDialog-VErHWAbo.js +1 -0
- package/ui/dist/assets/CronPanel-BwMrrZ5d.js +1 -0
- package/ui/dist/assets/{DataTable-PnhPeDBG.js → DataTable-BCqSUuN7.js} +1 -1
- package/ui/dist/assets/{DreamPanel-DIrtlk2K.js → DreamPanel-BNAcCLBB.js} +2 -2
- package/ui/dist/assets/EmptyState-D9kQf1PX.js +1 -0
- package/ui/dist/assets/{EvalHarnessPanel-uYb_ZEQG.js → EvalHarnessPanel-BaMLdBNm.js} +2 -2
- package/ui/dist/assets/EvalPanel-CW-SSjtg.js +1 -0
- package/ui/dist/assets/{FileViewer-CVO3TRs3.js → FileViewer-BL00nsd7.js} +1 -1
- package/ui/dist/assets/FilesPanel-CeC6YUSd.js +16 -0
- package/ui/dist/assets/FleetPanel-EyWF7l3W.js +1 -0
- package/ui/dist/assets/{HomelabPanel-BZvN4LPM.js → HomelabPanel-BRfKRYe7.js} +2 -2
- package/ui/dist/assets/InfraView-Jmqhg_Yc.js +2 -0
- package/ui/dist/assets/{InlineEditableField-mBzpbcLB.js → InlineEditableField-DgMrLDj1.js} +1 -1
- package/ui/dist/assets/Input-CBTwa_Iw.js +1 -0
- package/ui/dist/assets/IntegrationsPanel-DQL-7Ec6.js +1 -0
- package/ui/dist/assets/IntelligenceView-DxD78qfP.js +2 -0
- package/ui/dist/assets/LearningPanel-C_JzSbJU.js +1 -0
- package/ui/dist/assets/LiveStudio-Db5yeaWo.js +7 -0
- package/ui/dist/assets/{LogsPanel-DbP3Mwnr.js → LogsPanel-CpinKwaZ.js} +1 -1
- package/ui/dist/assets/McpPanel-D-MqN_f-.js +1 -0
- package/ui/dist/assets/MemoryGraphPanel-BnD5jRqf.js +1 -0
- package/ui/dist/assets/MemoryTaxonomyPanel-BBI202dd.js +6 -0
- package/ui/dist/assets/MemoryWikiPanel-Dn3XZHL0.js +6 -0
- package/ui/dist/assets/{MeshPanel-Bf-4brXL.js → MeshPanel-C-mRJpr0.js} +1 -1
- package/ui/dist/assets/{MissionCanvas-CJyhnauG.js → MissionCanvas-CbZW83Ch.js} +1 -1
- package/ui/dist/assets/{MissionChat-C2Nto3zM.js → MissionChat-Bs75jPAD.js} +1 -1
- package/ui/dist/assets/{MissionLibrary-RXyBHsLL.js → MissionLibrary-BxQ6SxPe.js} +1 -1
- package/ui/dist/assets/MissionStart-CBuBPasl.js +1 -0
- package/ui/dist/assets/Modal-ybPGvlQs.js +9 -0
- package/ui/dist/assets/{NvidiaPanel-4DlcQlyl.js → NvidiaPanel-DdG13OX4.js} +1 -1
- package/ui/dist/assets/OrganismPanel-xZWUJKyr.js +1 -0
- package/ui/dist/assets/OverviewPanel-B45ZYhJV.js +1 -0
- package/ui/dist/assets/{PageHeader-bnc85wQN.js → PageHeader-DdrbS1aq.js} +1 -1
- package/ui/dist/assets/PersonaProfilesPanel-CKER-EU5.js +8 -0
- package/ui/dist/assets/{PersonasPanel-dR8VppcD.js → PersonasPanel-CMMQ3nh3.js} +1 -1
- package/ui/dist/assets/{PhoneDeskPanel-CdVOY7H9.js → PhoneDeskPanel-Bw_Y-cVE.js} +2 -2
- package/ui/dist/assets/RecipesPanel-DzMcxpJJ.js +1 -0
- package/ui/dist/assets/SecurityPanel-BCq3Fzbr.js +1 -0
- package/ui/dist/assets/SelfImprovePanel-YE3hT8jK.js +1 -0
- package/ui/dist/assets/SelfProposalsPanel-DXuqBM6p.js +1 -0
- package/ui/dist/assets/SessionsPanel-DORz5goR.js +1 -0
- package/ui/dist/assets/SessionsTab-qYHDOuC8.js +1 -0
- package/ui/dist/assets/SettingsPanel-BbwPu1i7.js +1 -0
- package/ui/dist/assets/SettingsView-zgqkDDBJ.js +2 -0
- package/ui/dist/assets/{SkeletonLoader-Cax7YTqW.js → SkeletonLoader-r6OGXaU9.js} +1 -1
- package/ui/dist/assets/SkillsPanel-BjEOBMRo.js +11 -0
- package/ui/dist/assets/{SomaView-eG3wI4S1.js → SomaView-DLzApZVW.js} +2 -2
- package/ui/dist/assets/{StatCard-Djr487DV.js → StatCard-DLq8aBps.js} +1 -1
- package/ui/dist/assets/{StatusBadge-JpCoA33_.js → StatusBadge-BqlvIbdj.js} +1 -1
- package/ui/dist/assets/{Tabs-DJHu-roP.js → Tabs-DdUThlp1.js} +1 -1
- package/ui/dist/assets/TeamsPanel-uIIKoU7I.js +1 -0
- package/ui/dist/assets/{TelemetryPanel-D4PXsd-X.js → TelemetryPanel-dVr3yQQr.js} +1 -1
- package/ui/dist/assets/TitanCanvas-xHAJqwG2.js +945 -0
- package/ui/dist/assets/ToolsView-CG1mZdiy.js +2 -0
- package/ui/dist/assets/{Tooltip-B1LhTXJ8.js → Tooltip-C2tXJcrN.js} +1 -1
- package/ui/dist/assets/TraceViewer-BIMD_Osr.js +1 -0
- package/ui/dist/assets/TracesPanel-nMUiyMj5.js +1 -0
- package/ui/dist/assets/TrainingPanel-CT5R4HWm.js +1 -0
- package/ui/dist/assets/{VoiceOverlay-B_ss7Zg_.js → VoiceOverlay-Br4QnCtw.js} +3 -3
- package/ui/dist/assets/VramPanel-CdnJYytg.js +1 -0
- package/ui/dist/assets/WatchView-TNU6Ns1Q.js +13 -0
- package/ui/dist/assets/WorkTab-wTlX_UKP.js +1 -0
- package/ui/dist/assets/WorkflowBuilderPanel-CDpVt5ux.js +6 -0
- package/ui/dist/assets/WorkflowsPanel-zsFqsLdn.js +11 -0
- package/ui/dist/assets/{archive-gZFnGd5A.js → archive-Bh689DNg.js} +1 -1
- package/ui/dist/assets/{arrow-left-qA0Qer2h.js → arrow-left-WkVYLm80.js} +1 -1
- package/ui/dist/assets/{book-open-DIxdPqmD.js → book-open-ohEXgUsS.js} +1 -1
- package/ui/dist/assets/{bot-CvIF1uHi.js → bot-DvEcyQcD.js} +1 -1
- package/ui/dist/assets/{chart-column-BQiM-Td4.js → chart-column-w3goFd5f.js} +1 -1
- package/ui/dist/assets/{check-DgyDEFtq.js → check-CuRYh4Zh.js} +1 -1
- package/ui/dist/assets/{chevron-right-CQ1NTOtd.js → chevron-right-DbLSHmff.js} +1 -1
- package/ui/dist/assets/{circle-check-big-CAFcaPPH.js → circle-check-big-Bkba568b.js} +1 -1
- package/ui/dist/assets/{circle-stop-C-8xGv0n.js → circle-stop-Bx2ohEg8.js} +1 -1
- package/ui/dist/assets/{clipboard-list-9DdqBj1F.js → clipboard-list-Dj9tORnu.js} +1 -1
- package/ui/dist/assets/{clock-CF9BCIpL.js → clock-JyQAYy6X.js} +1 -1
- package/ui/dist/assets/{dollar-sign-LDRZBae6.js → dollar-sign-XxwPAA2a.js} +1 -1
- package/ui/dist/assets/{download-BBNXvBO0.js → download-D1izVEOL.js} +1 -1
- package/ui/dist/assets/{external-link-D_ji4Bec.js → external-link-DZ_rZsIt.js} +1 -1
- package/ui/dist/assets/{file-text-DrdTDEYp.js → file-text-Cfawu8Bs.js} +1 -1
- package/ui/dist/assets/{flask-conical-BGn5PgFX.js → flask-conical-Ql8QxhgY.js} +1 -1
- package/ui/dist/assets/{folder-BeZZUGnK.js → folder-DAdIw-Pb.js} +1 -1
- package/ui/dist/assets/{funnel-CAJgGO5M.js → funnel-FycfZcXo.js} +1 -1
- package/ui/dist/assets/{git-branch-BcXabeOs.js → git-branch-C2qrhGGu.js} +1 -1
- package/ui/dist/assets/index-Cml2x9pA.js +507 -0
- package/ui/dist/assets/index-yWybhcfI.css +1 -0
- package/ui/dist/assets/{layers-DxYDmPA_.js → layers-yzjtGlHB.js} +1 -1
- package/ui/dist/assets/{legacy-dHWI7k8P.js → legacy-D21WSMF1.js} +1 -1
- package/ui/dist/assets/{lightbulb-B0Du4SM4.js → lightbulb-BZJNK69S.js} +1 -1
- package/ui/dist/assets/{link-CUpaumqr.js → link-CnFkBkaY.js} +1 -1
- package/ui/dist/assets/{list-todo-CDDhmPQB.js → list-todo-BlgfQHup.js} +1 -1
- package/ui/dist/assets/{message-square-D5VWlv-Q.js → message-square-CRsG9u6_.js} +1 -1
- package/ui/dist/assets/{mic-Ddcc6Ann.js → mic-B32RHc7Y.js} +1 -1
- package/ui/dist/assets/{missions-2zox16Tc.js → missions-1iw8Z2_0.js} +1 -1
- package/ui/dist/assets/{network-DaJ7ugwX.js → network-C9RXQGrV.js} +1 -1
- package/ui/dist/assets/{pause-BukaK6rs.js → pause-BT1Bc2q3.js} +1 -1
- package/ui/dist/assets/{pencil-D_YwQBeg.js → pencil-BK5IU6o0.js} +1 -1
- package/ui/dist/assets/{play-BjdwtYMk.js → play-Cl1nC_gc.js} +1 -1
- package/ui/dist/assets/{plug-yISDdeW2.js → plug-DvcpOalj.js} +1 -1
- package/ui/dist/assets/{plus-BSjTdepW.js → plus-Dpo1qfrl.js} +1 -1
- package/ui/dist/assets/{radio-B7kX_yWE.js → radio-C5c9IyqX.js} +1 -1
- package/ui/dist/assets/{refresh-cw-CwDpzXUn.js → refresh-cw-C-iZkzuS.js} +1 -1
- package/ui/dist/assets/{rotate-ccw-7SQDTI0_.js → rotate-ccw-qzrB3SNw.js} +1 -1
- package/ui/dist/assets/{save-CjTPAQM0.js → save-DwR9wQVu.js} +1 -1
- package/ui/dist/assets/{search-BP7VlNxX.js → search-D10l0m3-.js} +1 -1
- package/ui/dist/assets/{send-C2XDuRPf.js → send-DtXGsaFW.js} +1 -1
- package/ui/dist/assets/{server-BE8W-AT4.js → server-BzisF3LL.js} +1 -1
- package/ui/dist/assets/settings-Dbwd1_-c.js +6 -0
- package/ui/dist/assets/{shield-check-s7la2J2K.js → shield-check-CXlDJyAW.js} +1 -1
- package/ui/dist/assets/square-BBC-JKzY.js +11 -0
- package/ui/dist/assets/{terminal-B8IK4WsO.js → terminal-DaBIlWEM.js} +1 -1
- package/ui/dist/assets/{test-tube-Xfn9DJeg.js → test-tube-CDATRD5t.js} +1 -1
- package/ui/dist/assets/{toggle-right-CHpzOIlj.js → toggle-right-DTmrC5RD.js} +1 -1
- package/ui/dist/assets/{trash-2-B1C85ePK.js → trash-2-CTeyjxD_.js} +1 -1
- package/ui/dist/assets/{trending-up-DDGHQZY1.js → trending-up-CXPRjRV4.js} +1 -1
- package/ui/dist/assets/{trophy-D0LhJSPA.js → trophy-DbVdXRtU.js} +1 -1
- package/ui/dist/assets/{volume-2-DMaE91b5.js → volume-2-DYDBmm3M.js} +1 -1
- package/ui/dist/assets/{wifi-off-DR9h8HGA.js → wifi-off-BBuIGbiP.js} +1 -1
- package/ui/dist/assets/zoom-out-D47_pRAO.js +16 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/sw.js +1 -1
- package/ui/dist/assets/AuditPanel-BaftX5MP.js +0 -1
- package/ui/dist/assets/BackupPanel-DAy9G7Wt.js +0 -1
- package/ui/dist/assets/CPActivity-BYDsUoMn.js +0 -1
- package/ui/dist/assets/CPAgentDetail-Bb9-GAJY.js +0 -1
- package/ui/dist/assets/CPAgents-BTZuGnki.js +0 -1
- package/ui/dist/assets/CPApprovals-BME2ARkO.js +0 -1
- package/ui/dist/assets/CPCosts-mOXwWq0i.js +0 -1
- package/ui/dist/assets/CPDashboard-CTlKGXXQ.js +0 -1
- package/ui/dist/assets/CPGoals-BNWhNP14.js +0 -1
- package/ui/dist/assets/CPInbox-ybe4r8LW.js +0 -16
- package/ui/dist/assets/CPIssueDetail-DaMMGbjw.js +0 -1
- package/ui/dist/assets/CPIssues-BgpQOISw.js +0 -1
- package/ui/dist/assets/CPLayout-bgErauTx.js +0 -2
- package/ui/dist/assets/CPOrg-C8l5SIWJ.js +0 -8
- package/ui/dist/assets/CPRuns-DB8S7loF.js +0 -1
- package/ui/dist/assets/CPVoice-DfwHPewA.js +0 -1
- package/ui/dist/assets/CheckpointsPanel-9-l_8GdG.js +0 -1
- package/ui/dist/assets/CommandPostHub-z55Yrhj1.js +0 -24
- package/ui/dist/assets/CronPanel-kEZK3gpx.js +0 -1
- package/ui/dist/assets/EmptyState-CfvU7SdB.js +0 -1
- package/ui/dist/assets/EvalPanel-CDG-njyj.js +0 -1
- package/ui/dist/assets/FilesPanel-CaLPog2e.js +0 -16
- package/ui/dist/assets/FleetPanel-BtlaV6pH.js +0 -1
- package/ui/dist/assets/InfraView-C0zEuFrR.js +0 -2
- package/ui/dist/assets/Input-CbrMbLgn.js +0 -1
- package/ui/dist/assets/IntegrationsPanel-B4TyR6jC.js +0 -1
- package/ui/dist/assets/IntelligenceView-DZ4HxYZ3.js +0 -2
- package/ui/dist/assets/LearningPanel-B4RIm_iQ.js +0 -1
- package/ui/dist/assets/McpPanel-BmNUFozc.js +0 -1
- package/ui/dist/assets/MemoryGraphPanel-JPurHV0L.js +0 -16
- package/ui/dist/assets/MemoryWikiPanel-DdvCAZHa.js +0 -6
- package/ui/dist/assets/MissionStart-wUkcEP0T.js +0 -1
- package/ui/dist/assets/Modal-BmS7C6FN.js +0 -1
- package/ui/dist/assets/OrganismPanel-C2LYDPrn.js +0 -1
- package/ui/dist/assets/OverviewPanel-DK8uuq4D.js +0 -1
- package/ui/dist/assets/PersonaProfilesPanel-DGtokXUu.js +0 -8
- package/ui/dist/assets/RecipesPanel-D3Zs2wxr.js +0 -1
- package/ui/dist/assets/SecurityPanel-BMERf796.js +0 -1
- package/ui/dist/assets/SelfImprovePanel-BxqWHXCU.js +0 -1
- package/ui/dist/assets/SelfProposalsPanel-CuC94vdx.js +0 -2
- package/ui/dist/assets/SessionsPanel-CQ8qvzp7.js +0 -1
- package/ui/dist/assets/SessionsTab-B3eHV3jf.js +0 -1
- package/ui/dist/assets/SettingsPanel-Cumls7N2.js +0 -1
- package/ui/dist/assets/SettingsView-BtA67pol.js +0 -2
- package/ui/dist/assets/SkillsPanel-CA415CT8.js +0 -11
- package/ui/dist/assets/TeamsPanel-C_Vu6vnY.js +0 -1
- package/ui/dist/assets/TitanCanvas-TuYZSZO7.js +0 -1117
- package/ui/dist/assets/ToolsView-BvTN6vFn.js +0 -2
- package/ui/dist/assets/TraceViewer-Bh8Jo3Dr.js +0 -1
- package/ui/dist/assets/TrainingPanel-Dmbd1rJ-.js +0 -1
- package/ui/dist/assets/VramPanel-CPICbZ2s.js +0 -1
- package/ui/dist/assets/WatchView-BCgLVfiV.js +0 -13
- package/ui/dist/assets/WorkTab-iptofXO9.js +0 -1
- package/ui/dist/assets/WorkflowsPanel-3RYkFHyf.js +0 -11
- package/ui/dist/assets/chevron-up-UyfdjRp6.js +0 -6
- package/ui/dist/assets/index-CUgepw5Q.js +0 -337
- package/ui/dist/assets/index-Dm6zcSTS.css +0 -1
- package/ui/dist/assets/proxy-CWET5FFX.js +0 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/gateway/routes/watchRouter.ts"],"sourcesContent":["/**\n * Watch Router\n *\n * Extracted from gateway/server.ts.\n * Consolidates all /api/watch/* routes.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport { join } from 'path';\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/gateway/routes/watchRouter.ts"],"sourcesContent":["/**\n * Watch Router\n *\n * Extracted from gateway/server.ts.\n * Consolidates all /api/watch/* routes.\n */\n\nimport { Router, type Request, type Response } from 'express';\nimport { join } from 'path';\nimport fs from 'fs';\nimport { TITAN_HOME } from '../../utils/constants.js';\nimport logger from '../../utils/logger.js';\nimport { setupSSEFlush } from '../../utils/sseFlush.js';\n\n// Daemon events (for SSE)\nimport { titanEvents } from '../../agent/daemon.js';\n\nconst COMPONENT = 'WatchRouter';\n\n// ── Module-level constants (avoid per-request allocation) ──────────\nconst PANE_SSE_TOPICS = [\n // Soma / drives\n 'drive:tick', 'hormone:update', 'pressure:threshold', 'soma:proposal',\n // Turns / tools\n 'turn:pre', 'turn:post', 'tool:call', 'tool:result',\n // Goals\n 'goal:create', 'goal:complete', 'goal:fail', 'goal:cancel', 'goal:update',\n // Command Post\n 'cp:activity', 'cp:proposal', 'cp:approval', 'cp:rejection',\n // Health\n 'health:up', 'health:down', 'health:degraded',\n // Multi-agent\n 'agent:spawn', 'agent:kill', 'agent:message',\n // Alerts\n 'alert:warning', 'alert:critical',\n];\n\nexport function createWatchRouter(): Router {\n const router = Router();\n\n // ── Watch stream — unified human-readable event firehose (v4.5.0)\n // Fuses every meaningful event across TITAN into a single SSE feed\n // with plain-English captions. Used by the /watch Pane UI.\n router.get('/watch/stream', async (req: Request, res: Response) => {\n const { humanize } = await import('../../watch/humanize.js');\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n 'X-Accel-Buffering': 'no',\n });\n const sseWrite = setupSSEFlush(res);\n\n // Every event topic the Pane cares about — union of drive ticks,\n // soma proposals, tool calls, goals, initiative, command-post, health,\n // multi-agent, alerts. Matches src/watch/humanize.ts dictionary.\n const topics = PANE_SSE_TOPICS;\n\n const send = (data: unknown) => {\n try { sseWrite(`data: ${JSON.stringify(data)}\\n\\n`); } catch { /* client gone */ }\n };\n\n // Initial snapshot — read drive state + recent goals so the UI has\n // something to render before the first live event arrives.\n try {\n // Soma-audit fix: respect TITAN_HOME — the old hardcoded ~/.titan made a\n // staging instance silently read PROD's drive data (cross-env leak).\n const driveStatePath = join(TITAN_HOME, 'drive-state.json');\n if (fs.existsSync(driveStatePath)) {\n const raw = JSON.parse(fs.readFileSync(driveStatePath, 'utf-8'));\n const latest = raw.latest as { timestamp?: string; drives?: unknown[]; totalPressure?: number; dominantDrives?: string[] } | undefined;\n if (latest) {\n send({\n type: 'snapshot',\n drives: latest.drives || [],\n totalPressure: latest.totalPressure || 0,\n dominantDrives: latest.dominantDrives || [],\n timestamp: latest.timestamp ? new Date(latest.timestamp).getTime() : Date.now(),\n });\n }\n }\n } catch { /* snapshot best-effort */ }\n\n // Wire live event listeners\n const listeners = new Map<string, (data: unknown) => void>();\n for (const topic of topics) {\n const handler = (payload: unknown) => {\n const event = humanize(topic, (payload as Record<string, unknown>) || {});\n if (event) send({ type: \"event\", ...event });\n };\n listeners.set(topic, handler);\n titanEvents.on(topic, handler);\n }\n\n const keepalive = setInterval(() => {\n try { sseWrite(': keepalive\\n\\n'); } catch { /* gone */ }\n }, 15_000);\n\n req.on('close', () => {\n clearInterval(keepalive);\n for (const [topic, handler] of listeners) {\n titanEvents.removeListener(topic, handler);\n }\n });\n });\n\n // Snapshot endpoint — returns current drive state + active goal +\n // last N events from a small ring buffer we maintain in-process.\n // Used by the Pane on first load to populate zones without waiting\n // for the next tick.\n router.get('/watch/snapshot', (_req: Request, res: Response) => {\n try {\n const driveStatePath = join(TITAN_HOME, 'drive-state.json');\n const goalsPath = join(TITAN_HOME, 'goals.json');\n const driveState = fs.existsSync(driveStatePath)\n ? JSON.parse(fs.readFileSync(driveStatePath, 'utf-8'))?.latest\n : null;\n const goalsRaw = fs.existsSync(goalsPath)\n ? JSON.parse(fs.readFileSync(goalsPath, 'utf-8'))\n : {};\n const allGoals = Array.isArray(goalsRaw) ? goalsRaw : Object.values(goalsRaw);\n const activeGoals = (allGoals as Array<Record<string, unknown>>).filter(g => g.status === 'active');\n res.json({\n drives: driveState?.drives || [],\n totalPressure: driveState?.totalPressure || 0,\n dominantDrives: driveState?.dominantDrives || [],\n activeGoals: activeGoals.slice(0, 5).map(g => ({\n id: g.id,\n title: g.title,\n progress: g.progress || 0,\n createdAt: g.createdAt,\n })),\n timestamp: Date.now(),\n });\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 return router;\n}\n"],"mappings":"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","names":[]}
|
package/dist/gateway/server.js
CHANGED
|
@@ -52,7 +52,7 @@ import { initSlashCommands, handleSlashCommand } from "./slashCommands.js";
|
|
|
52
52
|
import { initMcpServers } from "../mcp/registry.js";
|
|
53
53
|
import { mountMcpHttpEndpoints } from "../mcp/server.js";
|
|
54
54
|
import { initMonitors, setMonitorTriggerHandler, listMonitors, addMonitor, removeMonitor, getMonitorEvents } from "../agent/monitor.js";
|
|
55
|
-
import { seedBuiltinRecipes } from "../recipes/store.js";
|
|
55
|
+
import { seedBuiltinRecipes, findBySlashCommand } from "../recipes/store.js";
|
|
56
56
|
import { parseSlashCommand, runRecipe } from "../recipes/runner.js";
|
|
57
57
|
import { getCostStatus } from "../agent/costOptimizer.js";
|
|
58
58
|
import { initLearning, getLearningStats } from "../memory/learning.js";
|
|
@@ -90,6 +90,7 @@ import { createTelephonyRouter } from "./routes/telephony.js";
|
|
|
90
90
|
import { createUpdateRouter } from "./routes/update.js";
|
|
91
91
|
import { createSocialRouter } from "./routes/socialRouter.js";
|
|
92
92
|
import { createWatchRouter } from "./routes/watchRouter.js";
|
|
93
|
+
import { createStudioRouter } from "./routes/studioRouter.js";
|
|
93
94
|
import { setupSSEFlush } from "../utils/sseFlush.js";
|
|
94
95
|
import { createLifecycleRouter } from "./routes/agents.js";
|
|
95
96
|
import { getLifecycleManager } from "../utils/lifecycle.js";
|
|
@@ -580,10 +581,21 @@ async function handleInboundMessage(msg) {
|
|
|
580
581
|
}
|
|
581
582
|
try {
|
|
582
583
|
let fullResponse = "";
|
|
584
|
+
const slashRecipe = findBySlashCommand(command);
|
|
585
|
+
if (slashRecipe && args) {
|
|
586
|
+
for (const key of Object.keys(slashRecipe.parameters || {})) params[key] = args;
|
|
587
|
+
}
|
|
588
|
+
const runStart = Date.now();
|
|
589
|
+
let runTokens = 0;
|
|
583
590
|
for await (const step of runRecipe(command, params)) {
|
|
584
591
|
const r = await processMessage(step.prompt, msg.channel, msg.userId);
|
|
592
|
+
runTokens += r.tokenUsage?.total || 0;
|
|
585
593
|
fullResponse += (fullResponse ? "\n\n" : "") + r.content;
|
|
586
594
|
}
|
|
595
|
+
if (slashRecipe?.author === "muscle-memory") {
|
|
596
|
+
const { recordAdoptedRun } = await import("../agent/muscleMemory.js");
|
|
597
|
+
recordAdoptedRun(slashRecipe.id, Date.now() - runStart, runTokens);
|
|
598
|
+
}
|
|
587
599
|
await safeSend(msg.channel, { channel: msg.channel, userId: msg.userId, groupId: msg.groupId, content: fullResponse, replyTo: msg.id });
|
|
588
600
|
broadcast({ type: "message", direction: "outbound", channel: msg.channel, userId: msg.userId, content: fullResponse, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
589
601
|
return;
|
|
@@ -669,28 +681,16 @@ async function startGateway(options) {
|
|
|
669
681
|
const { hasUsableProvider } = await import("../config/config.js");
|
|
670
682
|
const usable = await hasUsableProvider();
|
|
671
683
|
if (!usable.ok) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
console.
|
|
676
|
-
console.
|
|
677
|
-
console.
|
|
678
|
-
console.
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
console.error(' \x1B[36mexport ANTHROPIC_API_KEY="sk-ant-..."\x1B[0m');
|
|
682
|
-
console.error(' \x1B[36mexport OPENAI_API_KEY="sk-..."\x1B[0m');
|
|
683
|
-
console.error(' \x1B[36mexport OLLAMA_BASE_URL="http://localhost:11434"\x1B[0m');
|
|
684
|
-
console.error("");
|
|
685
|
-
console.error(" Or check what went wrong:");
|
|
686
|
-
console.error(" \x1B[36mtitan doctor\x1B[0m");
|
|
687
|
-
console.error("");
|
|
688
|
-
console.error(" To skip this check (advanced):");
|
|
689
|
-
console.error(" \x1B[36mtitan gateway --skip-usable-check\x1B[0m");
|
|
690
|
-
console.error("");
|
|
691
|
-
process.exit(1);
|
|
684
|
+
const { setProviderReady } = await import("./onboarding.js");
|
|
685
|
+
setProviderReady(false);
|
|
686
|
+
logger.warn(COMPONENT, `No usable provider yet (${usable.details}) \u2014 starting in WELCOME MODE. Open the dashboard to finish setup.`);
|
|
687
|
+
console.log("");
|
|
688
|
+
console.log("\x1B[36m\x1B[1m\u{1F44B} Welcome to TITAN!\x1B[0m No AI model is connected yet.");
|
|
689
|
+
console.log(" Opening the dashboard will walk you through it in under a minute.");
|
|
690
|
+
console.log("");
|
|
691
|
+
} else {
|
|
692
|
+
logger.info(COMPONENT, `Provider check passed: ${usable.details}`);
|
|
692
693
|
}
|
|
693
|
-
logger.info(COMPONENT, `Provider check passed: ${usable.details}`);
|
|
694
694
|
}
|
|
695
695
|
if (config.autonomy?.mode === "autonomous") {
|
|
696
696
|
logger.warn(COMPONENT, '\u26A0\uFE0F AUTONOMY MODE IS "autonomous" \u2014 all tools run without approval. Safe for personal use, DANGEROUS for multi-user deployments.');
|
|
@@ -750,6 +750,16 @@ async function startGateway(options) {
|
|
|
750
750
|
} catch (err) {
|
|
751
751
|
logger.warn(COMPONENT, `somaInitiative failed to start: ${err.message}`);
|
|
752
752
|
}
|
|
753
|
+
try {
|
|
754
|
+
const { registerHeartbeat } = await import("../agent/heartbeat.js");
|
|
755
|
+
registerHeartbeat();
|
|
756
|
+
const { registerReminderWatcher } = await import("../agent/reminders.js");
|
|
757
|
+
registerReminderWatcher();
|
|
758
|
+
const { registerMuscleWatcher } = await import("../agent/muscleMemory.js");
|
|
759
|
+
registerMuscleWatcher();
|
|
760
|
+
} catch (err) {
|
|
761
|
+
logger.warn(COMPONENT, `heartbeat failed to register: ${err.message}`);
|
|
762
|
+
}
|
|
753
763
|
const defaultRateLimitWindowMs = options?.rateLimitWindowMs ?? 6e4;
|
|
754
764
|
const defaultRateLimitMax = options?.rateLimitMax ?? 30;
|
|
755
765
|
const rateLimitStore = /* @__PURE__ */ new Map();
|
|
@@ -1142,6 +1152,35 @@ async function startGateway(options) {
|
|
|
1142
1152
|
res.status(500).json({ error: "tool_run_failed", message: err.message });
|
|
1143
1153
|
}
|
|
1144
1154
|
});
|
|
1155
|
+
app.get("/api/memory/taxonomy", async (_req, res) => {
|
|
1156
|
+
const { summarizeMemoryTaxonomy } = await import("../memory/taxonomy.js");
|
|
1157
|
+
const cfg = loadConfig();
|
|
1158
|
+
let hindsightConnected = false;
|
|
1159
|
+
try {
|
|
1160
|
+
const { memory } = await import("../memory/facade.js");
|
|
1161
|
+
hindsightConnected = Boolean(await memory.episodic.isCrossSessionConnected());
|
|
1162
|
+
} catch {
|
|
1163
|
+
}
|
|
1164
|
+
res.json(summarizeMemoryTaxonomy(cfg, { hindsightConnected }));
|
|
1165
|
+
});
|
|
1166
|
+
app.get("/api/memory/about-me", async (req, res) => {
|
|
1167
|
+
try {
|
|
1168
|
+
const userId = getUserIdFromReq(req);
|
|
1169
|
+
const cfg = loadConfig();
|
|
1170
|
+
const { readSomaProfile } = await import("../storage/somaProfile.js");
|
|
1171
|
+
const profile = readSomaProfile(userId);
|
|
1172
|
+
const { searchMemories } = await import("../memory/memory.js");
|
|
1173
|
+
const facts = (await searchMemories()).slice(0, 100);
|
|
1174
|
+
res.json({
|
|
1175
|
+
identity: cfg.soul || null,
|
|
1176
|
+
observations: profile.learnedAboutUser ?? [],
|
|
1177
|
+
workingHours: profile.workingHours ?? null,
|
|
1178
|
+
facts
|
|
1179
|
+
});
|
|
1180
|
+
} catch (err) {
|
|
1181
|
+
res.status(500).json({ error: "about_me_failed", message: err.message });
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1145
1184
|
app.get("/api/memory/:key", async (req, res) => {
|
|
1146
1185
|
try {
|
|
1147
1186
|
const { recallFact } = await import("../memory/memory.js");
|
|
@@ -1358,6 +1397,63 @@ async function startGateway(options) {
|
|
|
1358
1397
|
res.status(500).json({ error: "advisories_unavailable", message: err.message });
|
|
1359
1398
|
}
|
|
1360
1399
|
});
|
|
1400
|
+
app.post("/api/soma/setpoints", async (req, res) => {
|
|
1401
|
+
try {
|
|
1402
|
+
const body = req.body ?? {};
|
|
1403
|
+
const overrides = {};
|
|
1404
|
+
for (const [k, v] of Object.entries(body)) {
|
|
1405
|
+
const n = Number(v);
|
|
1406
|
+
if (Number.isFinite(n) && n >= 0 && n <= 1) overrides[k] = n;
|
|
1407
|
+
}
|
|
1408
|
+
if (Object.keys(overrides).length === 0) {
|
|
1409
|
+
res.status(400).json({ error: "no_valid_setpoints", message: "Provide { driveId: 0..1 }." });
|
|
1410
|
+
return;
|
|
1411
|
+
}
|
|
1412
|
+
const cfg = loadConfig();
|
|
1413
|
+
const organism = { ...cfg.organism, driveSetpoints: { ...cfg.organism.driveSetpoints ?? {}, ...overrides } };
|
|
1414
|
+
updateConfig({ organism });
|
|
1415
|
+
res.json({ ok: true, driveSetpoints: organism.driveSetpoints });
|
|
1416
|
+
} catch (err) {
|
|
1417
|
+
res.status(500).json({ error: "setpoints_failed", message: err.message });
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1420
|
+
app.post("/api/soma/weights", async (req, res) => {
|
|
1421
|
+
try {
|
|
1422
|
+
const body = req.body ?? {};
|
|
1423
|
+
const overrides = {};
|
|
1424
|
+
for (const [k, v] of Object.entries(body)) {
|
|
1425
|
+
const n = Number(v);
|
|
1426
|
+
if (Number.isFinite(n) && n >= 0.1 && n <= 3) overrides[k] = n;
|
|
1427
|
+
}
|
|
1428
|
+
if (Object.keys(overrides).length === 0) {
|
|
1429
|
+
res.status(400).json({ error: "no_valid_weights", message: "Provide { driveId: 0.1..3.0 }." });
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
const cfg = loadConfig();
|
|
1433
|
+
const organism = { ...cfg.organism, driveWeights: { ...cfg.organism.driveWeights ?? {}, ...overrides } };
|
|
1434
|
+
updateConfig({ organism });
|
|
1435
|
+
res.json({ ok: true, driveWeights: organism.driveWeights });
|
|
1436
|
+
} catch (err) {
|
|
1437
|
+
res.status(500).json({ error: "weights_failed", message: err.message });
|
|
1438
|
+
}
|
|
1439
|
+
});
|
|
1440
|
+
app.get("/api/heartbeat/latest", async (_req, res) => {
|
|
1441
|
+
try {
|
|
1442
|
+
const { latestHeartbeat } = await import("../agent/heartbeat.js");
|
|
1443
|
+
res.json({ note: latestHeartbeat() });
|
|
1444
|
+
} catch (err) {
|
|
1445
|
+
res.status(500).json({ error: "heartbeat_failed", message: err.message });
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
app.post("/api/heartbeat/beat", async (_req, res) => {
|
|
1449
|
+
try {
|
|
1450
|
+
const { runHeartbeat } = await import("../agent/heartbeat.js");
|
|
1451
|
+
const note = await runHeartbeat();
|
|
1452
|
+
res.json({ ok: true, spoke: !!note, note });
|
|
1453
|
+
} catch (err) {
|
|
1454
|
+
res.status(500).json({ error: "heartbeat_failed", message: err.message });
|
|
1455
|
+
}
|
|
1456
|
+
});
|
|
1361
1457
|
app.get("/api/time-travel/checkpoints", async (req, res) => {
|
|
1362
1458
|
try {
|
|
1363
1459
|
const { listAllCheckpoints, listCheckpoints } = await import("../agent/shadowGit.js");
|
|
@@ -1413,13 +1509,14 @@ async function startGateway(options) {
|
|
|
1413
1509
|
try {
|
|
1414
1510
|
const { spawnSubAgent } = await import("../agent/subAgent.js");
|
|
1415
1511
|
const decomposePrompt = [
|
|
1416
|
-
`Decompose this autonomous mission into 3-6 concrete
|
|
1512
|
+
`Decompose this autonomous mission into 3-6 concrete subtasks.`,
|
|
1417
1513
|
``,
|
|
1418
1514
|
`Mission: ${description}`,
|
|
1419
1515
|
``,
|
|
1420
|
-
`Return STRICT JSON: { "subtasks": [ { "title": "...", "description": "..." }, ... ] }.`,
|
|
1516
|
+
`Return STRICT JSON: { "subtasks": [ { "title": "...", "description": "...", "dependsOn": [<1-based positions of prerequisite subtasks>] }, ... ] }.`,
|
|
1517
|
+
`Use dependsOn to express real ordering: if a subtask needs an earlier subtask's output, list that earlier subtask's 1-based position. Independent subtasks use [].`,
|
|
1518
|
+
`Example: if subtask 3 needs subtasks 1 and 2 done first -> "dependsOn": [1, 2]. Only reference EARLIER positions; never a later one or itself.`,
|
|
1421
1519
|
`Each title <= 60 chars, each description <= 200 chars.`,
|
|
1422
|
-
`Order subtasks dependency-aware (later ones may reference earlier output).`,
|
|
1423
1520
|
`Do NOT add a verification subtask \u2014 the driver verifies automatically.`,
|
|
1424
1521
|
`Do NOT wrap in markdown \u2014 pure JSON.`
|
|
1425
1522
|
].join("\n");
|
|
@@ -1429,15 +1526,8 @@ async function startGateway(options) {
|
|
|
1429
1526
|
tier: "fast",
|
|
1430
1527
|
maxRounds: 1
|
|
1431
1528
|
});
|
|
1432
|
-
const
|
|
1433
|
-
|
|
1434
|
-
const jsonEnd = raw.lastIndexOf("}");
|
|
1435
|
-
if (jsonStart >= 0 && jsonEnd > jsonStart) {
|
|
1436
|
-
const parsed = JSON.parse(raw.slice(jsonStart, jsonEnd + 1));
|
|
1437
|
-
if (Array.isArray(parsed.subtasks) && parsed.subtasks.length >= 1) {
|
|
1438
|
-
subtasks = parsed.subtasks.filter((s) => typeof s?.title === "string" && typeof s?.description === "string").slice(0, 6).map((s) => ({ title: String(s.title).slice(0, 80), description: String(s.description).slice(0, 280) }));
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1529
|
+
const { parseMissionSubtasks } = await import("../agent/missionDecompose.js");
|
|
1530
|
+
subtasks = parseMissionSubtasks(result.content || "");
|
|
1441
1531
|
} catch (err) {
|
|
1442
1532
|
logger.warn(COMPONENT, `Mission decomposition failed, creating goal with no subtasks: ${err.message}`);
|
|
1443
1533
|
}
|
|
@@ -1677,6 +1767,25 @@ async function startGateway(options) {
|
|
|
1677
1767
|
res.status(500).json({ error: "gift_unavailable", message: err.message });
|
|
1678
1768
|
}
|
|
1679
1769
|
});
|
|
1770
|
+
app.get("/api/security/audit", async (_req, res) => {
|
|
1771
|
+
const { auditConfig } = await import("../skills/builtin/config_audit.js");
|
|
1772
|
+
const cfg = loadConfig();
|
|
1773
|
+
res.json({ findings: auditConfig(cfg) });
|
|
1774
|
+
});
|
|
1775
|
+
app.get("/api/traces", async (req, res) => {
|
|
1776
|
+
const { listSpans } = await import("../telemetry/traceStore.js");
|
|
1777
|
+
const limit = req.query.limit ? parseInt(req.query.limit, 10) : 100;
|
|
1778
|
+
const sessionId = req.query.sessionId;
|
|
1779
|
+
res.json({ spans: listSpans({ limit, sessionId }) });
|
|
1780
|
+
});
|
|
1781
|
+
app.get("/api/traces/summary", async (_req, res) => {
|
|
1782
|
+
const { listSpans, summarizeTraces } = await import("../telemetry/traceStore.js");
|
|
1783
|
+
res.json(summarizeTraces(listSpans()));
|
|
1784
|
+
});
|
|
1785
|
+
app.get("/api/traces/export", async (_req, res) => {
|
|
1786
|
+
const { listSpans, toOTel } = await import("../telemetry/traceStore.js");
|
|
1787
|
+
res.json(toOTel(listSpans({ limit: 1e3 })));
|
|
1788
|
+
});
|
|
1680
1789
|
app.get("/api/stats", async (_req, res) => {
|
|
1681
1790
|
const usage = getUsageStats();
|
|
1682
1791
|
const cfg = loadConfig();
|
|
@@ -2173,6 +2282,33 @@ data: ${JSON.stringify({ message: "verification stream unavailable" })}
|
|
|
2173
2282
|
app.use("/api", createMetricsRouter());
|
|
2174
2283
|
app.use("/api", createMcpRouter());
|
|
2175
2284
|
app.use("/api", createAgentsRouter());
|
|
2285
|
+
app.get("/api/muscle", async (_req, res) => {
|
|
2286
|
+
const { listSkills, muscleStats } = await import("../agent/muscleMemory.js");
|
|
2287
|
+
res.json({ stats: muscleStats(), skills: listSkills() });
|
|
2288
|
+
});
|
|
2289
|
+
app.post("/api/muscle/scan", rateLimit(6e4, 2), async (_req, res) => {
|
|
2290
|
+
const { runMuscleScan } = await import("../agent/muscleMemory.js");
|
|
2291
|
+
res.json(await runMuscleScan(true));
|
|
2292
|
+
});
|
|
2293
|
+
app.post("/api/muscle/:id/adopt", rateLimit(6e4, 10), async (req, res) => {
|
|
2294
|
+
const { adoptSkill } = await import("../agent/muscleMemory.js");
|
|
2295
|
+
const result = adoptSkill(req.params.id);
|
|
2296
|
+
res.status("error" in result ? 400 : 200).json(result);
|
|
2297
|
+
});
|
|
2298
|
+
app.post("/api/muscle/:id/dismiss", rateLimit(6e4, 10), async (req, res) => {
|
|
2299
|
+
const { dismissSkill } = await import("../agent/muscleMemory.js");
|
|
2300
|
+
const ok = dismissSkill(req.params.id, req.body?.reason);
|
|
2301
|
+
res.status(ok ? 200 : 400).json({ ok });
|
|
2302
|
+
});
|
|
2303
|
+
app.get("/api/onboarding/state", async (_req, res) => {
|
|
2304
|
+
const { getOnboardingState } = await import("./onboarding.js");
|
|
2305
|
+
res.json(await getOnboardingState());
|
|
2306
|
+
});
|
|
2307
|
+
app.post("/api/onboarding/configure", async (req, res) => {
|
|
2308
|
+
const { applyOnboardingConfig } = await import("./onboarding.js");
|
|
2309
|
+
const result = await applyOnboardingConfig(req.body || {});
|
|
2310
|
+
res.status(result.ok ? 200 : 400).json(result);
|
|
2311
|
+
});
|
|
2176
2312
|
app.post("/api/message", rateLimit(defaultRateLimitWindowMs, defaultRateLimitMax), concurrencyGuard(MAX_CONCURRENT_MESSAGES), async (req, res) => {
|
|
2177
2313
|
const body = req.body || {};
|
|
2178
2314
|
const content = typeof body.content === "string" && body.content || typeof body.message === "string" && body.message || "";
|
|
@@ -2182,6 +2318,23 @@ data: ${JSON.stringify({ message: "verification stream unavailable" })}
|
|
|
2182
2318
|
res.status(400).json({ error: "content (or message) must be a non-empty string" });
|
|
2183
2319
|
return;
|
|
2184
2320
|
}
|
|
2321
|
+
{
|
|
2322
|
+
const { getProviderReady, refreshProviderReady } = await import("./onboarding.js");
|
|
2323
|
+
if (!getProviderReady()) {
|
|
2324
|
+
const recheck = await refreshProviderReady();
|
|
2325
|
+
if (!recheck.ok) {
|
|
2326
|
+
res.json({
|
|
2327
|
+
content: "I'm not connected to an AI model yet! Click **Set up TITAN** (or open Settings \u2192 Models) and I'll be ready in under a minute. If you use Ollama, just make sure it's running \u2014 I'll find it.",
|
|
2328
|
+
sessionId: requestedSessionId || "welcome",
|
|
2329
|
+
model: "none",
|
|
2330
|
+
toolsUsed: [],
|
|
2331
|
+
durationMs: 0,
|
|
2332
|
+
welcomeMode: true
|
|
2333
|
+
});
|
|
2334
|
+
return;
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2185
2338
|
if (requestedModel && typeof requestedModel === "string") {
|
|
2186
2339
|
const { tryResolveModel, getKnownProviderNames } = await import("../providers/router.js");
|
|
2187
2340
|
if (!tryResolveModel(requestedModel)) {
|
|
@@ -3335,6 +3488,7 @@ data: ${JSON.stringify(structured)}
|
|
|
3335
3488
|
app.use("/api", createLifecycleRouter());
|
|
3336
3489
|
app.use("/api", createSocialRouter());
|
|
3337
3490
|
app.use("/api", createWatchRouter());
|
|
3491
|
+
app.use("/api", createStudioRouter());
|
|
3338
3492
|
app.use("/api/files", createFilesRouter());
|
|
3339
3493
|
app.use("/api", createSystemRouter());
|
|
3340
3494
|
app.use("/api", createVoiceRouter(
|
|
@@ -3361,6 +3515,44 @@ data: ${JSON.stringify(structured)}
|
|
|
3361
3515
|
res.status(500).json({ error: "Widget gallery unavailable" });
|
|
3362
3516
|
}
|
|
3363
3517
|
});
|
|
3518
|
+
app.post("/api/widget/assist", async (req, res) => {
|
|
3519
|
+
try {
|
|
3520
|
+
const source = String(req.body?.source ?? "");
|
|
3521
|
+
const instruction = String(req.body?.instruction ?? "").trim();
|
|
3522
|
+
const format = String(req.body?.format ?? "react");
|
|
3523
|
+
const name = String(req.body?.name ?? "widget").slice(0, 80);
|
|
3524
|
+
if (instruction.length < 2) {
|
|
3525
|
+
res.status(400).json({ error: "instruction_required", message: "Describe the change you want." });
|
|
3526
|
+
return;
|
|
3527
|
+
}
|
|
3528
|
+
const { spawnSubAgent } = await import("../agent/subAgent.js");
|
|
3529
|
+
const prompt = [
|
|
3530
|
+
`You are an expert front-end engineer helping a NON-CODER edit a canvas widget by describing changes in plain English. They will NOT touch the code themselves.`,
|
|
3531
|
+
`Widget name: "${name}". Source format: ${format}.`,
|
|
3532
|
+
``,
|
|
3533
|
+
`CURRENT SOURCE:`,
|
|
3534
|
+
"```",
|
|
3535
|
+
source.slice(0, 12e3),
|
|
3536
|
+
"```",
|
|
3537
|
+
``,
|
|
3538
|
+
`THE USER WANTS: ${instruction}`,
|
|
3539
|
+
``,
|
|
3540
|
+
`Return ONLY the COMPLETE updated ${format} source \u2014 the full file, ready to render. No markdown fences, no commentary, no explanation. Keep it ONE self-contained widget. Preserve everything that already works and change only what the request implies. For a react widget, keep the component named "Widget" and the \`titan\` prop contract if present. If the request is ambiguous, make the most reasonable interpretation.`
|
|
3541
|
+
].join("\n");
|
|
3542
|
+
const result = await spawnSubAgent({ name: "widget-assist", task: prompt, tier: "fast", maxRounds: 1 });
|
|
3543
|
+
let out = (result.content || "").trim();
|
|
3544
|
+
const fence = out.match(/^```[a-zA-Z]*\s*\n([\s\S]*?)\n```\s*$/);
|
|
3545
|
+
if (fence) out = fence[1].trim();
|
|
3546
|
+
if (!out) {
|
|
3547
|
+
res.status(502).json({ error: "empty_result", message: "The AI returned nothing \u2014 try rephrasing." });
|
|
3548
|
+
return;
|
|
3549
|
+
}
|
|
3550
|
+
res.json({ source: out });
|
|
3551
|
+
} catch (err) {
|
|
3552
|
+
logger.error(COMPONENT, `widget assist error: ${err.message}`);
|
|
3553
|
+
res.status(500).json({ error: "widget_assist_failed", message: err.message });
|
|
3554
|
+
}
|
|
3555
|
+
});
|
|
3364
3556
|
app.get("/api/graphiti", async (_req, res) => {
|
|
3365
3557
|
try {
|
|
3366
3558
|
const { getGraphData, getGraphStats: getGraphStats2 } = await import("../memory/graph.js");
|
|
@@ -3587,23 +3779,39 @@ data: ${JSON.stringify(structured)}
|
|
|
3587
3779
|
}
|
|
3588
3780
|
const messengerAdapter = channels.get("messenger");
|
|
3589
3781
|
if (messengerAdapter) {
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3782
|
+
const messengerJson = express.json({
|
|
3783
|
+
verify: (req, _res, buf) => {
|
|
3784
|
+
req.rawBody = buf;
|
|
3785
|
+
}
|
|
3593
3786
|
});
|
|
3594
|
-
|
|
3787
|
+
const checkMessengerSignature = (req) => {
|
|
3788
|
+
const raw = req.rawBody ?? Buffer.from(JSON.stringify(req.body ?? {}));
|
|
3789
|
+
const result = messengerAdapter.verifySignature(raw, req.get("x-hub-signature-256") || void 0);
|
|
3790
|
+
if (result.reason === "no-secret") {
|
|
3791
|
+
logger.warn(COMPONENT, "Messenger FB_APP_SECRET not configured \u2014 webhook signature check SKIPPED (set FB_APP_SECRET to lock down)");
|
|
3792
|
+
}
|
|
3793
|
+
return result.ok;
|
|
3794
|
+
};
|
|
3795
|
+
const handleMessengerPost = (req, res) => {
|
|
3796
|
+
if (!checkMessengerSignature(req)) {
|
|
3797
|
+
logger.warn(COMPONENT, "Messenger webhook: invalid/missing X-Hub-Signature-256 \u2014 rejected (403)");
|
|
3798
|
+
res.status(403).send("forbidden");
|
|
3799
|
+
return;
|
|
3800
|
+
}
|
|
3595
3801
|
messengerAdapter.handleWebhook(req.body);
|
|
3596
3802
|
res.sendStatus(200);
|
|
3803
|
+
};
|
|
3804
|
+
app.get("/api/messenger/webhook", (req, res) => {
|
|
3805
|
+
const result = messengerAdapter.handleVerify(req.query);
|
|
3806
|
+
res.status(result.status).send(result.body);
|
|
3597
3807
|
});
|
|
3808
|
+
app.post("/api/messenger/webhook", messengerJson, handleMessengerPost);
|
|
3598
3809
|
app.get("/messenger/webhook", (req, res) => {
|
|
3599
3810
|
const result = messengerAdapter.handleVerify(req.query);
|
|
3600
3811
|
res.status(result.status).send(result.body);
|
|
3601
3812
|
});
|
|
3602
|
-
app.post("/messenger/webhook",
|
|
3603
|
-
|
|
3604
|
-
res.sendStatus(200);
|
|
3605
|
-
});
|
|
3606
|
-
logger.info(COMPONENT, `Messenger webhook: /api/messenger/webhook + /messenger/webhook (verify token: ${messengerAdapter.getVerifyToken()})`);
|
|
3813
|
+
app.post("/messenger/webhook", messengerJson, handleMessengerPost);
|
|
3814
|
+
logger.info(COMPONENT, `Messenger webhook: /api/messenger/webhook + /messenger/webhook (verify token: ${messengerAdapter.getVerifyToken()}, signature enforcement: ${messengerAdapter.hasAppSecret() ? "ON" : "OFF \u2014 set FB_APP_SECRET"})`);
|
|
3607
3815
|
}
|
|
3608
3816
|
const lineAdapter = channels.get("line");
|
|
3609
3817
|
if (lineAdapter) {
|