@tenex-chat/backend 0.9.4 → 0.9.6

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 (148) hide show
  1. package/README.md +5 -1
  2. package/dist/daemon-wrapper.cjs +47 -0
  3. package/dist/index.js +59268 -0
  4. package/dist/wrapper.js +171 -0
  5. package/package.json +19 -27
  6. package/src/agents/AgentRegistry.ts +9 -7
  7. package/src/agents/AgentStorage.ts +24 -1
  8. package/src/agents/agent-installer.ts +6 -0
  9. package/src/agents/agent-loader.ts +7 -2
  10. package/src/agents/constants.ts +10 -2
  11. package/src/agents/execution/AgentExecutor.ts +35 -6
  12. package/src/agents/execution/StreamCallbacks.ts +53 -13
  13. package/src/agents/execution/StreamExecutionHandler.ts +110 -16
  14. package/src/agents/execution/StreamSetup.ts +19 -9
  15. package/src/agents/execution/ToolEventHandlers.ts +112 -0
  16. package/src/agents/role-categories.ts +53 -0
  17. package/src/agents/types/runtime.ts +7 -0
  18. package/src/agents/types/storage.ts +7 -0
  19. package/src/commands/agent/import/openclaw-distiller.ts +63 -7
  20. package/src/commands/agent/import/openclaw-reader.ts +54 -0
  21. package/src/commands/agent/import/openclaw.ts +120 -29
  22. package/src/commands/agent/index.ts +83 -2
  23. package/src/commands/setup/display.ts +123 -0
  24. package/src/commands/setup/embed.ts +13 -13
  25. package/src/commands/setup/global-system-prompt.ts +15 -17
  26. package/src/commands/setup/image.ts +17 -20
  27. package/src/commands/setup/interactive.ts +37 -20
  28. package/src/commands/setup/llm.ts +12 -7
  29. package/src/commands/setup/onboarding.ts +1580 -248
  30. package/src/commands/setup/providers.ts +3 -3
  31. package/src/conversations/ConversationStore.ts +23 -2
  32. package/src/conversations/MessageBuilder.ts +51 -73
  33. package/src/conversations/formatters/utils/conversation-transcript-formatter.ts +425 -0
  34. package/src/conversations/search/embeddings/ConversationEmbeddingService.ts +40 -98
  35. package/src/conversations/search/embeddings/ConversationIndexingJob.ts +40 -52
  36. package/src/conversations/services/ConversationSummarizer.ts +1 -2
  37. package/src/conversations/types.ts +11 -0
  38. package/src/daemon/Daemon.ts +78 -57
  39. package/src/daemon/ProjectRuntime.ts +6 -12
  40. package/src/daemon/SubscriptionManager.ts +13 -0
  41. package/src/daemon/index.ts +0 -1
  42. package/src/event-handler/index.ts +1 -0
  43. package/src/index.ts +20 -1
  44. package/src/llm/ChunkHandler.ts +1 -1
  45. package/src/llm/FinishHandler.ts +28 -4
  46. package/src/llm/LLMConfigEditor.ts +218 -106
  47. package/src/llm/index.ts +0 -4
  48. package/src/llm/meta/MetaModelResolver.ts +3 -18
  49. package/src/llm/middleware/message-sanitizer.ts +153 -0
  50. package/src/llm/providers/ollama-models.ts +0 -38
  51. package/src/llm/service.ts +50 -15
  52. package/src/llm/types.ts +0 -12
  53. package/src/llm/utils/ConfigurationManager.ts +88 -465
  54. package/src/llm/utils/ConfigurationTester.ts +42 -185
  55. package/src/llm/utils/ModelSelector.ts +156 -92
  56. package/src/llm/utils/ProviderConfigUI.ts +10 -141
  57. package/src/llm/utils/models-dev-cache.ts +102 -23
  58. package/src/llm/utils/provider-select-prompt.ts +284 -0
  59. package/src/llm/utils/provider-setup.ts +81 -34
  60. package/src/llm/utils/variant-list-prompt.ts +361 -0
  61. package/src/nostr/AgentEventDecoder.ts +1 -0
  62. package/src/nostr/AgentEventEncoder.ts +37 -0
  63. package/src/nostr/AgentProfilePublisher.ts +13 -0
  64. package/src/nostr/AgentPublisher.ts +26 -0
  65. package/src/nostr/kinds.ts +1 -0
  66. package/src/nostr/ndkClient.ts +4 -1
  67. package/src/nostr/types.ts +12 -0
  68. package/src/prompts/fragments/25-rag-instructions.ts +22 -21
  69. package/src/prompts/fragments/31-agents-md-guidance.ts +7 -21
  70. package/src/prompts/fragments/index.ts +2 -0
  71. package/src/prompts/utils/systemPromptBuilder.ts +18 -28
  72. package/src/services/AgentDefinitionMonitor.ts +8 -0
  73. package/src/services/ConfigService.ts +34 -0
  74. package/src/services/PubkeyService.ts +7 -1
  75. package/src/services/compression/CompressionService.ts +133 -74
  76. package/src/services/compression/compression-utils.ts +110 -19
  77. package/src/services/config/types.ts +0 -6
  78. package/src/services/dispatch/AgentDispatchService.ts +79 -0
  79. package/src/services/intervention/InterventionService.ts +78 -5
  80. package/src/services/nip46/Nip46SigningService.ts +30 -1
  81. package/src/services/projects/ProjectContext.ts +8 -6
  82. package/src/services/rag/RAGCollectionRegistry.ts +199 -0
  83. package/src/services/rag/RAGDatabaseService.ts +2 -7
  84. package/src/services/rag/RAGOperations.ts +25 -45
  85. package/src/services/rag/RAGService.ts +0 -31
  86. package/src/services/rag/RagSubscriptionService.ts +71 -122
  87. package/src/services/rag/rag-utils.ts +13 -0
  88. package/src/services/ral/RALRegistry.ts +25 -184
  89. package/src/services/reports/ReportEmbeddingService.ts +63 -113
  90. package/src/services/search/UnifiedSearchService.ts +115 -4
  91. package/src/services/search/index.ts +1 -0
  92. package/src/services/search/projectFilter.ts +20 -4
  93. package/src/services/search/providers/ConversationSearchProvider.ts +1 -0
  94. package/src/services/search/providers/GenericCollectionSearchProvider.ts +81 -0
  95. package/src/services/search/providers/LessonSearchProvider.ts +1 -8
  96. package/src/services/search/providers/ReportSearchProvider.ts +1 -0
  97. package/src/services/search/types.ts +24 -3
  98. package/src/services/trust-pubkeys/SystemPubkeyListService.ts +148 -0
  99. package/src/services/trust-pubkeys/TrustPubkeyService.ts +70 -9
  100. package/src/telemetry/setup.ts +2 -13
  101. package/src/tools/implementations/ask.ts +3 -3
  102. package/src/tools/implementations/conversation_get.ts +28 -268
  103. package/src/tools/implementations/fs_grep.ts +6 -6
  104. package/src/tools/implementations/fs_read.ts +2 -0
  105. package/src/tools/implementations/fs_write.ts +2 -0
  106. package/src/tools/implementations/learn.ts +38 -50
  107. package/src/tools/implementations/rag_add_documents.ts +6 -4
  108. package/src/tools/implementations/rag_create_collection.ts +37 -4
  109. package/src/tools/implementations/rag_delete_collection.ts +9 -0
  110. package/src/tools/implementations/{search.ts → rag_search.ts} +31 -25
  111. package/src/tools/registry.ts +7 -8
  112. package/src/tools/types.ts +11 -2
  113. package/src/tools/utils/transcript-args.ts +13 -0
  114. package/src/utils/cli-theme.ts +13 -0
  115. package/src/utils/logger.ts +55 -0
  116. package/src/utils/metadataKeys.ts +17 -0
  117. package/src/utils/sqlEscaping.ts +39 -0
  118. package/src/wrapper.ts +7 -3
  119. package/dist/src/index.js +0 -46778
  120. package/dist/tenex-backend-wrapper.cjs +0 -3
  121. package/src/agents/execution/constants.ts +0 -16
  122. package/src/agents/execution/index.ts +0 -3
  123. package/src/agents/index.ts +0 -4
  124. package/src/commands/agent.ts +0 -215
  125. package/src/conversations/formatters/DelegationXmlFormatter.ts +0 -64
  126. package/src/conversations/formatters/index.ts +0 -9
  127. package/src/conversations/index.ts +0 -2
  128. package/src/conversations/utils/content-utils.ts +0 -69
  129. package/src/daemon/UnixSocketTransport.ts +0 -318
  130. package/src/event-handler/newConversation.ts +0 -165
  131. package/src/events/NDKProjectStatus.ts +0 -384
  132. package/src/events/index.ts +0 -4
  133. package/src/lib/json-parser.ts +0 -30
  134. package/src/llm/RecordingState.ts +0 -37
  135. package/src/llm/StreamPublisher.ts +0 -40
  136. package/src/llm/middleware/flight-recorder.ts +0 -188
  137. package/src/llm/utils/claudeCodePromptCompiler.ts +0 -141
  138. package/src/nostr/constants.ts +0 -38
  139. package/src/prompts/core/index.ts +0 -3
  140. package/src/prompts/index.ts +0 -21
  141. package/src/services/image/index.ts +0 -12
  142. package/src/services/status/index.ts +0 -11
  143. package/src/telemetry/diagnostics.ts +0 -27
  144. package/src/tools/implementations/rag_query.ts +0 -107
  145. package/src/types/index.ts +0 -46
  146. package/src/utils/agentFetcher.ts +0 -107
  147. package/src/utils/conversation-utils.ts +0 -1
  148. package/src/utils/process.ts +0 -49
