ai-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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +193 -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 +78 -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 +117 -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 +210 -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 +168 -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 +260 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/installer/detector.d.ts +48 -0
  43. package/dist/installer/detector.js +164 -0
  44. package/dist/installer/detector.js.map +1 -0
  45. package/dist/installer/index.d.ts +7 -0
  46. package/dist/installer/index.js +10 -0
  47. package/dist/installer/index.js.map +1 -0
  48. package/dist/installer/installer.d.ts +16 -0
  49. package/dist/installer/installer.js +262 -0
  50. package/dist/installer/installer.js.map +1 -0
  51. package/dist/installer/tools.d.ts +16 -0
  52. package/dist/installer/tools.js +327 -0
  53. package/dist/installer/tools.js.map +1 -0
  54. package/dist/installer/types.d.ts +68 -0
  55. package/dist/installer/types.js +5 -0
  56. package/dist/installer/types.js.map +1 -0
  57. package/dist/providers/base.d.ts +44 -0
  58. package/dist/providers/base.js +84 -0
  59. package/dist/providers/base.js.map +1 -0
  60. package/dist/providers/deepseek.d.ts +30 -0
  61. package/dist/providers/deepseek.js +148 -0
  62. package/dist/providers/deepseek.js.map +1 -0
  63. package/dist/providers/index.d.ts +5 -0
  64. package/dist/providers/index.js +8 -0
  65. package/dist/providers/index.js.map +1 -0
  66. package/dist/providers/openai.d.ts +30 -0
  67. package/dist/providers/openai.js +123 -0
  68. package/dist/providers/openai.js.map +1 -0
  69. package/dist/providers/registry.d.ts +37 -0
  70. package/dist/providers/registry.js +65 -0
  71. package/dist/providers/registry.js.map +1 -0
  72. package/dist/providers/types.d.ts +71 -0
  73. package/dist/providers/types.js +2 -0
  74. package/dist/providers/types.js.map +1 -0
  75. package/dist/server/conversation.d.ts +105 -0
  76. package/dist/server/conversation.js +279 -0
  77. package/dist/server/conversation.js.map +1 -0
  78. package/dist/server/index.d.ts +2 -0
  79. package/dist/server/index.js +3 -0
  80. package/dist/server/index.js.map +1 -0
  81. package/dist/server/tools/consult.d.ts +15 -0
  82. package/dist/server/tools/consult.js +164 -0
  83. package/dist/server/tools/consult.js.map +1 -0
  84. package/dist/server/tools/index.d.ts +1 -0
  85. package/dist/server/tools/index.js +2 -0
  86. package/dist/server/tools/index.js.map +1 -0
  87. package/dist/types/config.d.ts +20 -0
  88. package/dist/types/config.js +2 -0
  89. package/dist/types/config.js.map +1 -0
  90. package/dist/types/index.d.ts +3 -0
  91. package/dist/types/index.js +4 -0
  92. package/dist/types/index.js.map +1 -0
  93. package/dist/types/messages.d.ts +48 -0
  94. package/dist/types/messages.js +2 -0
  95. package/dist/types/messages.js.map +1 -0
  96. package/dist/types/models.d.ts +39 -0
  97. package/dist/types/models.js +66 -0
  98. package/dist/types/models.js.map +1 -0
  99. package/dist/ui/index.html +1244 -0
  100. package/dist/utils/errors.d.ts +32 -0
  101. package/dist/utils/errors.js +53 -0
  102. package/dist/utils/errors.js.map +1 -0
  103. package/dist/utils/index.d.ts +2 -0
  104. package/dist/utils/index.js +3 -0
  105. package/dist/utils/index.js.map +1 -0
  106. package/dist/utils/logger.d.ts +13 -0
  107. package/dist/utils/logger.js +73 -0
  108. package/dist/utils/logger.js.map +1 -0
  109. package/package.json +65 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Tool configuration types for multi-tool installer
