titan-agent 5.4.0 → 5.4.2

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.
Files changed (48) hide show
  1. package/dist/agent/agent.js +1 -1
  2. package/dist/agent/agent.js.map +1 -1
  3. package/dist/agent/agentLoop.js +77 -12
  4. package/dist/agent/agentLoop.js.map +1 -1
  5. package/dist/agent/agentWakeup.js +8 -3
  6. package/dist/agent/agentWakeup.js.map +1 -1
  7. package/dist/agent/commandPost.js +6 -1
  8. package/dist/agent/commandPost.js.map +1 -1
  9. package/dist/agent/heartbeatScheduler.js +36 -4
  10. package/dist/agent/heartbeatScheduler.js.map +1 -1
  11. package/dist/agent/toolRunner.js +30 -0
  12. package/dist/agent/toolRunner.js.map +1 -1
  13. package/dist/config/config.js +30 -8
  14. package/dist/config/config.js.map +1 -1
  15. package/dist/config/schema.js +10 -1
  16. package/dist/config/schema.js.map +1 -1
  17. package/dist/eval/record.js +1 -1
  18. package/dist/eval/record.js.map +1 -1
  19. package/dist/gateway/server.js +26 -0
  20. package/dist/gateway/server.js.map +1 -1
  21. package/dist/mesh/transport.js +60 -8
  22. package/dist/mesh/transport.js.map +1 -1
  23. package/dist/providers/anthropic.js +3 -2
  24. package/dist/providers/anthropic.js.map +1 -1
  25. package/dist/providers/base.js.map +1 -1
  26. package/dist/providers/google.js +94 -20
  27. package/dist/providers/google.js.map +1 -1
  28. package/dist/providers/modelCapabilities.js +59 -0
  29. package/dist/providers/modelCapabilities.js.map +1 -0
  30. package/dist/providers/ollama.js +3 -2
  31. package/dist/providers/ollama.js.map +1 -1
  32. package/dist/providers/openai.js +4 -3
  33. package/dist/providers/openai.js.map +1 -1
  34. package/dist/providers/openai_compat.js +3 -2
  35. package/dist/providers/openai_compat.js.map +1 -1
  36. package/dist/providers/router.js +63 -21
  37. package/dist/providers/router.js.map +1 -1
  38. package/dist/skills/registry.js +176 -163
  39. package/dist/skills/registry.js.map +1 -1
  40. package/dist/telemetry/activityLog.js +1 -1
  41. package/dist/telemetry/activityLog.js.map +1 -1
  42. package/dist/utils/constants.js +2 -2
  43. package/dist/utils/constants.js.map +1 -1
  44. package/docs/AGENT-HIERARCHY.md +154 -0
  45. package/docs/superpowers/plans/2026-04-29-titan-production-fix.md +241 -0
  46. package/package.json +2 -2
  47. package/scripts/start-workers.sh +39 -0
  48. package/scripts/task-feeder.ts +38 -0
@@ -6,6 +6,7 @@ import { TITAN_HOME, TITAN_SKILLS_DIR } from "../utils/constants.js";
6
6
  import { registerTool } from "../agent/toolRunner.js";
7
7
  import { ensureDir } from "../utils/helpers.js";
8
8
  import logger from "../utils/logger.js";
9
+ import { loadConfig } from "../config/config.js";
9
10
  const COMPONENT = "Skills";
10
11
  const DISABLED_SKILLS_PATH = join(TITAN_HOME, "disabled-skills.json");
11
12
  const registeredSkills = /* @__PURE__ */ new Map();