@@ -7,7 +7,8 @@ import {
7
7
  type ImageConfig,
8
8
  } from "@/services/image/ImageGenerationService";
9
9
  import { config as configService } from "@/services/ConfigService";
10
- import { logger } from "@/utils/logger";
10
+ import { amber, inquirerTheme } from "@/utils/cli-theme";
11
+ import chalk from "chalk";
11
12
  import { Command } from "commander";
12
13
  import inquirer from "inquirer";
13
14
 
@@ -31,9 +32,7 @@ export const imageCommand = new Command("image")
31
32
  if (scope === "project") {
32
33
  // Check if we're in a TENEX project
33
34
  if (!(await fileSystem.directoryExists(baseDir))) {
34
- logger.error(
35
- "No .tenex directory found. Make sure you're in a TENEX project directory."
36
- );
35
+ console.log(chalk.red("āŒ No .tenex directory found. Make sure you're in a TENEX project directory."));
37
36
  process.exitCode = 1;
38
37
  return;
39
38
  }
@@ -51,17 +50,13 @@ export const imageCommand = new Command("image")
51
50
  // Check if OpenRouter is configured
52
51
  const providersConfig = await configService.loadTenexProviders(configService.getGlobalPath());
53
52
  if (!providersConfig.providers.openrouter?.apiKey) {
54
- logger.error(
55
- "OpenRouter is not configured. Run `tenex setup providers` and add your OpenRouter API key first."
56
- );
57
- logger.info(
58
- "\nImage generation requires OpenRouter. Get an API key at: https://openrouter.ai/keys"
59
- );
53
+ console.log(chalk.red("āŒ OpenRouter is not configured. Run `tenex setup providers` and add your OpenRouter API key first."));
54
+ console.log(amber("→") + chalk.bold(" Image generation requires OpenRouter. Get an API key at: https://openrouter.ai/keys"));
60
55
  process.exitCode = 1;
61
56
  return;
62
57
  }
63
58
 
64
- logger.info("āœ“ OpenRouter API key found\n");
59
+ console.log(chalk.green("āœ“") + chalk.bold(" OpenRouter API key found") + "\n");
65
60
 
66
61
  // Build model choices
67
62
  const modelChoices = OPENROUTER_IMAGE_MODELS.map((m) => ({
@@ -83,6 +78,7 @@ export const imageCommand = new Command("image")
83
78
  message: "Select default image generation model:",
84
79
  choices: modelChoices,
85
80
  default: existing?.model || OPENROUTER_IMAGE_MODELS[0]?.value,
81
+ theme: inquirerTheme,
86
82
  },
87
83
  ]);
88
84
 
@@ -93,6 +89,7 @@ export const imageCommand = new Command("image")
93
89
  type: "input",
94
90
  name: "customModel",
95
91
  message: "Enter OpenRouter model ID (e.g., black-forest-labs/flux.2-pro):",
92
+ theme: inquirerTheme,
96
93
  validate: (input: string) =>
97
94
  input.trim().length > 0 || "Model ID cannot be empty",
98
95
  },