3
+ */
4
+ export type Platform = 'darwin' | 'win32' | 'linux';
5
+ export interface ToolConfigPath {
6
+ /** Path relative to home directory or absolute */
7
+ path: string;
8
+ /** Whether path is relative to home directory */
9
+ relative: boolean;
10
+ /** JSON key path to mcpServers object (e.g., "mcpServers" or "context_servers") */
11
+ mcpKey: string;
12
+ /** Config format */
13
+ format: 'json' | 'yaml';
14
+ }
15
+ export interface ToolDefinition {
16
+ /** Tool identifier */
17
+ id: string;
18
+ /** Display name */
19
+ name: string;
20
+ /** Tool description */
21
+ description: string;
22
+ /** Config paths per platform */
23
+ configPaths: Partial<Record<Platform, ToolConfigPath>>;
24
+ /** Detection methods */
25
+ detection: {
26
+ /** Check if binary exists in PATH */
27
+ binary?: string;
28
+ /** Check if directory exists (relative to home) */
29
+ directory?: string;
30
+ /** Check if config file exists */
31
+ configFile?: boolean;
32
+ /** VSCode extension ID to check */
33
+ vscodeExtension?: string;
34
+ };
35
+ /** MCP server configuration to add */
36
+ mcpConfig: {
37
+ /** Server name in config */
38
+ serverName: string;
39
+ /** Command to run */
40
+ command: string;
41
+ /** Command arguments */
42
+ args: string[];
43
+ };
44
+ /** Whether tool requires restart after installation */
45
+ requiresRestart: boolean;
46
+ /** Installation notes/instructions */
47
+ notes?: string;
48
+ }
49
+ export interface DetectedTool {
50
+ tool: ToolDefinition;
51
+ installed: boolean;
52
+ configExists: boolean;
53
+ mcpAlreadyInstalled: boolean;
54
+ configPath: string;
55
+ }
56
+ export interface InstallResult {
57
+ tool: ToolDefinition;
58
+ success: boolean;
59
+ message: string;
60
+ configPath?: string;
61
+ error?: string;
62
+ }
63
+ export interface InstallSummary {
64
+ detected: DetectedTool[];
65
+ installed: InstallResult[];
66
+ skipped: DetectedTool[];
67
+ errors: InstallResult[];
68
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Tool configuration types for multi-tool installer
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/installer/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,44 @@
1
+ import type { ProviderType } from '../types/index.js';
2
+ import type { IProvider, ProviderMessage, CompletionOptions, ProviderResponse, ProviderErrorInfo } from './types.js';
3
+ /**
4
+ * Custom error class for provider errors
5
+ */
6
+ export declare class ProviderError extends Error {
7
+ readonly info: ProviderErrorInfo;
8
+ constructor(info: ProviderErrorInfo);
9
+ }
10
+ /**
11
+ * Abstract base class for all providers
12
+ */
13
+ export declare abstract class BaseProvider implements IProvider {
14
+ abstract readonly name: ProviderType;
15
+ /**
16
+ * Get the API key for this provider
17
+ */
18
+ protected getApiKey(): string | undefined;
19
+ /**
20
+ * Check if the provider is configured
21
+ */
22
+ isConfigured(): boolean;
23
+ /**
24
+ * Create a chat completion - must be implemented by subclasses
25
+ */
26
+ abstract createCompletion(messages: ProviderMessage[], options: CompletionOptions): Promise<ProviderResponse>;
27
+ /**
28
+ * Format system prompt for models that don't support it directly
29
+ * Prepends system prompt to the first user message
30
+ */
31
+ protected formatSystemPromptAsUser(messages: ProviderMessage[], systemPrompt?: string): ProviderMessage[];
32
+ /**
33
+ * Log completion request
34
+ */
35
+ protected logRequest(model: string, messageCount: number, options: CompletionOptions): void;
36
+ /**
37
+ * Log completion response
38
+ */
39
+ protected logResponse(response: ProviderResponse): void;
40
+ /**
41
+ * Create a standardized provider error
42
+ */
43
+ protected createError(code: string, message: string, retryable: boolean, statusCode?: number): ProviderError;
44
+ }
@@ -0,0 +1,84 @@
1
+ import { getConfigManager } from '../config/index.js';
2
+ import { logger } from '../utils/index.js';
3
+ /**
4
+ * Custom error class for provider errors
5
+ */
6
+ export class ProviderError extends Error {
7
+ info;
8
+ constructor(info) {
9
+ super(info.message);
10
+ this.name = 'ProviderError';
11
+ this.info = info;
12
+ }
13
+ }
14
+ /**
15
+ * Abstract base class for all providers
16
+ */
17
+ export class BaseProvider {
18
+ /**
19
+ * Get the API key for this provider
20
+ */
21
+ getApiKey() {
22
+ return getConfigManager().getProviderKey(this.name);
23
+ }
24
+ /**
25
+ * Check if the provider is configured
26
+ */
27
+ isConfigured() {
28
+ return getConfigManager().isProviderConfigured(this.name);
29
+ }
30
+ /**
31
+ * Format system prompt for models that don't support it directly
32
+ * Prepends system prompt to the first user message
33
+ */
34
+ formatSystemPromptAsUser(messages, systemPrompt) {
35
+ if (!systemPrompt)
36
+ return messages;
37
+ const result = [...messages];
38
+ const firstUserIndex = result.findIndex((m) => m.role === 'user');
39
+ if (firstUserIndex >= 0) {
40
+ result[firstUserIndex] = {
41
+ ...result[firstUserIndex],
42
+ content: `[System Instructions]\n${systemPrompt}\n\n[User Query]\n${result[firstUserIndex].content}`,
43
+ };
44
+ }
45
+ return result;
46
+ }
47
+ /**
48
+ * Log completion request
49
+ */
50
+ logRequest(model, messageCount, options) {
51
+ logger.info('Provider completion request', {
52
+ provider: this.name,
53
+ model,
54
+ messageCount,
55
+ maxTokens: options.maxTokens,
56
+ hasSystemPrompt: !!options.systemPrompt,
57
+ });
58
+ }
59
+ /**
60
+ * Log completion response
61
+ */
62
+ logResponse(response) {
63
+ logger.info('Provider completion response', {
64
+ provider: this.name,
65
+ model: response.model,
66
+ finishReason: response.finishReason,
67
+ usage: response.usage,
68
+ hasReasoningContent: !!response.reasoningContent,
69
+ });
70
+ }
71
+ /**
72
+ * Create a standardized provider error
73
+ */
74
+ createError(code, message, retryable, statusCode) {
75
+ return new ProviderError({
76
+ provider: this.name,
77
+ code,
78
+ message,
79
+ retryable,
80
+ statusCode,
81
+ });
82
+ }
83
+ }
84
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAoB;IAEjC,YAAY,IAAuB;QACjC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAgB,YAAY;IAGhC;;OAEG;IACO,SAAS;QACjB,OAAO,gBAAgB,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,gBAAgB,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAUD;;;OAGG;IACO,wBAAwB,CAChC,QAA2B,EAC3B,YAAqB;QAErB,IAAI,CAAC,YAAY;YAAE,OAAO,QAAQ,CAAC;QAEnC,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC7B,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAElE,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,cAAc,CAAC,GAAG;gBACvB,GAAG,MAAM,CAAC,cAAc,CAAC;gBACzB,OAAO,EAAE,0BAA0B,YAAY,qBAAqB,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE;aACrG,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACO,UAAU,CAClB,KAAa,EACb,YAAoB,EACpB,OAA0B;QAE1B,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;YACzC,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,KAAK;YACL,YAAY;YACZ,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY;SACxC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACO,WAAW,CAAC,QAA0B;QAC9C,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC1C,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,mBAAmB,EAAE,CAAC,CAAC,QAAQ,CAAC,gBAAgB;SACjD,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACO,WAAW,CACnB,IAAY,EACZ,OAAe,EACf,SAAkB,EAClB,UAAmB;QAEnB,OAAO,IAAI,aAAa,CAAC;YACvB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,IAAI;YACJ,OAAO;YACP,SAAS;YACT,UAAU;SACX,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import type { ProviderType } from '../types/index.js';
2
+ import type { ProviderMessage, CompletionOptions, ProviderResponse } from './types.js';
3
+ import { BaseProvider } from './base.js';
4
+ /**
5
+ * DeepSeek Provider - Uses OpenAI-compatible SDK
6
+ */
7
+ export declare class DeepSeekProvider extends BaseProvider {
8
+ readonly name: ProviderType;
9
+ private client;
10
+ /**
11
+ * Get or create the OpenAI-compatible client for DeepSeek
12
+ */
13
+ private getClient;
14
+ /**
15
+ * Check if a model is a reasoning model
16
+ */
17
+ private isReasoningModel;
18
+ /**
19
+ * Check if a model supports system prompts
20
+ */
21
+ private supportsSystemPrompt;
22
+ /**
23
+ * Get the actual API model ID
24
+ */
25
+ private getApiModel;
26
+ /**
27
+ * Create a chat completion
28
+ */
29
+ createCompletion(messages: ProviderMessage[], options: CompletionOptions): Promise<ProviderResponse>;
30
+ }
@@ -0,0 +1,148 @@
1
+ import OpenAI from 'openai';
2
+ import { MODEL_CONFIG } from '../types/index.js';
3
+ import { BaseProvider } from './base.js';
4
+ import { logger } from '../utils/index.js';
5
+ /**
6
+ * DeepSeek API base URL
7
+ */
8
+ const DEEPSEEK_BASE_URL = 'https://api.deepseek.com';
9
+ /**
10
+ * DeepSeek Provider - Uses OpenAI-compatible SDK
11
+ */
12
+ export class DeepSeekProvider extends BaseProvider {
13
+ name = 'deepseek';
14
+ client = null;
15
+ /**
16
+ * Get or create the OpenAI-compatible client for DeepSeek
17
+ */
18
+ getClient() {
19
+ if (!this.client) {
20
+ const apiKey = this.getApiKey();
21
+ if (!apiKey) {
22
+ throw this.createError('AUTH_ERROR', 'DeepSeek API key not configured', false);
23
+ }
24
+ this.client = new OpenAI({
25
+ apiKey,
26
+ baseURL: DEEPSEEK_BASE_URL,
27
+ });
28
+ }
29
+ return this.client;
30
+ }
31
+ /**
32
+ * Check if a model is a reasoning model
33
+ */
34
+ isReasoningModel(model) {
35
+ const config = MODEL_CONFIG[model];
36
+ return config?.isReasoning ?? false;
37
+ }
38
+ /**
39
+ * Check if a model supports system prompts
40
+ */
41
+ supportsSystemPrompt(model) {
42
+ const config = MODEL_CONFIG[model];
43
+ return config?.supportsSystemPrompt ?? true;
44
+ }
45
+ /**
46
+ * Get the actual API model ID
47
+ */
48
+ getApiModel(model) {
49
+ const config = MODEL_CONFIG[model];
50
+ return config?.apiModel ?? model;
51
+ }
52
+ /**
53
+ * Create a chat completion
54
+ */
55
+ async createCompletion(messages, options) {
56
+ const client = this.getClient();
57
+ const apiModel = this.getApiModel(options.model);
58
+ const isReasoning = this.isReasoningModel(options.model);
59
+ const supportsSystem = this.supportsSystemPrompt(options.model);
60
+ this.logRequest(apiModel, messages.length, options);
61
+ const startTime = Date.now();
62
+ try {
63
+ // Build messages array
64
+ let chatMessages = [];
65
+ // Handle system prompt
66
+ if (options.systemPrompt) {
67
+ if (supportsSystem) {
68
+ chatMessages.push({
69
+ role: 'system',
70
+ content: options.systemPrompt,
71
+ });
72
+ }
73
+ else {
74
+ // For reasoning models, prepend to first user message
75
+ messages = this.formatSystemPromptAsUser(messages, options.systemPrompt);
76
+ }
77
+ }
78
+ // Add conversation messages
79
+ chatMessages.push(...messages.map((m) => ({
80
+ role: m.role,
81
+ content: m.content,
82
+ })));
83
+ // Build request parameters
84
+ const requestParams = {
85
+ model: apiModel,
86
+ messages: chatMessages,
87
+ };
88
+ // Handle token limits differently for reasoning models
89
+ if (isReasoning) {
90
+ // Reasoning models use max_completion_tokens
91
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
+ requestParams.max_completion_tokens =
93
+ options.maxTokens || 4096;
94
+ // DeepSeek reasoner: temperature must be 0
95
+ requestParams.temperature = 0;
96
+ }
97
+ else {
98
+ // Standard models use max_tokens
99
+ requestParams.max_tokens = options.maxTokens || 4096;
100
+ // Set temperature for non-reasoning models
101
+ if (options.temperature !== undefined) {
102
+ requestParams.temperature = options.temperature;
103
+ }
104
+ }
105
+ const response = await client.chat.completions.create(requestParams);
106
+ const choice = response.choices[0];
107
+ const content = choice?.message?.content || '';
108
+ // Extract reasoning content if present (DeepSeek Reasoner specific)
109
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
+ const reasoningContent = choice?.message
111
+ ?.reasoning_content;
112
+ const responseTime = Date.now() - startTime;
113
+ if (reasoningContent) {
114
+ logger.debug('Reasoning content received', {
115
+ model: apiModel,
116
+ reasoningLength: reasoningContent.length,
117
+ thinkingTime: responseTime,
118
+ });
119
+ }
120
+ const result = {
121
+ content,
122
+ model: response.model,
123
+ usage: response.usage
124
+ ? {
125
+ promptTokens: response.usage.prompt_tokens,
126
+ completionTokens: response.usage.completion_tokens,
127
+ totalTokens: response.usage.total_tokens,
128
+ }
129
+ : undefined,
130
+ finishReason: choice?.finish_reason || undefined,
131
+ reasoningContent,
132
+ responseTime,
133
+ };
134
+ this.logResponse(result);
135
+ return result;
136
+ }
137
+ catch (error) {
138
+ if (error instanceof OpenAI.APIError) {
139
+ const retryable = error.status === 429 ||
140
+ error.status === 500 ||
141
+ error.status === 503;
142
+ throw this.createError(error.code || 'API_ERROR', error.message, retryable, error.status);
143
+ }
144
+ throw error;
145
+ }
146
+ }
147
+ }
148
+ //# sourceMappingURL=deepseek.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepseek.js","sourceRoot":"","sources":["../../src/providers/deepseek.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAMjD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C;;GAEG;AACH,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAErD;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IACvC,IAAI,GAAiB,UAAU,CAAC;IACjC,MAAM,GAAkB,IAAI,CAAC;IAErC;;OAEG;IACK,SAAS;QACf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,CAAC,WAAW,CACpB,YAAY,EACZ,iCAAiC,EACjC,KAAK,CACN,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;gBACvB,MAAM;gBACN,OAAO,EAAE,iBAAiB;aAC3B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,KAAa;QACpC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAkB,CAAC,CAAC;QAChD,OAAO,MAAM,EAAE,WAAW,IAAI,KAAK,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,KAAa;QACxC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAkB,CAAC,CAAC;QAChD,OAAO,MAAM,EAAE,oBAAoB,IAAI,IAAI,CAAC;IAC9C,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,KAAa;QAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,KAAkB,CAAC,CAAC;QAChD,OAAO,MAAM,EAAE,QAAQ,IAAI,KAAK,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CACpB,QAA2B,EAC3B,OAA0B;QAE1B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEhE,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEpD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,uBAAuB;YACvB,IAAI,YAAY,GAA6C,EAAE,CAAC;YAEhE,uBAAuB;YACvB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,IAAI,cAAc,EAAE,CAAC;oBACnB,YAAY,CAAC,IAAI,CAAC;wBAChB,IAAI,EAAE,QAAQ;wBACd,OAAO,EAAE,OAAO,CAAC,YAAY;qBAC9B,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,sDAAsD;oBACtD,QAAQ,GAAG,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC;YAED,4BAA4B;YAC5B,YAAY,CAAC,IAAI,CACf,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtB,IAAI,EAAE,CAAC,CAAC,IAA4B;gBACpC,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC,CACJ,CAAC;YAEF,2BAA2B;YAC3B,MAAM,aAAa,GAA2C;gBAC5D,KAAK,EAAE,QAAQ;gBACf,QAAQ,EAAE,YAAY;aACvB,CAAC;YAEF,uDAAuD;YACvD,IAAI,WAAW,EAAE,CAAC;gBAChB,6CAA6C;gBAC7C,8DAA8D;gBAC7D,aAAqB,CAAC,qBAAqB;oBAC1C,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;gBAC5B,2CAA2C;gBAC3C,aAAa,CAAC,WAAW,GAAG,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,iCAAiC;gBACjC,aAAa,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;gBACrD,2CAA2C;gBAC3C,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;oBACtC,aAAa,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;gBAClD,CAAC;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAErE,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;YAE/C,oEAAoE;YACpE,8DAA8D;YAC9D,MAAM,gBAAgB,GAAI,MAAM,EAAE,OAAe;gBAC/C,EAAE,iBAAuC,CAAC;YAE5C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAE5C,IAAI,gBAAgB,EAAE,CAAC;gBACrB,MAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE;oBACzC,KAAK,EAAE,QAAQ;oBACf,eAAe,EAAE,gBAAgB,CAAC,MAAM;oBACxC,YAAY,EAAE,YAAY;iBAC3B,CAAC,CAAC;YACL,CAAC;YAED,MAAM,MAAM,GAAqB;gBAC/B,OAAO;gBACP,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACnB,CAAC,CAAC;wBACE,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa;wBAC1C,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,iBAAiB;wBAClD,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY;qBACzC;oBACH,CAAC,CAAC,SAAS;gBACb,YAAY,EAAE,MAAM,EAAE,aAAa,IAAI,SAAS;gBAChD,gBAAgB;gBAChB,YAAY;aACb,CAAC;YAEF,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACrC,MAAM,SAAS,GACb,KAAK,CAAC,MAAM,KAAK,GAAG;oBACpB,KAAK,CAAC,MAAM,KAAK,GAAG;oBACpB,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC;gBAEvB,MAAM,IAAI,CAAC,WAAW,CACpB,KAAK,CAAC,IAAI,IAAI,WAAW,EACzB,KAAK,CAAC,OAAO,EACb,SAAS,EACT,KAAK,CAAC,MAAM,CACb,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ export type { IProvider, ProviderMessage, CompletionOptions, ProviderResponse, TokenUsage, ProviderErrorInfo, ModelConfig, } from './types.js';
2
+ export { BaseProvider, ProviderError } from './base.js';
3
+ export { ProviderRegistry, getProviderRegistry, initializeProviders, } from './registry.js';
4
+ export { DeepSeekProvider } from './deepseek.js';
5
+ export { OpenAIProvider } from './openai.js';
@@ -0,0 +1,8 @@
1
+ // Base
2
+ export { BaseProvider, ProviderError } from './base.js';
3
+ // Registry
4
+ export { ProviderRegistry, getProviderRegistry, initializeProviders, } from './registry.js';
5
+ // Providers
6
+ export { DeepSeekProvider } from './deepseek.js';
7
+ export { OpenAIProvider } from './openai.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAWA,OAAO;AACP,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAExD,WAAW;AACX,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { ProviderType } from '../types/index.js';
2
+ import type { ProviderMessage, CompletionOptions, ProviderResponse } from './types.js';
3
+ import { BaseProvider } from './base.js';
4
+ /**
5
+ * OpenAI Provider - GPT-5.2 models
6
+ */
7
+ export declare class OpenAIProvider extends BaseProvider {
8
+ readonly name: ProviderType;
9
+ private client;
10
+ /**
11
+ * Get or create the OpenAI client
12
+ */
13
+ private getClient;
14
+ /**
15
+ * Check if a model is a reasoning model
16
+ */
17
+ private isReasoningModel;
18
+ /**
19
+ * Get reasoning effort for the model
20
+ */
21
+ private getReasoningEffort;
22
+ /**
23
+ * Get the actual API model ID
24
+ */
25
+ private getApiModel;
26
+ /**
27
+ * Create a chat completion
28
+ */
29
+ createCompletion(messages: ProviderMessage[], options: CompletionOptions): Promise<ProviderResponse>;
30
+ }
@@ -0,0 +1,123 @@
1
+ import OpenAI from 'openai';
2
+ import { MODEL_CONFIG } from '../types/index.js';
3
+ import { BaseProvider } from './base.js';
4
+ import { logger } from '../utils/index.js';
5
+ /**
6
+ * OpenAI Provider - GPT-5.2 models
7
+ */
8
+ export class OpenAIProvider extends BaseProvider {
9
+ name = 'openai';
10
+ client = null;
11
+ /**
12
+ * Get or create the OpenAI client
13
+ */
14
+ getClient() {
15
+ if (!this.client) {
16
+ const apiKey = this.getApiKey();
17
+ if (!apiKey) {
18
+ throw this.createError('AUTH_ERROR', 'OpenAI API key not configured', false);
19
+ }
20
+ this.client = new OpenAI({
21
+ apiKey,
22
+ });
23
+ }
24
+ return this.client;
25
+ }
26
+ /**
27
+ * Check if a model is a reasoning model
28
+ */
29
+ isReasoningModel(model) {
30
+ const config = MODEL_CONFIG[model];
31
+ return config?.isReasoning ?? false;
32
+ }
33
+ /**
34
+ * Get reasoning effort for the model
35
+ */
36
+ getReasoningEffort(model) {
37
+ const config = MODEL_CONFIG[model];
38
+ return config?.reasoningEffort;
39
+ }
40
+ /**
41
+ * Get the actual API model ID
42
+ */
43
+ getApiModel(model) {
44
+ const config = MODEL_CONFIG[model];
45
+ return config?.apiModel ?? model;
46
+ }
47
+ /**
48
+ * Create a chat completion
49
+ */
50
+ async createCompletion(messages, options) {
51
+ const client = this.getClient();
52
+ const apiModel = this.getApiModel(options.model);
53
+ const isReasoning = this.isReasoningModel(options.model);
54
+ const reasoningEffort = this.getReasoningEffort(options.model);
55
+ this.logRequest(apiModel, messages.length, options);
56
+ const startTime = Date.now();
57
+ try {
58
+ // Build messages array
59
+ const chatMessages = [];
60
+ // Add system prompt if provided
61
+ if (options.systemPrompt) {
62
+ chatMessages.push({
63
+ role: 'system',
64
+ content: options.systemPrompt,
65
+ });
66
+ }
67
+ // Add conversation messages
68
+ chatMessages.push(...messages.map((m) => ({
69
+ role: m.role,
70
+ content: m.content,
71
+ })));
72
+ // Build request parameters
73
+ const requestParams = {
74
+ model: apiModel,
75
+ messages: chatMessages,
76
+ max_tokens: options.maxTokens || 4096,
77
+ };
78
+ // Add reasoning effort for GPT-5.2 models
79
+ if (isReasoning && reasoningEffort) {
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ requestParams.reasoning_effort = reasoningEffort;
82
+ }
83
+ // Set temperature for non-reasoning or if specified
84
+ if (options.temperature !== undefined) {
85
+ requestParams.temperature = options.temperature;
86
+ }
87
+ const response = await client.chat.completions.create(requestParams);
88
+ const choice = response.choices[0];
89
+ const content = choice?.message?.content || '';
90
+ const responseTime = Date.now() - startTime;
91
+ logger.debug('OpenAI response received', {
92
+ model: apiModel,
93
+ responseTime,
94
+ finishReason: choice?.finish_reason,
95
+ });
96
+ const result = {
97
+ content,
98
+ model: response.model,
99
+ usage: response.usage
100
+ ? {
101
+ promptTokens: response.usage.prompt_tokens,
102
+ completionTokens: response.usage.completion_tokens,
103
+ totalTokens: response.usage.total_tokens,
104
+ }
105
+ : undefined,
106
+ finishReason: choice?.finish_reason || undefined,
107
+ responseTime,
108
+ };
109
+ this.logResponse(result);
110
+ return result;
111
+ }
112
+ catch (error) {
113
+ if (error instanceof OpenAI.APIError) {
114
+ const retryable = error.status === 429 ||
115
+ error.status === 500 ||
116
+ error.status === 503;
117
+ throw this.createError(error.code || 'API_ERROR', error.message, retryable, error.status);
118
+ }
119
+ throw error;
120
+ }
121
+ }
122
+ }
123
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ProviderType } from '../types/index.js';
2
+ import type { IProvider } from './types.js';
3
+ /**
4
+ * Registry for managing provider instances
5
+ */
6
+ export declare class ProviderRegistry {
7
+ private providers;
8
+ /**
9
+ * Register a provider
10
+ */
11
+ register(provider: IProvider): void;
12
+ /**
13
+ * Get a provider by name
14
+ */
15
+ getProvider(name: ProviderType): IProvider;
16
+ /**
17
+ * Check if a provider exists
18
+ */
19
+ hasProvider(name: ProviderType): boolean;
20
+ /**
21
+ * Get all registered providers
22
+ */
23
+ getAllProviders(): IProvider[];
24
+ /**
25
+ * Get all configured providers
26
+ */
27
+ getConfiguredProviders(): IProvider[];
28
+ }
29
+ /**
30
+ * Get the provider registry instance
31
+ */
32
+ export declare function getProviderRegistry(): ProviderRegistry;
33
+ /**
34
+ * Initialize the registry with all providers
35
+ * Called during server startup
36
+ */
37
+ export declare function initializeProviders(): Promise<void>;