@@ -219,90 +220,100 @@ async function initBuiltinSkills() {
219
220
  const { registerFacebookSkill } = await import("./builtin/facebook.js");
220
221
  const { registerFBAutopilotSkill } = await import("./builtin/fb_autopilot.js");
221
222
  const { registerWidgetGallerySkill } = await import("./builtin/widget_gallery.js");
223
+ const config = loadConfig();
224
+ const primitiveMode = config.skills.primitiveMode;
225
+ if (primitiveMode) {
226
+ logger.info(COMPONENT, "PRIMITIVE MODE ENABLED \u2014 loading only shell, filesystem, web_search");
227
+ }
222
228
  const registrations = [
223
229
  ["shell", registerShellSkill],
224
230
  ["filesystem", registerFilesystemSkill],
225
- ["web_search", registerWebSearchSkill],
226
- ["cron", registerCronSkill],
227
- ["webhook", registerWebhookSkill],
228
- ["memory", registerMemorySkill],
229
- ["browser", registerBrowserSkill],
230
- ["sessions", registerSessionsSkill],
231
- ["process", registerProcessSkill],
232
- ["web_fetch", registerWebFetchSkill],
233
- ["apply_patch", registerApplyPatchSkill],
234
- ["auto_generate", registerAutoGenerateSkill],
235
- ["vision", registerVisionSkill],
236
- ["voice", registerVoiceSkills],
237
- ["memory_graph", registerMemoryGraphSkill],
238
- ["web_browser", initWebBrowserTool],
239
- ["github", registerGitHubSkill],
240
- ["email", registerEmailSkill],
241
- ["computer_use", registerComputerUseSkill],
242
- ["image_gen", registerImageGenSkill],
243
- ["pdf", registerPdfSkill],
244
- ["calendar", registerCalendarSkill],
245
- ["smart_home", registerSmartHomeSkill],
246
- ["data_analysis", registerDataAnalysisSkill],
247
- ["skyvern", registerSkyvernSkill],
248
- ["web_browse_llm", registerWebBrowseLlmSkill],
249
- ["income_tracker", registerIncomeTrackerSkill],
250
- ["freelance_monitor", registerFreelanceMonitorSkill],
251
- ["content_publisher", registerContentPublisherSkill],
252
- ["lead_scorer", registerLeadScorerSkill],
253
- ["hunter", registerHunterSkill],
254
- ["code_exec", registerCodeExecSkill],
255
- ["execute_code", registerExecuteCodeSkill],
256
- ["weather", registerWeatherSkill],
257
- ["goals", registerGoalsSkill],
258
- ["x_poster", registerXPosterSkill],
259
- ["model_switch", initModelSwitchTool],
260
- ["rag", registerRagSkill],
261
- ["deep_research", registerDeepResearchSkill],
262
- ["system_info", registerSystemInfoSkill],
263
- ["persona_manager", registerPersonaManagerSkill],
264
- ["research_pipeline", registerResearchPipelineSkill],
265
- ["autoresearch", registerAutoresearchSkill],
266
- ["self_doctor", registerSelfDoctorSkill],
267
- ["interaction_tracker", registerInteractionTrackerSkill],
268
- ["feedback_tracker", registerFeedbackTrackerSkill],
269
- ["growth_experiments", registerGrowthExperimentsSkill],
270
- ["content_calendar", registerContentCalendarSkill],
271
- ["slack", registerSlackSkill],
272
- ["revenuecat_kb", registerRevenueCatKBSkill],
273
- ["weekly_report", registerWeeklyReportSkill],
274
- ["self_improve", registerSelfImproveSkill],
275
- ["gepa", registerGepaSkill],
276
- ["model_trainer", registerModelTrainerSkill],
277
- ["social_scheduler", registerSocialSchedulerSkill],
278
- ["structured_output", registerStructuredOutputSkill],
279
- ["workflows", registerWorkflowsSkill],
280
- ["agent_handoff", registerAgentHandoffSkill],
281
- ["knowledge_base", registerKnowledgeBaseSkill],
282
- ["event_triggers", registerEventTriggersSkill],
283
- ["evals", registerEvalsSkill],
284
- ["a2a_protocol", registerA2AProtocolSkill],
285
- ["approval_gates", registerApprovalGatesSkill],
286
- ["vram", registerVRAMSkills],
287
- ["security_scan", registerSecurityScanSkill],
288
- ["changelog_gen", registerChangelogGenSkill],
289
- ["jira_linear", registerJiraLinearSkill],
290
- ["audit_trail", registerAuditTrailSkill],
291
- ["visual_plan", registerVisualPlanSkill],
292
- ["screen_record", registerScreenRecordSkill],
293
- ["session_teleport", registerSessionTeleportSkill],
294
- ["cross_provider", registerCrossProviderSkill],
295
- ["sentry", registerSentrySkill],
296
- ["video", registerVideoSkill],
297
- ["mixture_of_agents", registerMixtureOfAgentsSkill],
298
- ["agent_debate", registerAgentDebateSkill],
299
- ["file_checkpoints", registerFileCheckpointsSkill],
300
- ["verify_page", registerVerifyPageSkill],
301
- ["agent_messaging", registerAgentMessagingSkill],
302
- ["facebook", registerFacebookSkill],
303
- ["fb_autopilot", registerFBAutopilotSkill],
304
- ["widget_gallery", registerWidgetGallerySkill]
231
+ ["web_search", registerWebSearchSkill]
305
232
  ];
233
+ if (!primitiveMode) {
234
+ registrations.push(
235
+ ["cron", registerCronSkill],
236
+ ["webhook", registerWebhookSkill],
237
+ ["memory", registerMemorySkill],
238
+ ["browser", registerBrowserSkill],
239
+ ["sessions", registerSessionsSkill],
240
+ ["process", registerProcessSkill],
241
+ ["web_fetch", registerWebFetchSkill],
242
+ ["apply_patch", registerApplyPatchSkill],
243
+ ["auto_generate", registerAutoGenerateSkill],
244
+ ["vision", registerVisionSkill],
245
+ ["voice", registerVoiceSkills],
246
+ ["memory_graph", registerMemoryGraphSkill],
247
+ ["web_browser", initWebBrowserTool],
248
+ ["github", registerGitHubSkill],
249
+ ["email", registerEmailSkill],
250
+ ["computer_use", registerComputerUseSkill],
251
+ ["image_gen", registerImageGenSkill],
252
+ ["pdf", registerPdfSkill],
253
+ ["calendar", registerCalendarSkill],
254
+ ["smart_home", registerSmartHomeSkill],
255
+ ["data_analysis", registerDataAnalysisSkill],
256
+ ["skyvern", registerSkyvernSkill],
257
+ ["web_browse_llm", registerWebBrowseLlmSkill],
258
+ ["income_tracker", registerIncomeTrackerSkill],
259
+ ["freelance_monitor", registerFreelanceMonitorSkill],
260
+ ["content_publisher", registerContentPublisherSkill],
261
+ ["lead_scorer", registerLeadScorerSkill],
262
+ ["hunter", registerHunterSkill],
263
+ ["code_exec", registerCodeExecSkill],
264
+ ["execute_code", registerExecuteCodeSkill],
265
+ ["weather", registerWeatherSkill],
266
+ ["goals", registerGoalsSkill],
267
+ ["x_poster", registerXPosterSkill],
268
+ ["model_switch", initModelSwitchTool],
269
+ ["rag", registerRagSkill],
270
+ ["deep_research", registerDeepResearchSkill],
271
+ ["system_info", registerSystemInfoSkill],
272
+ ["persona_manager", registerPersonaManagerSkill],
273
+ ["research_pipeline", registerResearchPipelineSkill],
274
+ ["autoresearch", registerAutoresearchSkill],
275
+ ["self_doctor", registerSelfDoctorSkill],
276
+ ["interaction_tracker", registerInteractionTrackerSkill],
277
+ ["feedback_tracker", registerFeedbackTrackerSkill],
278
+ ["growth_experiments", registerGrowthExperimentsSkill],
279
+ ["content_calendar", registerContentCalendarSkill],
280
+ ["slack", registerSlackSkill],
281
+ ["revenuecat_kb", registerRevenueCatKBSkill],
282
+ ["weekly_report", registerWeeklyReportSkill],
283
+ ["self_improve", registerSelfImproveSkill],
284
+ ["gepa", registerGepaSkill],
285
+ ["model_trainer", registerModelTrainerSkill],
286
+ ["social_scheduler", registerSocialSchedulerSkill],
287
+ ["structured_output", registerStructuredOutputSkill],
288
+ ["workflows", registerWorkflowsSkill],
289
+ ["agent_handoff", registerAgentHandoffSkill],
290
+ ["knowledge_base", registerKnowledgeBaseSkill],
291
+ ["event_triggers", registerEventTriggersSkill],
292
+ ["evals", registerEvalsSkill],
293
+ ["a2a_protocol", registerA2AProtocolSkill],
294
+ ["approval_gates", registerApprovalGatesSkill],
295
+ ["vram", registerVRAMSkills],
296
+ ["security_scan", registerSecurityScanSkill],
297
+ ["changelog_gen", registerChangelogGenSkill],
298
+ ["jira_linear", registerJiraLinearSkill],
299
+ ["audit_trail", registerAuditTrailSkill],
300
+ ["visual_plan", registerVisualPlanSkill],
301
+ ["screen_record", registerScreenRecordSkill],
302
+ ["session_teleport", registerSessionTeleportSkill],
303
+ ["cross_provider", registerCrossProviderSkill],
304
+ ["sentry", registerSentrySkill],
305
+ ["video", registerVideoSkill],
306
+ ["mixture_of_agents", registerMixtureOfAgentsSkill],
307
+ ["agent_debate", registerAgentDebateSkill],
308
+ ["file_checkpoints", registerFileCheckpointsSkill],
309
+ ["verify_page", registerVerifyPageSkill],
310
+ ["agent_messaging", registerAgentMessagingSkill],
311
+ ["facebook", registerFacebookSkill],
312
+ ["fb_autopilot", registerFBAutopilotSkill],
313
+ ["widget_gallery", registerWidgetGallerySkill],
314
+ ["widget_gallery", registerWidgetGallerySkill]
315
+ );
316
+ }
306
317
  for (const [name, fn] of registrations) {
307
318
  try {
308
319
  fn();
@@ -310,93 +321,95 @@ async function initBuiltinSkills() {
310
321
  logger.warn(COMPONENT, `Failed to register skill "${name}": ${e.message}`);
311
322
  }
312
323
  }
313
- const { registerPlannerTool } = await import("../agent/planner.js");
314
- try {
315
- registerPlannerTool();
316
- } catch (e) {
317
- logger.warn(COMPONENT, `Failed to register planner: ${e.message}`);
318
- }
319
- try {
320
- const { createTopFactsPlugin } = await import("../plugins/topFacts.js");
321
- const { createMemoryRetrievalPlugin } = await import("../plugins/memoryRetrieval.js");
322
- const { registerPlugin } = await import("../plugins/registry.js");
323
- const topFacts = createTopFactsPlugin();
324
- registerPlugin(topFacts);
325
- if (topFacts.bootstrap) await topFacts.bootstrap({});
326
- const memoryRetrieval = createMemoryRetrievalPlugin();
327
- registerPlugin(memoryRetrieval);
328
- if (memoryRetrieval.bootstrap) await memoryRetrieval.bootstrap({});
329
- } catch (e) {
330
- logger.warn(COMPONENT, `Failed to register TopFacts plugin: ${e.message}`);
331
- }
332
- try {
333
- const { createSmartCompressPlugin } = await import("../plugins/smartCompress.js");
334
- const { registerPlugin: regPlugin } = await import("../plugins/registry.js");
335
- const smartCompress = createSmartCompressPlugin();
336
- regPlugin(smartCompress);
337
- if (smartCompress.bootstrap) await smartCompress.bootstrap({});
338
- } catch (e) {
339
- logger.warn(COMPONENT, `Failed to register SmartCompress plugin: ${e.message}`);
340
- }
341
- const { getToolSearchHandler, getToolExpandHandler } = await import("../agent/toolSearch.js");
342
- try {
343
- registerTool(getToolSearchHandler());
344
- } catch (e) {
345
- logger.warn(COMPONENT, `Failed to register tool_search: ${e.message}`);
346
- }
347
- try {
348
- registerTool(getToolExpandHandler());
349
- } catch (e) {
350
- logger.warn(COMPONENT, `Failed to register tool_expand: ${e.message}`);
351
- }
352
- try {
353
- const { saveSkill, searchSkills } = await import("./proceduralMemory.js");
354
- registerTool({
355
- name: "save_skill",
356
- description: "Save a reusable approach/technique as a procedural skill for future tasks. Use this when you discover an effective approach that could help in similar future situations.",
357
- parameters: {
358
- type: "object",
359
- properties: {
360
- name: { type: "string", description: 'Short descriptive name for the skill (e.g., "Deploy Node.js app to Docker")' },
361
- tags: { type: "array", items: { type: "string" }, description: 'Tags for searchability (e.g., ["docker", "deployment", "nodejs"])' },
362
- content: { type: "string", description: "The reusable approach/technique in markdown format. Include key steps, commands, and gotchas." }
324
+ if (!primitiveMode) {
325
+ const { registerPlannerTool } = await import("../agent/planner.js");
326
+ try {
327
+ registerPlannerTool();
328
+ } catch (e) {
329
+ logger.warn(COMPONENT, `Failed to register planner: ${e.message}`);
330
+ }
331
+ try {
332
+ const { createTopFactsPlugin } = await import("../plugins/topFacts.js");
333
+ const { createMemoryRetrievalPlugin } = await import("../plugins/memoryRetrieval.js");
334
+ const { registerPlugin } = await import("../plugins/registry.js");
335
+ const topFacts = createTopFactsPlugin();
336
+ registerPlugin(topFacts);
337
+ if (topFacts.bootstrap) await topFacts.bootstrap({});
338
+ const memoryRetrieval = createMemoryRetrievalPlugin();
339
+ registerPlugin(memoryRetrieval);
340
+ if (memoryRetrieval.bootstrap) await memoryRetrieval.bootstrap({});
341
+ } catch (e) {
342
+ logger.warn(COMPONENT, `Failed to register TopFacts plugin: ${e.message}`);
343
+ }
344
+ try {
345
+ const { createSmartCompressPlugin } = await import("../plugins/smartCompress.js");
346
+ const { registerPlugin: regPlugin } = await import("../plugins/registry.js");
347
+ const smartCompress = createSmartCompressPlugin();
348
+ regPlugin(smartCompress);
349
+ if (smartCompress.bootstrap) await smartCompress.bootstrap({});
350
+ } catch (e) {
351
+ logger.warn(COMPONENT, `Failed to register SmartCompress plugin: ${e.message}`);
352
+ }
353
+ const { getToolSearchHandler, getToolExpandHandler } = await import("../agent/toolSearch.js");
354
+ try {
355
+ registerTool(getToolSearchHandler());
356
+ } catch (e) {
357
+ logger.warn(COMPONENT, `Failed to register tool_search: ${e.message}`);
358
+ }
359
+ try {
360
+ registerTool(getToolExpandHandler());
361
+ } catch (e) {
362
+ logger.warn(COMPONENT, `Failed to register tool_expand: ${e.message}`);
363
+ }
364
+ try {
365
+ const { saveSkill, searchSkills } = await import("./proceduralMemory.js");
366
+ registerTool({
367
+ name: "save_skill",
368
+ description: "Save a reusable approach/technique as a procedural skill for future tasks. Use this when you discover an effective approach that could help in similar future situations.",
369
+ parameters: {
370
+ type: "object",
371
+ properties: {
372
+ name: { type: "string", description: 'Short descriptive name for the skill (e.g., "Deploy Node.js app to Docker")' },
373
+ tags: { type: "array", items: { type: "string" }, description: 'Tags for searchability (e.g., ["docker", "deployment", "nodejs"])' },
374
+ content: { type: "string", description: "The reusable approach/technique in markdown format. Include key steps, commands, and gotchas." }
375
+ },
376
+ required: ["name", "tags", "content"]
363
377
  },
364
- required: ["name", "tags", "content"]
365
- },
366
- execute: async (args) => {
367
- const name = args.name;
368
- const tags = args.tags || [];
369
- const content = args.content;
370
- if (!name || !content) return "Error: name and content are required";
371
- const skill = saveSkill(name, tags, content);
372
- return `Skill saved: "${skill.name}" (tags: ${skill.tags.join(", ")}). It will be auto-recalled in future tasks matching these tags.`;
373
- }
374
- });
375
- registerTool({
376
- name: "recall_skill",
377
- description: "Search for previously saved procedural skills by keyword or tag. Returns reusable approaches from past tasks.",
378
- parameters: {
379
- type: "object",
380
- properties: {
381
- query: { type: "string", description: "Search query \u2014 keywords or tags to find relevant skills" }
378
+ execute: async (args) => {
379
+ const name = args.name;
380
+ const tags = args.tags || [];
381
+ const content = args.content;
382
+ if (!name || !content) return "Error: name and content are required";
383
+ const skill = saveSkill(name, tags, content);
384
+ return `Skill saved: "${skill.name}" (tags: ${skill.tags.join(", ")}). It will be auto-recalled in future tasks matching these tags.`;
385
+ }
386
+ });
387
+ registerTool({
388
+ name: "recall_skill",
389
+ description: "Search for previously saved procedural skills by keyword or tag. Returns reusable approaches from past tasks.",
390
+ parameters: {
391
+ type: "object",
392
+ properties: {
393
+ query: { type: "string", description: "Search query \u2014 keywords or tags to find relevant skills" }
394
+ },
395
+ required: ["query"]
382
396
  },
383
- required: ["query"]
384
- },
385
- execute: async (args) => {
386
- const query = args.query;
387
- if (!query) return "Error: query is required";
388
- const results = searchSkills(query, 5);
389
- if (results.length === 0) return "No matching skills found. Consider saving useful approaches with save_skill.";
390
- return results.map(
391
- (s) => `### ${s.name}
397
+ execute: async (args) => {
398
+ const query = args.query;
399
+ if (!query) return "Error: query is required";
400
+ const results = searchSkills(query, 5);
401
+ if (results.length === 0) return "No matching skills found. Consider saving useful approaches with save_skill.";
402
+ return results.map(
403
+ (s) => `### ${s.name}
392
404
  Tags: ${s.tags.join(", ")} | Used ${s.useCount}x
393
405
  ${s.content.slice(0, 800)}`
394
- ).join("\n\n---\n\n");
395
- }
396
- });
397
- logger.info(COMPONENT, "Registered procedural memory tools (save_skill, recall_skill)");
398
- } catch (e) {
399
- logger.warn(COMPONENT, `Failed to register procedural memory tools: ${e.message}`);
406
+ ).join("\n\n---\n\n");
407
+ }
408
+ });
409
+ logger.info(COMPONENT, "Registered procedural memory tools (save_skill, recall_skill)");
410
+ } catch (e) {
411
+ logger.warn(COMPONENT, `Failed to register procedural memory tools: ${e.message}`);
412
+ }
400
413
  }
401
414
  logger.info(COMPONENT, `Loaded ${registeredSkills.size} built-in skills`);
402
415
  if (process.env.NODE_ENV !== "production" || process.env.TITAN_DEV) {