@@ -120,6 +117,7 @@ export const imageCommand = new Command("image")
120
117
  message: "Select default aspect ratio:",
121
118
  choices: aspectRatioChoices,
122
119
  default: existing?.defaultAspectRatio || "1:1",
120
+ theme: inquirerTheme,
123
121
  },
124
122
  ]);
125
123
 
@@ -139,6 +137,7 @@ export const imageCommand = new Command("image")
139
137
  message: "Select default image size:",
140
138
  choices: imageSizeChoices,
141
139
  default: existing?.defaultImageSize || "2K",
140
+ theme: inquirerTheme,
142
141
  },
143
142
  ]);
144
143
 
@@ -158,14 +157,12 @@ export const imageCommand = new Command("image")
158
157
  const modelInfo = OPENROUTER_IMAGE_MODELS.find((m) => m.value === model);
159
158
  const modelDisplayName = modelInfo ? modelInfo.name : model;
160
159
 
161
- logger.info(
162
- `\nāœ… Image generation configured for ${scope}\n` +
163
- ` Provider: OpenRouter\n` +
164
- ` Model: ${modelDisplayName} (${model})\n` +
165
- ` Default aspect ratio: ${aspectRatio}\n` +
166
- ` Default image size: ${imageSize}\n` +
167
- "\nAgents can now use the generate_image tool to create images."
168
- );
160
+ console.log("\n" + chalk.green("āœ“") + chalk.bold(` Image generation configured for ${scope}`));
161
+ console.log(chalk.gray(` Provider: OpenRouter`));
162
+ console.log(chalk.gray(` Model: ${modelDisplayName} (${model})`));
163
+ console.log(chalk.gray(` Default aspect ratio: ${aspectRatio}`));
164
+ console.log(chalk.gray(` Default image size: ${imageSize}`));
165
+ console.log(chalk.gray("\nAgents can now use the generate_image tool to create images."));
169
166
  } catch (error: unknown) {
170
167
  // Handle SIGINT (Ctrl+C) gracefully
171
168
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -173,7 +170,7 @@ export const imageCommand = new Command("image")
173
170
  return;
174
171
  }
