@mainwp/control 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 (204) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +583 -0
  3. package/bin/_exit.js +12 -0
  4. package/bin/dev.js +7 -0
  5. package/bin/run.js +7 -0
  6. package/dist/chat/chat-engine.d.ts +213 -0
  7. package/dist/chat/chat-engine.d.ts.map +1 -0
  8. package/dist/chat/chat-engine.js +636 -0
  9. package/dist/chat/chat-engine.js.map +1 -0
  10. package/dist/chat/index.d.ts +10 -0
  11. package/dist/chat/index.d.ts.map +1 -0
  12. package/dist/chat/index.js +14 -0
  13. package/dist/chat/index.js.map +1 -0
  14. package/dist/chat/providers/anthropic.d.ts +52 -0
  15. package/dist/chat/providers/anthropic.d.ts.map +1 -0
  16. package/dist/chat/providers/anthropic.js +292 -0
  17. package/dist/chat/providers/anthropic.js.map +1 -0
  18. package/dist/chat/providers/gemini.d.ts +52 -0
  19. package/dist/chat/providers/gemini.d.ts.map +1 -0
  20. package/dist/chat/providers/gemini.js +284 -0
  21. package/dist/chat/providers/gemini.js.map +1 -0
  22. package/dist/chat/providers/index.d.ts +19 -0
  23. package/dist/chat/providers/index.d.ts.map +1 -0
  24. package/dist/chat/providers/index.js +23 -0
  25. package/dist/chat/providers/index.js.map +1 -0
  26. package/dist/chat/providers/local.d.ts +37 -0
  27. package/dist/chat/providers/local.d.ts.map +1 -0
  28. package/dist/chat/providers/local.js +130 -0
  29. package/dist/chat/providers/local.js.map +1 -0
  30. package/dist/chat/providers/openai-compatible.d.ts +155 -0
  31. package/dist/chat/providers/openai-compatible.d.ts.map +1 -0
  32. package/dist/chat/providers/openai-compatible.js +264 -0
  33. package/dist/chat/providers/openai-compatible.js.map +1 -0
  34. package/dist/chat/providers/openai.d.ts +24 -0
  35. package/dist/chat/providers/openai.d.ts.map +1 -0
  36. package/dist/chat/providers/openai.js +62 -0
  37. package/dist/chat/providers/openai.js.map +1 -0
  38. package/dist/chat/providers/openrouter.d.ts +26 -0
  39. package/dist/chat/providers/openrouter.d.ts.map +1 -0
  40. package/dist/chat/providers/openrouter.js +65 -0
  41. package/dist/chat/providers/openrouter.js.map +1 -0
  42. package/dist/chat/providers/provider-fetch.d.ts +15 -0
  43. package/dist/chat/providers/provider-fetch.d.ts.map +1 -0
  44. package/dist/chat/providers/provider-fetch.js +35 -0
  45. package/dist/chat/providers/provider-fetch.js.map +1 -0
  46. package/dist/chat/providers/provider.d.ts +214 -0
  47. package/dist/chat/providers/provider.d.ts.map +1 -0
  48. package/dist/chat/providers/provider.js +166 -0
  49. package/dist/chat/providers/provider.js.map +1 -0
  50. package/dist/chat/providers/sse-reader.d.ts +21 -0
  51. package/dist/chat/providers/sse-reader.d.ts.map +1 -0
  52. package/dist/chat/providers/sse-reader.js +48 -0
  53. package/dist/chat/providers/sse-reader.js.map +1 -0
  54. package/dist/chat/system-prompt.d.ts +33 -0
  55. package/dist/chat/system-prompt.d.ts.map +1 -0
  56. package/dist/chat/system-prompt.js +166 -0
  57. package/dist/chat/system-prompt.js.map +1 -0
  58. package/dist/chat/tool-envelope.d.ts +72 -0
  59. package/dist/chat/tool-envelope.d.ts.map +1 -0
  60. package/dist/chat/tool-envelope.js +263 -0
  61. package/dist/chat/tool-envelope.js.map +1 -0
  62. package/dist/commands/abilities/info.d.ts +21 -0
  63. package/dist/commands/abilities/info.d.ts.map +1 -0
  64. package/dist/commands/abilities/info.js +80 -0
  65. package/dist/commands/abilities/info.js.map +1 -0
  66. package/dist/commands/abilities/list.d.ts +19 -0
  67. package/dist/commands/abilities/list.d.ts.map +1 -0
  68. package/dist/commands/abilities/list.js +98 -0
  69. package/dist/commands/abilities/list.js.map +1 -0
  70. package/dist/commands/abilities/run.d.ts +75 -0
  71. package/dist/commands/abilities/run.d.ts.map +1 -0
  72. package/dist/commands/abilities/run.js +468 -0
  73. package/dist/commands/abilities/run.js.map +1 -0
  74. package/dist/commands/chat.d.ts +54 -0
  75. package/dist/commands/chat.d.ts.map +1 -0
  76. package/dist/commands/chat.js +384 -0
  77. package/dist/commands/chat.js.map +1 -0
  78. package/dist/commands/config/show.d.ts +54 -0
  79. package/dist/commands/config/show.d.ts.map +1 -0
  80. package/dist/commands/config/show.js +324 -0
  81. package/dist/commands/config/show.js.map +1 -0
  82. package/dist/commands/doctor.d.ts +77 -0
  83. package/dist/commands/doctor.d.ts.map +1 -0
  84. package/dist/commands/doctor.js +412 -0
  85. package/dist/commands/doctor.js.map +1 -0
  86. package/dist/commands/jobs/watch.d.ts +50 -0
  87. package/dist/commands/jobs/watch.d.ts.map +1 -0
  88. package/dist/commands/jobs/watch.js +269 -0
  89. package/dist/commands/jobs/watch.js.map +1 -0
  90. package/dist/commands/login.d.ts +25 -0
  91. package/dist/commands/login.d.ts.map +1 -0
  92. package/dist/commands/login.js +165 -0
  93. package/dist/commands/login.js.map +1 -0
  94. package/dist/commands/profile/delete.d.ts +22 -0
  95. package/dist/commands/profile/delete.d.ts.map +1 -0
  96. package/dist/commands/profile/delete.js +57 -0
  97. package/dist/commands/profile/delete.js.map +1 -0
  98. package/dist/commands/profile/list.d.ts +19 -0
  99. package/dist/commands/profile/list.d.ts.map +1 -0
  100. package/dist/commands/profile/list.js +53 -0
  101. package/dist/commands/profile/list.js.map +1 -0
  102. package/dist/commands/profile/use.d.ts +22 -0
  103. package/dist/commands/profile/use.d.ts.map +1 -0
  104. package/dist/commands/profile/use.js +46 -0
  105. package/dist/commands/profile/use.js.map +1 -0
  106. package/dist/config/fs-utils.d.ts +14 -0
  107. package/dist/config/fs-utils.d.ts.map +1 -0
  108. package/dist/config/fs-utils.js +31 -0
  109. package/dist/config/fs-utils.js.map +1 -0
  110. package/dist/config/keychain.d.ts +53 -0
  111. package/dist/config/keychain.d.ts.map +1 -0
  112. package/dist/config/keychain.js +175 -0
  113. package/dist/config/keychain.js.map +1 -0
  114. package/dist/config/profile-store.d.ts +85 -0
  115. package/dist/config/profile-store.d.ts.map +1 -0
  116. package/dist/config/profile-store.js +228 -0
  117. package/dist/config/profile-store.js.map +1 -0
  118. package/dist/config/settings.d.ts +71 -0
  119. package/dist/config/settings.d.ts.map +1 -0
  120. package/dist/config/settings.js +151 -0
  121. package/dist/config/settings.js.map +1 -0
  122. package/dist/core/abilities-executor.d.ts +126 -0
  123. package/dist/core/abilities-executor.d.ts.map +1 -0
  124. package/dist/core/abilities-executor.js +264 -0
  125. package/dist/core/abilities-executor.js.map +1 -0
  126. package/dist/core/batch-manager.d.ts +113 -0
  127. package/dist/core/batch-manager.d.ts.map +1 -0
  128. package/dist/core/batch-manager.js +244 -0
  129. package/dist/core/batch-manager.js.map +1 -0
  130. package/dist/core/http-client.d.ts +111 -0
  131. package/dist/core/http-client.d.ts.map +1 -0
  132. package/dist/core/http-client.js +329 -0
  133. package/dist/core/http-client.js.map +1 -0
  134. package/dist/core/safety-controller.d.ts +114 -0
  135. package/dist/core/safety-controller.d.ts.map +1 -0
  136. package/dist/core/safety-controller.js +229 -0
  137. package/dist/core/safety-controller.js.map +1 -0
  138. package/dist/hooks/command-not-found.d.ts +12 -0
  139. package/dist/hooks/command-not-found.d.ts.map +1 -0
  140. package/dist/hooks/command-not-found.js +58 -0
  141. package/dist/hooks/command-not-found.js.map +1 -0
  142. package/dist/index.d.ts +7 -0
  143. package/dist/index.d.ts.map +1 -0
  144. package/dist/index.js +7 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/lib/base-command.d.ts +123 -0
  147. package/dist/lib/base-command.d.ts.map +1 -0
  148. package/dist/lib/base-command.js +285 -0
  149. package/dist/lib/base-command.js.map +1 -0
  150. package/dist/output/formatter.d.ts +48 -0
  151. package/dist/output/formatter.d.ts.map +1 -0
  152. package/dist/output/formatter.js +138 -0
  153. package/dist/output/formatter.js.map +1 -0
  154. package/dist/output/json-envelope.d.ts +43 -0
  155. package/dist/output/json-envelope.d.ts.map +1 -0
  156. package/dist/output/json-envelope.js +73 -0
  157. package/dist/output/json-envelope.js.map +1 -0
  158. package/dist/utils/audit-logger.d.ts +97 -0
  159. package/dist/utils/audit-logger.d.ts.map +1 -0
  160. package/dist/utils/audit-logger.js +169 -0
  161. package/dist/utils/audit-logger.js.map +1 -0
  162. package/dist/utils/colors.d.ts +29 -0
  163. package/dist/utils/colors.d.ts.map +1 -0
  164. package/dist/utils/colors.js +36 -0
  165. package/dist/utils/colors.js.map +1 -0
  166. package/dist/utils/errors.d.ts +107 -0
  167. package/dist/utils/errors.d.ts.map +1 -0
  168. package/dist/utils/errors.js +149 -0
  169. package/dist/utils/errors.js.map +1 -0
  170. package/dist/utils/exit-codes.d.ts +21 -0
  171. package/dist/utils/exit-codes.d.ts.map +1 -0
  172. package/dist/utils/exit-codes.js +20 -0
  173. package/dist/utils/exit-codes.js.map +1 -0
  174. package/dist/utils/format.d.ts +64 -0
  175. package/dist/utils/format.d.ts.map +1 -0
  176. package/dist/utils/format.js +69 -0
  177. package/dist/utils/format.js.map +1 -0
  178. package/dist/utils/prompt.d.ts +34 -0
  179. package/dist/utils/prompt.d.ts.map +1 -0
  180. package/dist/utils/prompt.js +132 -0
  181. package/dist/utils/prompt.js.map +1 -0
  182. package/dist/utils/retry.d.ts +59 -0
  183. package/dist/utils/retry.d.ts.map +1 -0
  184. package/dist/utils/retry.js +96 -0
  185. package/dist/utils/retry.js.map +1 -0
  186. package/dist/utils/terminal-sanitizer.d.ts +60 -0
  187. package/dist/utils/terminal-sanitizer.d.ts.map +1 -0
  188. package/dist/utils/terminal-sanitizer.js +166 -0
  189. package/dist/utils/terminal-sanitizer.js.map +1 -0
  190. package/dist/validation/input-sanitizer.d.ts +76 -0
  191. package/dist/validation/input-sanitizer.d.ts.map +1 -0
  192. package/dist/validation/input-sanitizer.js +199 -0
  193. package/dist/validation/input-sanitizer.js.map +1 -0
  194. package/dist/validation/schema-validator.d.ts +75 -0
  195. package/dist/validation/schema-validator.d.ts.map +1 -0
  196. package/dist/validation/schema-validator.js +147 -0
  197. package/dist/validation/schema-validator.js.map +1 -0
  198. package/oclif.manifest.json +857 -0
  199. package/package.json +101 -0
  200. package/scripts/completions/README.md +221 -0
  201. package/scripts/completions/mainwpcontrol.bash +193 -0
  202. package/scripts/completions/mainwpcontrol.zsh +267 -0
  203. package/scripts/completions/profile-completer.sh +35 -0
  204. package/scripts/completions/regenerate.sh +78 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * OpenAI-Compatible Provider Base Class
