morpheus-cli 0.1.4 → 0.1.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 (40) hide show
  1. package/README.md +266 -211
  2. package/bin/morpheus.js +30 -0
  3. package/dist/channels/telegram.js +11 -3
  4. package/dist/cli/commands/config.js +18 -3
  5. package/dist/cli/commands/init.js +3 -3
  6. package/dist/cli/index.js +4 -0
  7. package/dist/config/mcp-loader.js +42 -0
  8. package/dist/config/schemas.js +16 -0
  9. package/dist/http/__tests__/auth.test.js +53 -0
  10. package/dist/http/api.js +12 -0
  11. package/dist/http/middleware/auth.js +23 -0
  12. package/dist/http/server.js +2 -1
  13. package/dist/runtime/__tests__/agent.test.js +8 -4
  14. package/dist/runtime/__tests__/agent_memory_limit.test.js +61 -0
  15. package/dist/runtime/__tests__/agent_persistence.test.js +1 -1
  16. package/dist/runtime/__tests__/manual_start_verify.js +4 -0
  17. package/dist/runtime/agent.js +84 -9
  18. package/dist/runtime/audio-agent.js +11 -1
  19. package/dist/runtime/display.js +12 -0
  20. package/dist/runtime/memory/sqlite.js +142 -9
  21. package/dist/runtime/providers/factory.js +50 -6
  22. package/dist/runtime/scaffold.js +5 -0
  23. package/dist/runtime/tools/__tests__/factory.test.js +42 -0
  24. package/dist/runtime/tools/__tests__/tools.test.js +127 -0
  25. package/dist/runtime/tools/analytics-tools.js +73 -0
  26. package/dist/runtime/tools/config-tools.js +70 -0
  27. package/dist/runtime/tools/diagnostic-tools.js +124 -0
  28. package/dist/runtime/tools/factory.js +78 -0
  29. package/dist/runtime/tools/index.js +4 -0
  30. package/dist/types/auth.js +4 -0
  31. package/dist/types/config.js +4 -0
  32. package/dist/types/mcp.js +11 -0
  33. package/dist/types/tools.js +2 -0
  34. package/dist/types/usage.js +1 -0
  35. package/dist/ui/assets/index-4kQpg2wK.js +50 -0
  36. package/dist/ui/assets/index-CwL7mn36.css +1 -0
  37. package/dist/ui/index.html +2 -2
  38. package/package.json +5 -2
  39. package/dist/ui/assets/index-Az60Fu0M.js +0 -50
  40. package/dist/ui/assets/index-nNle8n-Z.css +0 -1