175
172
 
176
- logger.error(`Failed to configure image generation: ${error}`);
173
+ console.log(chalk.red(`āŒ Failed to configure image generation: ${error}`));
177
174
  process.exitCode = 1;
178
175
  }
179
176
  });
@@ -1,16 +1,17 @@
1
1
  import { LLMConfigEditor } from "@/llm/LLMConfigEditor";
2
+ import { runProviderSetup } from "@/llm/utils/provider-setup";
2
3
  import { config } from "@/services/ConfigService";
3
4
  import type { TenexConfig } from "@/services/config/types";
4
- import { logger } from "@/utils/logger";
5
- import chalk from "chalk";
5
+ import { inquirerTheme } from "@/utils/cli-theme";
6
+ import * as display from "./display";
6
7
  import inquirer from "inquirer";
7
8
 
8
9
  export async function runInteractiveSetup(): Promise<TenexConfig> {
9
- logger.info(chalk.cyan("\nšŸš€ Welcome to TENEX Daemon Setup\n"));
10
- logger.info("Let's configure your daemon to get started.\n");
10
+ display.welcome();
11
11
 
12
12
  // Load current configuration to check what's missing
13
13
  const { config: currentConfig, llms: currentLLMs } = await config.loadConfig();
14
+ const globalPath = config.getGlobalPath();
14
15
  const needsPubkeys =
15
16
  !currentConfig.whitelistedPubkeys || currentConfig.whitelistedPubkeys.length === 0;
16
17
  const needsLLMs =
@@ -28,31 +29,44 @@ export async function runInteractiveSetup(): Promise<TenexConfig> {
28
29
  whitelistedPubkeys: pubkeys,
29
30
  };
30
31
 
31
- // Step 2: Save basic configuration (preserving existing settings)
32
+ // Save basic configuration
32
33
  await config.saveGlobalConfig(tenexConfig);
33
34
 
34
- // Step 3: Set up LLM configurations if needed
35
+ // Step 2: Providers
35
36
  if (needsLLMs) {
36
- logger.info(chalk.yellow("\nStep 2: LLM Configuration"));
37
- logger.info("You need at least one LLM configuration to run projects.\n");
38
-
39
- const llmEditor = new LLMConfigEditor();
40
- await llmEditor.runOnboardingFlow();
37
+ display.step(1, 2, "AI Providers");
38
+ display.context("Connect the AI services your agents will use.");
39
+ display.blank();
40
+
41
+ const existingProviders = await config.loadTenexProviders(globalPath);
42
+ const updatedProviders = await runProviderSetup(existingProviders);
43
+ await config.saveGlobalProviders(updatedProviders);
44
+ display.success("Provider credentials saved");
45
+
46
+ // Step 3: Models
47
+ if (Object.keys(updatedProviders.providers).length > 0) {
48
+ display.step(2, 2, "Models");
49
+ display.context("Configure which models your agents will use.");
50
+ display.blank();
51
+
52
+ const llmEditor = new LLMConfigEditor();
53
+ await llmEditor.showMainMenu();
54
+ }
41
55
  }
42
56
 
43
- logger.info(chalk.green("\nāœ… Setup complete!"));
44
- logger.info(chalk.green(`Configuration saved to: ${config.getGlobalPath()}/`));
45
- logger.info(
46
- chalk.gray("\nYou can now run 'tenex daemon' to start the daemon with your configuration.")
47
- );
57
+ display.setupComplete();
58
+ display.context(`Configuration saved to: ${config.getGlobalPath()}/`);
59
+ display.hint("You can now run 'tenex daemon' to start the daemon with your configuration.");
60
+ display.blank();
48
61
 
49
62
  return tenexConfig;
50
63
  }