3
+ *
4
+ * Abstract base for providers that use the OpenAI chat completions API format:
5
+ * OpenAI, OpenRouter, and local OpenAI-compatible servers (Ollama, LM Studio, etc.)
6
+ */
7
+ import { type LLMProvider, type LLMResponse, type Message, type ChatOptions, type ProviderConfig, type ProviderCapabilities, type StreamChunk } from './provider.js';
8
+ /**
9
+ * OpenAI-compatible API message format
10
+ */
11
+ export interface OpenAICompatibleMessage {
12
+ role: 'system' | 'user' | 'assistant' | 'tool';
13
+ content: string | null;
14
+ tool_calls?: OpenAICompatibleToolCall[];
15
+ tool_call_id?: string;
16
+ }
17
+ /**
18
+ * OpenAI-compatible tool call format
19
+ */
20
+ export interface OpenAICompatibleToolCall {
21
+ id: string;
22
+ type: 'function';
23
+ function: {
24
+ name: string;
25
+ arguments: string;
26
+ };
27
+ }
28
+ /**
29
+ * OpenAI-compatible tool definition format
30
+ */
31
+ export interface OpenAICompatibleTool {
32
+ type: 'function';
33
+ function: {
34
+ name: string;
35
+ description: string;
36
+ parameters: Record<string, unknown>;
37
+ };
38
+ }
39
+ /**
40
+ * OpenAI-compatible API response
41
+ */
42
+ export interface OpenAICompatibleResponse {
43
+ id: string;
44
+ object?: string;
45
+ created?: number;
46
+ model: string;
47
+ choices: Array<{
48
+ index: number;
49
+ message: {
50
+ role: 'assistant';
51
+ content: string | null;
52
+ tool_calls?: OpenAICompatibleToolCall[];
53
+ };
54
+ finish_reason: string;
55
+ }>;
56
+ usage?: {
57
+ prompt_tokens: number;
58
+ completion_tokens: number;
59
+ total_tokens: number;
60
+ };
61
+ }
62
+ /**
63
+ * OpenAI-compatible stream chunk
64
+ */
65
+ export interface OpenAICompatibleStreamChunk {
66
+ id: string;
67
+ object?: string;
68
+ created?: number;
69
+ model: string;
70
+ choices: Array<{
71
+ index: number;
72
+ delta: {
73
+ role?: 'assistant';
74
+ content?: string;
75
+ tool_calls?: Array<{
76
+ index: number;
77
+ id?: string;
78
+ type?: 'function';
79
+ function?: {
80
+ name?: string;
81
+ arguments?: string;
82
+ };
83
+ }>;
84
+ };
85
+ finish_reason: string | null;
86
+ }>;
87
+ }
88
+ /**
89
+ * Abstract base class for OpenAI-compatible LLM providers.
90
+ *
91
+ * Subclasses must implement:
92
+ * - `name` and `capabilities` (readonly properties)
93
+ * - `getHeaders()` — provider-specific auth headers
94
+ * - `getModels()` — available model list
95
+ * - `isConfigured()` — config validation
96
+ *
97
+ * Subclasses may override:
98
+ * - `convertFinishReason()` — if the provider maps finish reasons differently
99
+ * - `chat()` — if the provider needs fallback logic (e.g. local tool embedding)
100
+ * - `getStreamToolCallId()` — if the provider generates tool call IDs differently
101
+ */
102
+ export declare abstract class OpenAICompatibleProvider implements LLMProvider {
103
+ abstract readonly name: string;
104
+ abstract readonly capabilities: ProviderCapabilities;
105
+ protected readonly apiKey: string;
106
+ protected readonly baseUrl: string;
107
+ protected readonly defaultModel: string;
108
+ protected readonly timeout: number;
109
+ constructor(config: ProviderConfig, defaults: {
110
+ baseUrl: string;
111
+ model: string;
112
+ timeout?: number;
113
+ });
114
+ abstract isConfigured(): boolean;
115
+ abstract getModels(): string[];
116
+ protected abstract getHeaders(): Record<string, string>;
117
+ getDefaultModel(): string;
118
+ chat(messages: Message[], options?: ChatOptions): Promise<LLMResponse>;
119
+ chatStream(messages: Message[], options?: ChatOptions): AsyncGenerator<StreamChunk, void, undefined>;
120
+ /**
121
+ * Convert internal messages to OpenAI-compatible format
122
+ */
123
+ protected convertMessages(messages: Message[]): OpenAICompatibleMessage[];
124
+ /**
125
+ * Convert tool definitions to OpenAI-compatible format
126
+ */
127
+ protected convertTools(tools: Array<{
128
+ name: string;
129
+ description: string;
130
+ parameters: Record<string, unknown>;
131
+ }>): OpenAICompatibleTool[];
132
+ /**
133
+ * Convert OpenAI-compatible response to internal format
134
+ */
135
+ protected convertResponse(response: OpenAICompatibleResponse): LLMResponse;
136
+ /**
137
+ * Convert the API finish reason string to the internal LLMResponse finishReason.
138
+ * Override in subclasses if the provider uses different finish reason strings.
139
+ */
140
+ protected convertFinishReason(reason: string): LLMResponse['finishReason'];
141
+ /**
142
+ * Parse tool call arguments JSON
143
+ */
144
+ protected parseArguments(args: string): Record<string, unknown>;
145
+ /**
146
+ * Generate a tool call ID for streaming when the server doesn't provide one.
147
+ * Override in subclasses if needed (e.g. local providers that omit IDs).
148
+ */
149
+ protected getStreamToolCallId(index: number): string;
150
+ /**
151
+ * Make API request with timeout
152
+ */
153
+ protected makeRequest<T>(endpoint: string, body: Record<string, unknown>, signal?: AbortSignal): Promise<T>;
154
+ }
155
+ //# sourceMappingURL=openai-compatible.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-compatible.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/openai-compatible.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,264 @@
1
+ /**
2
+ * OpenAI-Compatible Provider Base Class
3
+ *
4
+ * Abstract base for providers that use the OpenAI chat completions API format:
5
+ * OpenAI, OpenRouter, and local OpenAI-compatible servers (Ollama, LM Studio, etc.)
6
+ */
7
+ import { readSSEStream } from './sse-reader.js';
8
+ /**
9
+ * Abstract base class for OpenAI-compatible LLM providers.
10
+ *
11
+ * Subclasses must implement:
12
+ * - `name` and `capabilities` (readonly properties)
13
+ * - `getHeaders()` — provider-specific auth headers
14
+ * - `getModels()` — available model list
15
+ * - `isConfigured()` — config validation
16
+ *
17
+ * Subclasses may override:
18
+ * - `convertFinishReason()` — if the provider maps finish reasons differently
19
+ * - `chat()` — if the provider needs fallback logic (e.g. local tool embedding)
20
+ * - `getStreamToolCallId()` — if the provider generates tool call IDs differently
21
+ */
22
+ export class OpenAICompatibleProvider {
23
+ apiKey;
24
+ baseUrl;
25
+ defaultModel;
26
+ timeout;
27
+ constructor(config, defaults) {
28
+ this.apiKey = config.apiKey;
29
+ this.baseUrl = config.baseUrl ?? defaults.baseUrl;
30
+ this.defaultModel = config.defaultModel ?? defaults.model;
31
+ this.timeout = config.timeout ?? (defaults.timeout ?? 60000);
32
+ }
33
+ getDefaultModel() {
34
+ return this.defaultModel;
35
+ }
36
+ async chat(messages, options) {
37
+ const model = options?.model ?? this.defaultModel;
38
+ const apiMessages = this.convertMessages(messages);
39
+ const requestBody = {
40
+ model,
41
+ messages: apiMessages,
42
+ };
43
+ if (options?.temperature !== undefined) {
44
+ requestBody['temperature'] = options.temperature;
45
+ }
46
+ if (options?.maxTokens !== undefined) {
47
+ requestBody['max_tokens'] = options.maxTokens;
48
+ }
49
+ if (options?.stop) {
50
+ requestBody['stop'] = options.stop;
51
+ }
52
+ if (options?.tools && options.tools.length > 0) {
53
+ requestBody['tools'] = this.convertTools(options.tools);
54
+ requestBody['tool_choice'] = 'auto';
55
+ }
56
+ const response = await this.makeRequest('/chat/completions', requestBody, options?.signal);
57
+ return this.convertResponse(response);
58
+ }
59
+ async *chatStream(messages, options) {
60
+ const model = options?.model ?? this.defaultModel;
61
+ const apiMessages = this.convertMessages(messages);
62
+ const requestBody = {
63
+ model,
64
+ messages: apiMessages,
65
+ stream: true,
66
+ };
67
+ if (options?.temperature !== undefined) {
68
+ requestBody['temperature'] = options.temperature;
69
+ }
70
+ if (options?.maxTokens !== undefined) {
71
+ requestBody['max_tokens'] = options.maxTokens;
72
+ }
73
+ if (options?.tools && options.tools.length > 0) {
74
+ requestBody['tools'] = this.convertTools(options.tools);
75
+ requestBody['tool_choice'] = 'auto';
76
+ }
77
+ // Track tool calls across chunks
78
+ const toolCalls = new Map();
79
+ for await (const data of readSSEStream({
80
+ url: `${this.baseUrl}/chat/completions`,
81
+ headers: this.getHeaders(),
82
+ body: requestBody,
83
+ signal: options?.signal,
84
+ providerName: this.name,
85
+ })) {
86
+ if (data === '[DONE]') {
87
+ yield { done: true };
88
+ return;
89
+ }
90
+ try {
91
+ const chunk = JSON.parse(data);
92
+ const choice = chunk.choices[0];
93
+ if (!choice)
94
+ continue;
95
+ const delta = choice.delta;
96
+ // Content chunk
97
+ if (delta.content) {
98
+ yield { content: delta.content, done: false };
99
+ }
100
+ // Tool call chunks
101
+ if (delta.tool_calls) {
102
+ for (const tc of delta.tool_calls) {
103
+ const existing = toolCalls.get(tc.index);
104
+ if (!existing) {
105
+ toolCalls.set(tc.index, {
106
+ id: tc.id ?? this.getStreamToolCallId(tc.index),
107
+ name: tc.function?.name ?? '',
108
+ arguments: tc.function?.arguments ?? '',
109
+ });
110
+ }
111
+ else {
112
+ if (tc.function?.arguments) {
113
+ existing.arguments += tc.function.arguments;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ // Final chunk
119
+ if (choice.finish_reason === 'tool_calls') {
120
+ for (const [, tc] of toolCalls) {
121
+ try {
122
+ const args = JSON.parse(tc.arguments);
123
+ yield {
124
+ toolCall: {
125
+ id: tc.id,
126
+ name: tc.name,
127
+ arguments: args,
128
+ },
129
+ done: false,
130
+ };
131
+ }
132
+ catch {
133
+ // Invalid JSON, skip
134
+ }
135
+ }
136
+ yield { done: true };
137
+ return;
138
+ }
139
+ }
140
+ catch {
141
+ // Invalid JSON, skip line
142
+ }
143
+ }
144
+ yield { done: true };
145
+ }
146
+ /**
147
+ * Convert internal messages to OpenAI-compatible format
148
+ */
149
+ convertMessages(messages) {
150
+ return messages.map((msg) => {
151
+ const base = {
152
+ role: msg.role,
153
+ content: msg.content,
154
+ };
155
+ if (msg.role === 'tool' && msg.toolCallId) {
156
+ base.tool_call_id = msg.toolCallId;
157
+ }
158
+ return base;
159
+ });
160
+ }
161
+ /**
162
+ * Convert tool definitions to OpenAI-compatible format
163
+ */
164
+ convertTools(tools) {
165
+ return tools.map((tool) => ({
166
+ type: 'function',
167
+ function: {
168
+ name: tool.name,
169
+ description: tool.description,
170
+ parameters: tool.parameters,
171
+ },
172
+ }));
173
+ }
174
+ /**
175
+ * Convert OpenAI-compatible response to internal format
176
+ */
177
+ convertResponse(response) {
178
+ const choice = response.choices[0];
179
+ if (!choice) {
180
+ throw new Error('No response choice');
181
+ }
182
+ const toolCalls = choice.message.tool_calls?.map((tc) => ({
183
+ id: tc.id,
184
+ name: tc.function.name,
185
+ arguments: this.parseArguments(tc.function.arguments),
186
+ }));
187
+ return {
188
+ content: choice.message.content ?? '',
189
+ toolCalls,
190
+ finishReason: this.convertFinishReason(choice.finish_reason),
191
+ usage: response.usage
192
+ ? {
193
+ promptTokens: response.usage.prompt_tokens,
194
+ completionTokens: response.usage.completion_tokens,
195
+ totalTokens: response.usage.total_tokens,
196
+ }
197
+ : undefined,
198
+ model: response.model,
199
+ };
200
+ }
201
+ /**
202
+ * Convert the API finish reason string to the internal LLMResponse finishReason.
203
+ * Override in subclasses if the provider uses different finish reason strings.
204
+ */
205
+ convertFinishReason(reason) {
206
+ switch (reason) {
207
+ case 'stop':
208
+ return 'stop';
209
+ case 'tool_calls':
210
+ return 'tool_calls';
211
+ case 'length':
212
+ return 'length';
213
+ case 'content_filter':
214
+ return 'content_filter';
215
+ default:
216
+ return reason;
217
+ }
218
+ }
219
+ /**
220
+ * Parse tool call arguments JSON
221
+ */
222
+ parseArguments(args) {
223
+ try {
224
+ return JSON.parse(args);
225
+ }
226
+ catch {
227
+ return {};
228
+ }
229
+ }
230
+ /**
231
+ * Generate a tool call ID for streaming when the server doesn't provide one.
232
+ * Override in subclasses if needed (e.g. local providers that omit IDs).
233
+ */
234
+ getStreamToolCallId(index) {
235
+ return `tc_${Date.now()}_${index}`;
236
+ }
237
+ /**
238
+ * Make API request with timeout
239
+ */
240
+ async makeRequest(endpoint, body, signal) {
241
+ const controller = new AbortController();
242
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
243
+ const combinedSignal = signal
244
+ ? AbortSignal.any([signal, controller.signal])
245
+ : controller.signal;
246
+ try {
247
+ const response = await fetch(`${this.baseUrl}${endpoint}`, {
248
+ method: 'POST',
249
+ headers: this.getHeaders(),
250
+ body: JSON.stringify(body),
251
+ signal: combinedSignal,
252
+ });
253
+ if (!response.ok) {
254
+ const error = await response.text();
255
+ throw new Error(`${this.name} API error: ${response.status} ${error}`);
256
+ }
257
+ return (await response.json());
258
+ }
259
+ finally {
260
+ clearTimeout(timeoutId);
261
+ }
262
+ }
263
+ }
264
+ //# sourceMappingURL=openai-compatible.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-compatible.js","sourceRoot":"","sources":["../../../src/chat/providers/openai-compatible.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * OpenAI Provider for mainwpcontrol
3
+ *
4
+ * Implements LLM provider interface for OpenAI GPT models.
5
+ */
6
+ import { type LLMProvider, type ProviderConfig, type ProviderCapabilities } from './provider.js';
7
+ import { OpenAICompatibleProvider } from './openai-compatible.js';
8
+ /**
9
+ * OpenAI provider implementation
10
+ */
11
+ export declare class OpenAIProvider extends OpenAICompatibleProvider {
12
+ readonly name = "openai";
13
+ readonly capabilities: ProviderCapabilities;
14
+ private readonly organization;
15
+ constructor(config: ProviderConfig);
16
+ isConfigured(): boolean;
17
+ getModels(): string[];
18
+ protected getHeaders(): Record<string, string>;
19
+ }
20
+ /**
21
+ * Create OpenAI provider
22
+ */
23
+ export declare function createOpenAIProvider(config: ProviderConfig): LLMProvider;
24
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAE1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAgBlE;;GAEG;AACH,qBAAa,cAAe,SAAQ,wBAAwB;IAC1D,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAMzC;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAEtC,MAAM,EAAE,cAAc;IAKlC,YAAY,IAAI,OAAO;IAIvB,SAAS,IAAI,MAAM,EAAE;IAIrB,SAAS,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAY/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CAExE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * OpenAI Provider for mainwpcontrol
3
+ *
4
+ * Implements LLM provider interface for OpenAI GPT models.
5
+ */
6
+ import { registerProvider, } from './provider.js';
7
+ import { OpenAICompatibleProvider } from './openai-compatible.js';
8
+ /**
9
+ * Available OpenAI models
10
+ */
11
+ const OPENAI_MODELS = [
12
+ 'gpt-4o',
13
+ 'gpt-4o-mini',
14
+ 'gpt-4-turbo',
15
+ 'gpt-4',
16
+ 'gpt-3.5-turbo',
17
+ ];
18
+ const DEFAULT_MODEL = 'gpt-4o-mini';
19
+ const DEFAULT_BASE_URL = 'https://api.openai.com/v1';
20
+ /**
21
+ * OpenAI provider implementation
22
+ */
23
+ export class OpenAIProvider extends OpenAICompatibleProvider {
24
+ name = 'openai';
25
+ capabilities = {
26
+ functionCalling: true,
27
+ streaming: true,
28
+ systemMessages: true,
29
+ vision: true,
30
+ maxContextLength: 128000, // GPT-4o
31
+ };
32
+ organization;
33
+ constructor(config) {
34
+ super(config, { baseUrl: DEFAULT_BASE_URL, model: DEFAULT_MODEL });
35
+ this.organization = config.organization;
36
+ }
37
+ isConfigured() {
38
+ return Boolean(this.apiKey);
39
+ }
40
+ getModels() {
41
+ return [...OPENAI_MODELS];
42
+ }
43
+ getHeaders() {
44
+ const headers = {
45
+ 'Content-Type': 'application/json',
46
+ Authorization: `Bearer ${this.apiKey}`,
47
+ };
48
+ if (this.organization) {
49
+ headers['OpenAI-Organization'] = this.organization;
50
+ }
51
+ return headers;
52
+ }
53
+ }
54
+ /**
55
+ * Create OpenAI provider
56
+ */
57
+ export function createOpenAIProvider(config) {
58
+ return new OpenAIProvider(config);
59
+ }
60
+ // Register provider
61
+ registerProvider('openai', createOpenAIProvider);
62
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/chat/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE;;GAEG;AACH,MAAM,aAAa,GAAG;IACpB,QAAQ;IACR,aAAa;IACb,aAAa;IACb,OAAO;IACP,eAAe;CACP,CAAC;AAEX,MAAM,aAAa,GAAG,aAAa,CAAC;AACpC,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAErD;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,wBAAwB;IACjD,IAAI,GAAG,QAAQ,CAAC;IAChB,YAAY,GAAyB;QAC5C,eAAe,EAAE,IAAI;QACrB,SAAS,EAAE,IAAI;QACf,cAAc,EAAE,IAAI;QACpB,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,MAAM,EAAE,SAAS;KACpC,CAAC;IAEe,YAAY,CAAqB;IAElD,YAAY,MAAsB;QAChC,KAAK,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAC1C,CAAC;IAED,YAAY;QACV,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC;IAC5B,CAAC;IAES,UAAU;QAClB,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;SACvC,CAAC;QAEF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;QACrD,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,oBAAoB;AACpB,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * OpenRouter Provider for mainwpcontrol
3
+ *
4
+ * Implements LLM provider interface for OpenRouter.
5
+ * OpenRouter provides access to multiple models through a unified API
6
+ * that's compatible with OpenAI's format.
7
+ */
8
+ import { type LLMProvider, type ProviderConfig, type ProviderCapabilities } from './provider.js';
9
+ import { OpenAICompatibleProvider } from './openai-compatible.js';
10
+ /**
11
+ * OpenRouter provider implementation
12
+ */
13
+ export declare class OpenRouterProvider extends OpenAICompatibleProvider {
14
+ readonly name = "openrouter";
15
+ readonly capabilities: ProviderCapabilities;
16
+ private readonly appName;
17
+ constructor(config: ProviderConfig);
18
+ isConfigured(): boolean;
19
+ getModels(): string[];
20
+ protected getHeaders(): Record<string, string>;
21
+ }
22
+ /**
23
+ * Create OpenRouter provider
24
+ */
25
+ export declare function createOpenRouterProvider(config: ProviderConfig): LLMProvider;
26
+ //# sourceMappingURL=openrouter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/openrouter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAE1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAmBlE;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,wBAAwB;IAC9D,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAMzC;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,cAAc;IAKlC,YAAY,IAAI,OAAO;IAIvB,SAAS,IAAI,MAAM,EAAE;IAIrB,SAAS,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAQ/C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CAE5E"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * OpenRouter Provider for mainwpcontrol
3
+ *
4
+ * Implements LLM provider interface for OpenRouter.
5
+ * OpenRouter provides access to multiple models through a unified API
6
+ * that's compatible with OpenAI's format.
7
+ */
8
+ import { registerProvider, } from './provider.js';
9
+ import { OpenAICompatibleProvider } from './openai-compatible.js';
10
+ /**
11
+ * Popular OpenRouter models
12
+ */
13
+ const OPENROUTER_MODELS = [
14
+ 'anthropic/claude-3.5-sonnet',
15
+ 'anthropic/claude-3-opus',
16
+ 'openai/gpt-4o',
17
+ 'openai/gpt-4o-mini',
18
+ 'google/gemini-pro-1.5',
19
+ 'meta-llama/llama-3.1-405b-instruct',
20
+ 'meta-llama/llama-3.1-70b-instruct',
21
+ 'mistralai/mistral-large',
22
+ ];
23
+ const DEFAULT_MODEL = 'anthropic/claude-3.5-sonnet';
24
+ const DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1';
25
+ /**
26
+ * OpenRouter provider implementation
27
+ */
28
+ export class OpenRouterProvider extends OpenAICompatibleProvider {
29
+ name = 'openrouter';
30
+ capabilities = {
31
+ functionCalling: true,
32
+ streaming: true,
33
+ systemMessages: true,
34
+ vision: true,
35
+ maxContextLength: 200000, // Varies by model
36
+ };
37
+ appName;
38
+ constructor(config) {
39
+ super(config, { baseUrl: DEFAULT_BASE_URL, model: DEFAULT_MODEL });
40
+ this.appName = 'mainwpcontrol';
41
+ }
42
+ isConfigured() {
43
+ return Boolean(this.apiKey);
44
+ }
45
+ getModels() {
46
+ return [...OPENROUTER_MODELS];
47
+ }
48
+ getHeaders() {
49
+ return {
50
+ 'Content-Type': 'application/json',
51
+ Authorization: `Bearer ${this.apiKey}`,
52
+ 'HTTP-Referer': 'https://github.com/mainwp/mainwp-control',
53
+ 'X-Title': this.appName,
54
+ };
55
+ }
56
+ }
57
+ /**
58
+ * Create OpenRouter provider
59
+ */
60
+ export function createOpenRouterProvider(config) {
61
+ return new OpenRouterProvider(config);
62
+ }
63
+ // Register provider
64
+ registerProvider('openrouter', createOpenRouterProvider);
65
+ //# sourceMappingURL=openrouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../../src/chat/providers/openrouter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAIL,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE;;GAEG;AACH,MAAM,iBAAiB,GAAG;IACxB,6BAA6B;IAC7B,yBAAyB;IACzB,eAAe;IACf,oBAAoB;IACpB,uBAAuB;IACvB,oCAAoC;IACpC,mCAAmC;IACnC,yBAAyB;CACjB,CAAC;AAEX,MAAM,aAAa,GAAG,6BAA6B,CAAC;AACpD,MAAM,gBAAgB,GAAG,8BAA8B,CAAC;AAExD;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,wBAAwB;IACrD,IAAI,GAAG,YAAY,CAAC;IACpB,YAAY,GAAyB;QAC5C,eAAe,EAAE,IAAI;QACrB,SAAS,EAAE,IAAI;QACf,cAAc,EAAE,IAAI;QACpB,MAAM,EAAE,IAAI;QACZ,gBAAgB,EAAE,MAAM,EAAE,kBAAkB;KAC7C,CAAC;IAEe,OAAO,CAAS;IAEjC,YAAY,MAAsB;QAChC,KAAK,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC;IACjC,CAAC;IAED,YAAY;QACV,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,iBAAiB,CAAC,CAAC;IAChC,CAAC;IAES,UAAU;QAClB,OAAO;YACL,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;YACtC,cAAc,EAAE,0CAA0C;YAC1D,SAAS,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAsB;IAC7D,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,oBAAoB;AACpB,gBAAgB,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shared HTTP fetch utility for LLM providers
3
+ *
4
+ * Extracts the common makeRequest pattern: timeout via AbortController,
5
+ * combined abort signals, JSON POST, error handling.
6
+ */
7
+ export declare function makeProviderRequest<T>(options: {
8
+ url: string;
9
+ headers: Record<string, string>;
10
+ body: Record<string, unknown>;
11
+ timeout: number;
12
+ signal?: AbortSignal | undefined;
13
+ providerName: string;
14
+ }): Promise<T>;
15
+ //# sourceMappingURL=provider-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-fetch.d.ts","sourceRoot":"","sources":["../../../src/chat/providers/provider-fetch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,OAAO,EAAE;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,CAAC,CAAC,CA6Bb"}