@@ -0,0 +1,124 @@
1
+ import { tool } from "langchain";
2
+ import * as z from "zod";
3
+ import { ConfigManager } from "../../config/manager.js";
4
+ import { promises as fsPromises } from "fs";
5
+ import path from "path";
6
+ import { homedir } from "os";
7
+ // Tool for performing system diagnostics
8
+ export const DiagnosticTool = tool(async () => {
9
+ try {
10
+ const timestamp = new Date().toISOString();
11
+ const components = {};
12
+ // Check configuration
13
+ try {
14
+ const configManager = ConfigManager.getInstance();
15
+ await configManager.load();
16
+ const config = configManager.get();
17
+ // Basic validation - check if required fields exist
18
+ const requiredFields = ['llm', 'logging', 'ui'];
19
+ const missingFields = requiredFields.filter(field => !(field in config));
20
+ if (missingFields.length === 0) {
21
+ components.config = {
22
+ status: "healthy",
23
+ message: "Configuration is valid and complete",
24
+ details: {
25
+ llmProvider: config.llm?.provider,
26
+ uiEnabled: config.ui?.enabled,
27
+ uiPort: config.ui?.port
28
+ }
29
+ };
30
+ }
31
+ else {
32
+ components.config = {
33
+ status: "warning",
34
+ message: `Missing required configuration fields: ${missingFields.join(', ')}`,
35
+ details: { missingFields }
36
+ };
37
+ }
38
+ }
39
+ catch (error) {
40
+ components.config = {
41
+ status: "error",
42
+ message: `Configuration error: ${error.message}`,
43
+ details: {}
44
+ };
45
+ }
46
+ // Check storage/database
47
+ try {
48
+ // For now, we'll check if the data directory exists
49
+ const dbPath = path.join(homedir(), ".morpheus", "memory", "short-memory.db");
50
+ await fsPromises.access(dbPath);
51
+ components.storage = {
52
+ status: "healthy",
53
+ message: "Database file is accessible",
54
+ details: { path: dbPath }
55
+ };
56
+ }
57
+ catch (error) {
58
+ components.storage = {
59
+ status: "error",
60
+ message: `Storage error: ${error.message}`,
61
+ details: {}
62
+ };
63
+ }
64
+ // Check network connectivity (basic check)
65
+ try {
66
+ // For now, we'll just check if we can reach the LLM provider configuration
67
+ const configManager = ConfigManager.getInstance();
68
+ await configManager.load();
69
+ const config = configManager.get();
70
+ if (config.llm && config.llm.provider) {
71
+ components.network = {
72
+ status: "healthy",
73
+ message: `LLM provider configured: ${config.llm.provider}`,
74
+ details: { provider: config.llm.provider }
75
+ };
76
+ }
77
+ else {
78
+ components.network = {
79
+ status: "warning",
80
+ message: "No LLM provider configured",
81
+ details: {}
82
+ };
83
+ }
84
+ }
85
+ catch (error) {
86
+ components.network = {
87
+ status: "error",
88
+ message: `Network check error: ${error.message}`,
89
+ details: {}
90
+ };
91
+ }
92
+ // Check if the agent is running
93
+ try {
94
+ // This is a basic check - in a real implementation, we might check if the agent process is running
95
+ components.agent = {
96
+ status: "healthy",
97
+ message: "Agent is running",
98
+ details: { uptime: "N/A - runtime information not available in this context" }
99
+ };
100
+ }
101
+ catch (error) {
102
+ components.agent = {
103
+ status: "error",
104
+ message: `Agent check error: ${error.message}`,
105
+ details: {}
106
+ };
107
+ }
108
+ return JSON.stringify({
109
+ timestamp,
110
+ components
111
+ });
112
+ }
113
+ catch (error) {
114
+ console.error("Error in DiagnosticTool:", error);
115
+ return JSON.stringify({
116
+ timestamp: new Date().toISOString(),
117
+ error: "Failed to run diagnostics"
118
+ });
119
+ }
120
+ }, {
121
+ name: "diagnostic_check",
122
+ description: "Performs system health diagnostics and returns a comprehensive report on system components.",
123
+ schema: z.object({}),
124
+ });
@@ -0,0 +1,78 @@
1
+ import { MultiServerMCPClient } from "@langchain/mcp-adapters";
2
+ import { DisplayManager } from "../display.js";
3
+ import { loadMCPConfig } from "../../config/mcp-loader.js";
4
+ const display = DisplayManager.getInstance();
5
+ // Fields not supported by Google Gemini API
6
+ const UNSUPPORTED_SCHEMA_FIELDS = ['examples', 'additionalInfo', 'default', '$schema'];
7
+ /**
8
+ * Recursively removes unsupported fields from JSON schema objects.
9
+ * This is needed because some MCP servers (like Coolify) return schemas
10
+ * with fields that Gemini doesn't accept.
11
+ */
12
+ function sanitizeSchema(obj) {
13
+ if (obj === null || typeof obj !== 'object') {
14
+ return obj;
15
+ }
16
+ if (Array.isArray(obj)) {
17
+ return obj.map(sanitizeSchema);
18
+ }
19
+ const sanitized = {};
20
+ for (const [key, value] of Object.entries(obj)) {
21
+ if (!UNSUPPORTED_SCHEMA_FIELDS.includes(key)) {
22
+ sanitized[key] = sanitizeSchema(value);
23
+ }
24
+ }
25
+ return sanitized;
26
+ }
27
+ /**
28
+ * Wraps a tool to sanitize its schema for Gemini compatibility.
29
+ * Creates a proxy that intercepts schema access and sanitizes the output.
30
+ */
31
+ function wrapToolWithSanitizedSchema(tool) {
32
+ display.log('Tool loaded: - ' + tool.name, { source: 'ToolsFactory' });
33
+ // The MCP tools have a schema property that returns JSON Schema
34
+ // We need to intercept and sanitize it
35
+ const originalSchema = tool.schema;
36
+ if (originalSchema && typeof originalSchema === 'object') {
37
+ // Sanitize the schema object directly
38
+ const sanitized = sanitizeSchema(originalSchema);
39
+ tool.schema = sanitized;
40
+ }
41
+ return tool;
42
+ }
43
+ export class ToolsFactory {
44
+ static async create() {
45
+ const display = DisplayManager.getInstance();
46
+ const mcpServers = await loadMCPConfig();
47
+ const serverCount = Object.keys(mcpServers).length;
48
+ if (serverCount === 0) {
49
+ display.log('No MCP servers configured in mcps.json', { level: 'info', source: 'ToolsFactory' });
50
+ return [];
51
+ }
52
+ const client = new MultiServerMCPClient({
53
+ mcpServers: mcpServers,
54
+ onConnectionError: "ignore",
55
+ // log the MCP client's internal events
56
+ beforeToolCall: ({ serverName, name, args }) => {
57
+ display.log(`MCP Tool Call - Server: ${serverName}, Tool: ${name}, Args: ${JSON.stringify(args)}`, { source: 'MCPServer' });
58
+ return;
59
+ },
60
+ // log the results of tool calls
61
+ afterToolCall: (res) => {
62
+ display.log(`MCP Tool Result - ${JSON.stringify(res)}`, { source: 'MCPServer' });
63
+ return;
64
+ }
65
+ });
66
+ try {
67
+ const tools = await client.getTools();
68
+ // Sanitize tool schemas to remove fields not supported by Gemini
69
+ const sanitizedTools = tools.map(tool => wrapToolWithSanitizedSchema(tool));
70
+ display.log(`Loaded ${sanitizedTools.length} MCP tools (schemas sanitized for Gemini compatibility)`, { level: 'info', source: 'ToolsFactory' });
71
+ return sanitizedTools;
72
+ }
73
+ catch (error) {
74
+ display.log(`Failed to initialize MCP tools: ${error}`, { level: 'warning', source: 'ToolsFactory' });
75
+ return []; // Return empty tools on failure to allow agent to start
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,4 @@
1
+ // Export all tools from the tools module
2
+ export * from './config-tools.js';
3
+ export * from './diagnostic-tools.js';
4
+ export * from './analytics-tools.js';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Shared constants and interfaces for HTTP Authentication
3
+ */
4
+ export const AUTH_HEADER = 'x-architect-pass';
@@ -9,10 +9,14 @@ export const DEFAULT_CONFIG = {
9
9
  retention: '14d',
10
10
  },
11
11
  audio: {
12
+ provider: 'google',
12
13
  enabled: true,
13
14
  maxDurationSeconds: 300,
14
15
  supportedMimeTypes: ['audio/ogg', 'audio/mp3', 'audio/mpeg', 'audio/wav'],
15
16
  },
17
+ memory: {
18
+ limit: 100
19
+ },
16
20
  llm: {
17
21
  provider: 'openai',
18
22
  model: 'gpt-4',
@@ -0,0 +1,11 @@
1
+ export const DEFAULT_MCP_TEMPLATE = {
2
+ "_comment": "MCP Server Configuration for Morpheus",
3
+ "_docs": "Add your MCP servers below. Each key is a unique server name.",
4
+ "example": {
5
+ "_comment": "EXAMPLE - Remove or replace this entry with your own MCPs",
6
+ "transport": "stdio",
7
+ "command": "npx",
8
+ "args": ["-y", "your-mcp-package-name"],
9
+ "env": {}
10
+ }
11
+ };
@@ -0,0 +1,2 @@
1
+ // Tool type definitions for Morpheus internal tools
2
+ export {};
@@ -0,0 +1 @@
1
+ export {};