agent-consultation-mcp 1.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.
Files changed (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +140 -0
  3. package/dist/api/index.d.ts +27 -0
  4. package/dist/api/index.js +213 -0
  5. package/dist/api/index.js.map +1 -0
  6. package/dist/api/middleware/security.d.ts +6 -0
  7. package/dist/api/middleware/security.js +28 -0
  8. package/dist/api/middleware/security.js.map +1 -0
  9. package/dist/api/routes/chat.d.ts +2 -0
  10. package/dist/api/routes/chat.js +61 -0
  11. package/dist/api/routes/chat.js.map +1 -0
  12. package/dist/api/routes/config.d.ts +2 -0
  13. package/dist/api/routes/config.js +81 -0
  14. package/dist/api/routes/config.js.map +1 -0
  15. package/dist/api/routes/providers.d.ts +2 -0
  16. package/dist/api/routes/providers.js +225 -0
  17. package/dist/api/routes/providers.js.map +1 -0
  18. package/dist/api/standalone-server.d.ts +12 -0
  19. package/dist/api/standalone-server.js +91 -0
  20. package/dist/api/standalone-server.js.map +1 -0
  21. package/dist/config/defaults.d.ts +17 -0
  22. package/dist/config/defaults.js +30 -0
  23. package/dist/config/defaults.js.map +1 -0
  24. package/dist/config/encryption.d.ts +12 -0
  25. package/dist/config/encryption.js +85 -0
  26. package/dist/config/encryption.js.map +1 -0
  27. package/dist/config/index.d.ts +5 -0
  28. package/dist/config/index.js +6 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/manager.d.ts +62 -0
  31. package/dist/config/manager.js +186 -0
  32. package/dist/config/manager.js.map +1 -0
  33. package/dist/config/prompts.d.ts +10 -0
  34. package/dist/config/prompts.js +140 -0
  35. package/dist/config/prompts.js.map +1 -0
  36. package/dist/config/schema.d.ts +141 -0
  37. package/dist/config/schema.js +54 -0
  38. package/dist/config/schema.js.map +1 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.js +224 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/providers/base.d.ts +44 -0
  43. package/dist/providers/base.js +84 -0
  44. package/dist/providers/base.js.map +1 -0
  45. package/dist/providers/deepseek.d.ts +30 -0
  46. package/dist/providers/deepseek.js +148 -0
  47. package/dist/providers/deepseek.js.map +1 -0
  48. package/dist/providers/index.d.ts +5 -0
  49. package/dist/providers/index.js +8 -0
  50. package/dist/providers/index.js.map +1 -0
  51. package/dist/providers/openai.d.ts +30 -0
  52. package/dist/providers/openai.js +123 -0
  53. package/dist/providers/openai.js.map +1 -0
  54. package/dist/providers/registry.d.ts +37 -0
  55. package/dist/providers/registry.js +65 -0
  56. package/dist/providers/registry.js.map +1 -0
  57. package/dist/providers/types.d.ts +71 -0
  58. package/dist/providers/types.js +2 -0
  59. package/dist/providers/types.js.map +1 -0
  60. package/dist/server/conversation.d.ts +101 -0
  61. package/dist/server/conversation.js +275 -0
  62. package/dist/server/conversation.js.map +1 -0
  63. package/dist/server/index.d.ts +2 -0
  64. package/dist/server/index.js +3 -0
  65. package/dist/server/index.js.map +1 -0
  66. package/dist/server/tools/consult.d.ts +15 -0
  67. package/dist/server/tools/consult.js +164 -0
  68. package/dist/server/tools/consult.js.map +1 -0
  69. package/dist/server/tools/index.d.ts +1 -0
  70. package/dist/server/tools/index.js +2 -0
  71. package/dist/server/tools/index.js.map +1 -0
  72. package/dist/types/config.d.ts +20 -0
  73. package/dist/types/config.js +2 -0
  74. package/dist/types/config.js.map +1 -0
  75. package/dist/types/index.d.ts +3 -0
  76. package/dist/types/index.js +4 -0
  77. package/dist/types/index.js.map +1 -0
  78. package/dist/types/messages.d.ts +48 -0
  79. package/dist/types/messages.js +2 -0
  80. package/dist/types/messages.js.map +1 -0
  81. package/dist/types/models.d.ts +39 -0
  82. package/dist/types/models.js +66 -0
  83. package/dist/types/models.js.map +1 -0
  84. package/dist/ui/index.html +1044 -0
  85. package/dist/utils/errors.d.ts +32 -0
  86. package/dist/utils/errors.js +53 -0
  87. package/dist/utils/errors.js.map +1 -0
  88. package/dist/utils/index.d.ts +2 -0
  89. package/dist/utils/index.js +3 -0
  90. package/dist/utils/index.js.map +1 -0
  91. package/dist/utils/logger.d.ts +13 -0
  92. package/dist/utils/logger.js +73 -0
  93. package/dist/utils/logger.js.map +1 -0
  94. package/package.json +65 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Menes Ekinci
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # Agent Consultation MCP
2
+
3
+ An MCP (Model Context Protocol) server that allows AI agents like Claude Code to consult other AI models (DeepSeek Reasoner, OpenAI GPT-5.2) for alternative perspectives during coding sessions.
4
+
5
+ ## Features
6
+
7
+ - **Multi-Provider Support**: DeepSeek (Reasoner, Chat) and OpenAI (GPT-5.2, GPT-5.2 Pro)
8
+ - **Specialized Consultation Modes**: Debug, Code Analysis, Architecture Review, Plan Validation, Concept Explanation
9
+ - **Conversation Management**: Continue multi-turn conversations with context
10
+ - **Web UI**: Configure providers and API keys through a browser interface
11
+ - **Encrypted Storage**: API keys are encrypted at rest
12
+
13
+ ## Installation
14
+
15
+ ### Via npx (Recommended)
16
+
17
+ No installation required - just add to your Claude Code MCP settings:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "agent-consultation": {
23
+ "command": "npx",
24
+ "args": ["-y", "agent-consultation-mcp"]
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ ### Global Installation
31
+
32
+ ```bash
33
+ npm install -g agent-consultation-mcp
34
+ ```
35
+
36
+ Then add to your MCP settings:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "agent-consultation": {
42
+ "command": "agent-consultation-mcp"
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ ## Configuration
49
+
50
+ ### Setting Up API Keys
51
+
52
+ 1. **Via Web UI** (Recommended):
53
+ ```bash
54
+ npx agent-consultation-mcp --config
55
+ ```
56
+ This opens a browser where you can configure providers and API keys.
57
+
58
+ 2. **Via Config File**:
59
+ Config is stored at `~/.agent-consultation-mcp/config.json`
60
+
61
+ ### Supported Providers
62
+
63
+ | Provider | Models | API Key |
64
+ |----------|--------|---------|
65
+ | DeepSeek | `deepseek-reasoner` (default), `deepseek-chat` | [Get API Key](https://platform.deepseek.com/) |
66
+ | OpenAI | `gpt-5.2`, `gpt-5.2-pro` | [Get API Key](https://platform.openai.com/) |
67
+
68
+ ## Usage
69
+
70
+ Once configured, Claude Code can use the following tools:
71
+
72
+ ### consult_agent
73
+
74
+ Get a second opinion from another AI model.
75
+
76
+ ```
77
+ Parameters:
78
+ - question (required): The question or problem to get advice on
79
+ - mode (optional): Consultation mode - debug, analyzeCode, reviewArchitecture, validatePlan, explainConcept, general
80
+ - context (optional): Additional context like code snippets or error messages
81
+ ```
82
+
83
+ ### continue_conversation
84
+
85
+ Continue an existing consultation conversation.
86
+
87
+ ```
88
+ Parameters:
89
+ - conversationId (required): The conversation ID from a previous consultation
90
+ - message (required): Your follow-up message
91
+ ```
92
+
93
+ ### end_conversation
94
+
95
+ End an active consultation conversation.
96
+
97
+ ```
98
+ Parameters:
99
+ - conversationId (required): The conversation ID to end
100
+ ```
101
+
102
+ ## Example
103
+
104
+ In Claude Code, you might use it like:
105
+
106
+ > "Can you consult DeepSeek about this architecture decision? I'm not sure if using a monorepo is the right choice for this microservices setup."
107
+
108
+ Claude will then call the `consult_agent` tool with your question and provide the response.
109
+
110
+ ## Consultation Modes
111
+
112
+ | Mode | Description |
113
+ |------|-------------|
114
+ | `debug` | Focus on finding bugs, analyzing errors, and suggesting fixes |
115
+ | `analyzeCode` | Code review focusing on quality, patterns, and improvements |
116
+ | `reviewArchitecture` | Evaluate architectural decisions and suggest alternatives |
117
+ | `validatePlan` | Review implementation plans for completeness and risks |
118
+ | `explainConcept` | Explain technical concepts clearly |
119
+ | `general` | General-purpose consultation |
120
+
121
+ ## Development
122
+
123
+ ```bash
124
+ # Clone the repo
125
+ git clone https://github.com/menesekinci/agent-consultation-mcp.git
126
+ cd agent-consultation-mcp
127
+
128
+ # Install dependencies
129
+ npm install
130
+
131
+ # Run in development mode
132
+ npm run dev
133
+
134
+ # Build for production
135
+ npm run build
136
+ ```
137
+
138
+ ## License
139
+
140
+ MIT
@@ -0,0 +1,27 @@
1
+ export interface ConfigUIOptions {
2
+ port?: number;
3
+ openBrowser?: boolean;
4
+ }
5
+ /**
6
+ * Start the configuration UI HTTP server
7
+ */
8
+ export declare function startConfigUI(options?: ConfigUIOptions): Promise<void>;
9
+ /**
10
+ * Start the UI server in background mode (for MCP mode)
11
+ * Does not block and does not open browser automatically
12
+ */
13
+ export declare function startBackgroundUIServer(port?: number): Promise<boolean>;
14
+ /**
15
+ * Open the Web UI in browser (only opens once per session)
16
+ * Spawns a completely separate standalone server process that handles
17
+ * both server startup and browser opening.
18
+ */
19
+ export declare function openWebUI(): Promise<void>;
20
+ /**
21
+ * Check if browser has been opened
22
+ */
23
+ export declare function isBrowserOpened(): boolean;
24
+ /**
25
+ * Check if background server is running
26
+ */
27
+ export declare function isBackgroundServerRunning(): boolean;
@@ -0,0 +1,213 @@
1
+ import express from 'express';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { spawn } from 'child_process';
5
+ import open from 'open';
6
+ import { getConfigManager } from '../config/index.js';
7
+ import { logger } from '../utils/index.js';
8
+ import { configRoutes } from './routes/config.js';
9
+ import { providerRoutes } from './routes/providers.js';
10
+ import chatRoutes from './routes/chat.js';
11
+ import { securityMiddleware } from './middleware/security.js';
12
+ // Get __dirname equivalent in ES modules
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+ const DEFAULT_PORT = 3456;
16
+ // Track background UI server state
17
+ let backgroundServerRunning = false;
18
+ let browserOpened = false;
19
+ let backgroundServerPort = DEFAULT_PORT;
20
+ /**
21
+ * Start the configuration UI HTTP server
22
+ */
23
+ export async function startConfigUI(options = {}) {
24
+ const port = options.port ?? DEFAULT_PORT;
25
+ const shouldOpenBrowser = options.openBrowser ?? true;
26
+ // Ensure config is loaded
27
+ const configManager = getConfigManager();
28
+ await configManager.init();
29
+ const app = express();
30
+ // Middleware
31
+ app.use(express.json());
32
+ app.use(securityMiddleware);
33
+ // API routes
34
+ app.use('/api/config', configRoutes);
35
+ app.use('/api/providers', providerRoutes);
36
+ app.use('/api/chat', chatRoutes);
37
+ // Serve static UI files
38
+ const uiPath = path.join(__dirname, '../ui');
39
+ app.use(express.static(uiPath));
40
+ // Fallback to index.html for SPA-like behavior (Express 5 compatible)
41
+ app.use((_req, res, next) => {
42
+ // Only serve index.html for non-API requests that don't have a file extension
43
+ if (!_req.path.startsWith('/api') && !path.extname(_req.path)) {
44
+ res.sendFile(path.join(uiPath, 'index.html'));
45
+ }
46
+ else {
47
+ next();
48
+ }
49
+ });
50
+ // Error handling middleware
51
+ app.use((err, _req, res, _next) => {
52
+ logger.error('HTTP server error', { error: err.message });
53
+ res.status(500).json({
54
+ error: 'Internal server error',
55
+ message: err.message,
56
+ });
57
+ });
58
+ // CRITICAL: Bind to localhost only for security
59
+ return new Promise((resolve, reject) => {
60
+ const server = app.listen(port, '127.0.0.1', () => {
61
+ const url = `http://127.0.0.1:${port}`;
62
+ logger.info(`Config UI running at ${url}`);
63
+ console.log(`
64
+ ┌─────────────────────────────────────────────────┐
65
+ │ │
66
+ │ Agent Consultation MCP - Configuration UI │
67
+ │ │
68
+ │ URL: ${url.padEnd(40)}│
69
+ │ │
70
+ │ Press Ctrl+C to stop │
71
+ │ │
72
+ └─────────────────────────────────────────────────┘
73
+ `);
74
+ // Open browser
75
+ if (shouldOpenBrowser) {
76
+ open(url).catch((err) => {
77
+ logger.warn('Failed to open browser', { error: err.message });
78
+ console.log(`Please open ${url} in your browser`);
79
+ });
80
+ }
81
+ resolve();
82
+ });
83
+ server.on('error', (err) => {
84
+ if (err.code === 'EADDRINUSE') {
85
+ logger.error(`Port ${port} is already in use`);
86
+ console.error(`\nError: Port ${port} is already in use.`);
87
+ console.error(`Try a different port: npx agent-consultation-mcp --config --port ${port + 1}\n`);
88
+ }
89
+ reject(err);
90
+ });
91
+ });
92
+ }
93
+ /**
94
+ * Start the UI server in background mode (for MCP mode)
95
+ * Does not block and does not open browser automatically
96
+ */
97
+ export async function startBackgroundUIServer(port = DEFAULT_PORT) {
98
+ if (backgroundServerRunning) {
99
+ return true;
100
+ }
101
+ // Ensure config is loaded
102
+ const configManager = getConfigManager();
103
+ await configManager.init();
104
+ const app = express();
105
+ // Middleware
106
+ app.use(express.json());
107
+ app.use(securityMiddleware);
108
+ // API routes
109
+ app.use('/api/config', configRoutes);
110
+ app.use('/api/providers', providerRoutes);
111
+ app.use('/api/chat', chatRoutes);
112
+ // Serve static UI files
113
+ const uiPath = path.join(__dirname, '../ui');
114
+ app.use(express.static(uiPath));
115
+ // Fallback to index.html for SPA-like behavior
116
+ app.use((_req, res, next) => {
117
+ if (!_req.path.startsWith('/api') && !path.extname(_req.path)) {
118
+ res.sendFile(path.join(uiPath, 'index.html'));
119
+ }
120
+ else {
121
+ next();
122
+ }
123
+ });
124
+ // Error handling middleware
125
+ app.use((err, _req, res, _next) => {
126
+ logger.error('Background HTTP server error', { error: err.message });
127
+ res.status(500).json({
128
+ error: 'Internal server error',
129
+ message: err.message,
130
+ });
131
+ });
132
+ return new Promise((resolve) => {
133
+ const server = app.listen(port, '127.0.0.1', () => {
134
+ backgroundServerRunning = true;
135
+ backgroundServerPort = port;
136
+ logger.info(`Background UI server started at http://127.0.0.1:${port}`);
137
+ resolve(true);
138
+ });
139
+ server.on('error', (err) => {
140
+ if (err.code === 'EADDRINUSE') {
141
+ // Port is in use, maybe server is already running from another process
142
+ logger.debug(`Port ${port} already in use, assuming UI server is running`);
143
+ backgroundServerRunning = true;
144
+ backgroundServerPort = port;
145
+ resolve(true);
146
+ }
147
+ else {
148
+ logger.error('Failed to start background UI server', { error: err.message });
149
+ resolve(false);
150
+ }
151
+ });
152
+ });
153
+ }
154
+ /**
155
+ * Open the Web UI in browser (only opens once per session)
156
+ * Spawns a completely separate standalone server process that handles
157
+ * both server startup and browser opening.
158
+ */
159
+ export async function openWebUI() {
160
+ logger.info('openWebUI called', { browserOpened });
161
+ if (browserOpened) {
162
+ logger.info('Browser already opened, skipping');
163
+ return;
164
+ }
165
+ // Path to the standalone server script
166
+ const standaloneServerPath = path.join(__dirname, 'standalone-server.js');
167
+ logger.info('Spawning standalone server process', { standaloneServerPath });
168
+ try {
169
+ // Spawn a completely detached process
170
+ // This process will start the server AND open the browser
171
+ const child = spawn(process.execPath, [standaloneServerPath, String(backgroundServerPort)], {
172
+ detached: true,
173
+ stdio: 'ignore',
174
+ windowsHide: true,
175
+ env: { ...process.env }
176
+ });
177
+ // Unref to allow parent (MCP) process to exit independently
178
+ child.unref();
179
+ browserOpened = true;
180
+ backgroundServerRunning = true;
181
+ logger.info('Standalone server process spawned successfully');
182
+ }
183
+ catch (err) {
184
+ logger.error('Failed to spawn standalone server process', {
185
+ error: err instanceof Error ? err.message : 'Unknown error'
186
+ });
187
+ // Fallback: try to open browser directly (server might already be running)
188
+ const url = `http://127.0.0.1:${backgroundServerPort}`;
189
+ try {
190
+ await open(url, { wait: false });
191
+ browserOpened = true;
192
+ logger.info('Browser opened via fallback');
193
+ }
194
+ catch (openErr) {
195
+ logger.error('Fallback browser open also failed', {
196
+ error: openErr instanceof Error ? openErr.message : 'Unknown error'
197
+ });
198
+ }
199
+ }
200
+ }
201
+ /**
202
+ * Check if browser has been opened
203
+ */
204
+ export function isBrowserOpened() {
205
+ return browserOpened;
206
+ }
207
+ /**
208
+ * Check if background server is running
209
+ */
210
+ export function isBackgroundServerRunning() {
211
+ return backgroundServerRunning;
212
+ }
213
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Request, Response, NextFunction } from 'express';
2
+ /**
3
+ * Security middleware for the config UI HTTP server
4
+ * Adds security headers to all responses
5
+ */
6
+ export declare function securityMiddleware(_req: Request, res: Response, next: NextFunction): void;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Security middleware for the config UI HTTP server
3
+ * Adds security headers to all responses
4
+ */
5
+ export function securityMiddleware(_req, res, next) {
6
+ // Prevent MIME type sniffing
7
+ res.setHeader('X-Content-Type-Options', 'nosniff');
8
+ // Prevent clickjacking
9
+ res.setHeader('X-Frame-Options', 'DENY');
10
+ // Enable XSS filter in browsers
11
+ res.setHeader('X-XSS-Protection', '1; mode=block');
12
+ // Content Security Policy - allow CDN resources for Alpine.js and Tailwind
13
+ // Note: 'unsafe-eval' is required for Alpine.js to evaluate expressions
14
+ // This is acceptable since the UI runs on localhost only
15
+ res.setHeader('Content-Security-Policy', [
16
+ "default-src 'self'",
17
+ "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.tailwindcss.com https://unpkg.com",
18
+ "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
19
+ "img-src 'self' data:",
20
+ "font-src 'self' https://fonts.gstatic.com",
21
+ "connect-src 'self'",
22
+ ].join('; '));
23
+ // Prevent caching of sensitive data
24
+ res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
25
+ res.setHeader('Pragma', 'no-cache');
26
+ next();
27
+ }
28
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/api/middleware/security.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAa,EACb,GAAa,EACb,IAAkB;IAElB,6BAA6B;IAC7B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;IAEnD,uBAAuB;IACvB,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAEzC,gCAAgC;IAChC,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;IAEnD,2EAA2E;IAC3E,wEAAwE;IACxE,yDAAyD;IACzD,GAAG,CAAC,SAAS,CACX,yBAAyB,EACzB;QACE,oBAAoB;QACpB,+FAA+F;QAC/F,+DAA+D;QAC/D,sBAAsB;QACtB,2CAA2C;QAC3C,oBAAoB;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,oCAAoC;IACpC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,qCAAqC,CAAC,CAAC;IACtE,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAEpC,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,61 @@
1
+ import { Router } from 'express';
2
+ import { ConversationManager } from '../../server/conversation.js';
3
+ const router = Router();
4
+ /**
5
+ * GET /api/chat/history
6
+ * Returns all conversations (active + archived) from files
7
+ */
8
+ router.get('/history', (_req, res) => {
9
+ try {
10
+ // Load active conversations
11
+ const activeConversations = ConversationManager.loadFromFile();
12
+ // Load archived conversations
13
+ const archivedConversations = ConversationManager.loadHistoryFromFile();
14
+ // Format active conversations for UI display
15
+ const active = activeConversations.map((conv) => ({
16
+ id: conv.id,
17
+ model: conv.model,
18
+ messageCount: conv.messages.length,
19
+ messages: conv.messages.map((msg, idx) => ({
20
+ id: `${conv.id}-${idx}`,
21
+ role: msg.role,
22
+ content: msg.content,
23
+ })),
24
+ createdAt: conv.createdAt.toISOString(),
25
+ lastActivityAt: conv.lastActivityAt.toISOString(),
26
+ status: 'active',
27
+ }));
28
+ // Format archived conversations for UI display
29
+ const archived = archivedConversations.map((conv) => ({
30
+ id: conv.id,
31
+ model: conv.model,
32
+ messageCount: conv.messages.length,
33
+ messages: conv.messages.map((msg, idx) => ({
34
+ id: `${conv.id}-${idx}`,
35
+ role: msg.role,
36
+ content: msg.content,
37
+ })),
38
+ createdAt: conv.createdAt,
39
+ lastActivityAt: conv.lastActivityAt,
40
+ endedAt: conv.endedAt,
41
+ endReason: conv.endReason,
42
+ status: 'archived',
43
+ }));
44
+ // Combine: active first, then archived (already sorted by newest first)
45
+ const allConversations = [...active, ...archived];
46
+ res.json({
47
+ count: allConversations.length,
48
+ activeCount: active.length,
49
+ archivedCount: archived.length,
50
+ conversations: allConversations,
51
+ });
52
+ }
53
+ catch (error) {
54
+ res.status(500).json({
55
+ error: 'Failed to fetch conversation history',
56
+ message: error instanceof Error ? error.message : 'Unknown error',
57
+ });
58
+ }
59
+ });
60
+ export default router;
61
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../src/api/routes/chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAgD,MAAM,8BAA8B,CAAC;AAGjH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAa,EAAE,GAAa,EAAE,EAAE;IACtD,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,YAAY,EAAE,CAAC;QAE/D,8BAA8B;QAC9B,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,mBAAmB,EAAE,CAAC;QAExE,6CAA6C;QAC7C,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAkB,EAAE,EAAE,CAAC,CAAC;YAC9D,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,GAAW,EAAE,EAAE,CAAC,CAAC;gBAC1D,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE;gBACvB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC;YACH,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;YACvC,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE;YACjD,MAAM,EAAE,QAAiB;SAC1B,CAAC,CAAC,CAAC;QAEJ,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC,IAA0B,EAAE,EAAE,CAAC,CAAC;YAC1E,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,GAAW,EAAE,EAAE,CAAC,CAAC;gBAC1D,EAAE,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE;gBACvB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC;YACH,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,MAAM,EAAE,UAAmB;SAC5B,CAAC,CAAC,CAAC;QAEJ,wEAAwE;QACxE,MAAM,gBAAgB,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC;QAElD,GAAG,CAAC,IAAI,CAAC;YACP,KAAK,EAAE,gBAAgB,CAAC,MAAM;YAC9B,WAAW,EAAE,MAAM,CAAC,MAAM;YAC1B,aAAa,EAAE,QAAQ,CAAC,MAAM;YAC9B,aAAa,EAAE,gBAAgB;SAChC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,sCAAsC;YAC7C,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAClE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export { router as configRoutes };
@@ -0,0 +1,81 @@
1
+ import { Router } from 'express';
2
+ import { getConfigManager } from '../../config/index.js';
3
+ import { MODEL_TYPES } from '../../types/index.js';
4
+ const router = Router();
5
+ /**
6
+ * GET /api/config - Get current configuration (with masked keys)
7
+ */
8
+ router.get('/', (_req, res) => {
9
+ try {
10
+ const config = getConfigManager().getConfig();
11
+ // Build safe response with masked keys
12
+ const safeConfig = {
13
+ defaultModel: config.defaultModel,
14
+ maxMessages: config.maxMessages,
15
+ availableModels: MODEL_TYPES,
16
+ providers: Object.fromEntries(Object.entries(config.providers).map(([id, cfg]) => [
17
+ id,
18
+ {
19
+ enabled: cfg.enabled,
20
+ hasKey: !!cfg.apiKey,
21
+ },
22
+ ])),
23
+ };
24
+ res.json(safeConfig);
25
+ }
26
+ catch (error) {
27
+ res.status(500).json({
28
+ error: 'Failed to get configuration',
29
+ message: error instanceof Error ? error.message : 'Unknown error',
30
+ });
31
+ }
32
+ });
33
+ /**
34
+ * PATCH /api/config - Update configuration (defaultModel, maxMessages)
35
+ */
36
+ router.patch('/', async (req, res) => {
37
+ try {
38
+ const { defaultModel, maxMessages } = req.body;
39
+ const updates = {};
40
+ // Validate defaultModel
41
+ if (defaultModel !== undefined) {
42
+ if (!MODEL_TYPES.includes(defaultModel)) {
43
+ res.status(400).json({
44
+ error: 'Invalid model',
45
+ message: `Model must be one of: ${MODEL_TYPES.join(', ')}`,
46
+ });
47
+ return;
48
+ }
49
+ updates.defaultModel = defaultModel;
50
+ }
51
+ // Validate maxMessages
52
+ if (maxMessages !== undefined) {
53
+ const num = parseInt(maxMessages, 10);
54
+ if (isNaN(num) || num < 1 || num > 50) {
55
+ res.status(400).json({
56
+ error: 'Invalid maxMessages',
57
+ message: 'maxMessages must be between 1 and 50',
58
+ });
59
+ return;
60
+ }
61
+ updates.maxMessages = num;
62
+ }
63
+ if (Object.keys(updates).length === 0) {
64
+ res.status(400).json({
65
+ error: 'No updates provided',
66
+ message: 'Provide at least one of: defaultModel, maxMessages',
67
+ });
68
+ return;
69
+ }
70
+ await getConfigManager().update(updates);
71
+ res.json({ success: true, updated: updates });
72
+ }
73
+ catch (error) {
74
+ res.status(500).json({
75
+ error: 'Failed to update configuration',
76
+ message: error instanceof Error ? error.message : 'Unknown error',
77
+ });
78
+ }
79
+ });
80
+ export { router as configRoutes };
81
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/api/routes/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export { router as providerRoutes };