51
64
 
52
65
  async function promptForPubkeys(): Promise<string[]> {
53
- logger.info(chalk.yellow("Step 1: Whitelist Configuration"));
54
- logger.info("Enter the Nostr pubkeys (hex format) that are allowed to control this daemon.");
55
- logger.info("You can add multiple pubkeys, one at a time.\n");
66
+ display.step(0, 0, "Whitelist Configuration");
67
+ display.context("Enter the Nostr pubkeys (hex format) that are allowed to control this daemon.");
68
+ display.context("You can add multiple pubkeys, one at a time.");
69
+ display.blank();
56
70
 
57
71
  const pubkeys: string[] = [];
58
72
  let addMore = true;
@@ -63,6 +77,7 @@ async function promptForPubkeys(): Promise<string[]> {
63
77
  type: "input",
64
78
  name: "pubkey",
65
79
  message: "Enter a pubkey (hex format):",
80
+ theme: inquirerTheme,
66
81
  validate: (input) => {
67
82
  if (!input.trim()) {
68
83
  return "Pubkey cannot be empty";
@@ -84,12 +99,14 @@ async function promptForPubkeys(): Promise<string[]> {
84
99
  name: "continueAdding",
85
100
  message: "Add another pubkey?",
86
101
  default: false,
102
+ theme: inquirerTheme,
87
103
  },
88
104
  ]);
89
105
  addMore = continueAdding;
90
106
  }
91
107
  }
92
108
 
93
- logger.info(chalk.green(`\nāœ“ Added ${pubkeys.length} whitelisted pubkey(s)\n`));
109
+ display.blank();
110
+ display.success(`Added ${pubkeys.length} whitelisted pubkey(s)`);
94
111
  return pubkeys;
95
112
  }
@@ -1,13 +1,19 @@
1
1
  import * as fileSystem from "@/lib/fs";
2
2
  import { LLMConfigEditor } from "@/llm/LLMConfigEditor";
3
+ import { ensureCacheLoaded } from "@/llm/utils/models-dev-cache";
3
4
  import { config } from "@/services/ConfigService";
4
- import { logger } from "@/utils/logger";
5
+ import { amber } from "@/utils/cli-theme";
6
+ import chalk from "chalk";
5
7
  import { Command } from "commander";
6
8
 
7
9
  export const llmCommand = new Command("llm")
8
10
  .description("Manage LLM configurations (global only)")
9
- .action(async () => {
11
+ .option("--advanced", "Show advanced options (temperature, max tokens)")
12
+ .action(async (opts) => {
10
13
  try {
14
+ // Preload models.dev cache in background so model lists are ready
15
+ ensureCacheLoaded().catch(() => {});
16
+
11
17
  // LLM configuration is global only
12
18
  const globalConfigDir = config.getGlobalPath();
13
19
 
@@ -16,14 +22,13 @@ export const llmCommand = new Command("llm")
16
22
 
17
23
  const providersConfig = await config.loadTenexProviders(globalConfigDir);
18
24
  if (Object.keys(providersConfig.providers).length === 0) {
19
- logger.error(
20
- "No providers configured. Run `tenex setup providers` before configuring LLMs."
21
- );
25
+ console.log(chalk.red("āŒ No providers configured."));
26
+ console.log(amber("→") + chalk.bold(" Run tenex setup providers first"));
22
27
  process.exitCode = 1;
23
28
  return;
24
29
  }
25
30
 
26
- const llmManager = new LLMConfigEditor();
31
+ const llmManager = new LLMConfigEditor({ advanced: opts.advanced });
27
32
  await llmManager.showMainMenu();
28
33
  } catch (error: unknown) {
29
34
  // Handle SIGINT (Ctrl+C) gracefully - just exit without error
@@ -32,7 +37,7 @@ export const llmCommand = new Command("llm")
32
37
  return;
33
38
  }
34
39
  // Only show error for actual problems
35
- logger.error(`Failed to start LLM configuration: ${error}`);
40
+ console.log(chalk.red(`āŒ Failed to start LLM configuration: ${error}`));
36
41
  process.exitCode = 1;
37
42
  }
38
43
  });