@involvex/prompt-enhancer 0.0.2

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 (60) hide show
  1. package/.github/FUNDING.yml +9 -0
  2. package/LICENSE +21 -0
  3. package/dist/app.d.ts +5 -0
  4. package/dist/app.js +39 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +53 -0
  7. package/dist/commands/about.d.ts +1 -0
  8. package/dist/commands/about.js +6 -0
  9. package/dist/commands/direct-enhance.d.ts +5 -0
  10. package/dist/commands/direct-enhance.js +52 -0
  11. package/dist/commands/enhanceprompt.d.ts +1 -0
  12. package/dist/commands/enhanceprompt.js +6 -0
  13. package/dist/commands/help.d.ts +1 -0
  14. package/dist/commands/help.js +6 -0
  15. package/dist/commands/settings.d.ts +1 -0
  16. package/dist/commands/settings.js +1 -0
  17. package/dist/commands/version.d.ts +1 -0
  18. package/dist/commands/version.js +6 -0
  19. package/dist/components/enhance-prompt.d.ts +5 -0
  20. package/dist/components/enhance-prompt.js +82 -0
  21. package/dist/components/history-viewer.d.ts +5 -0
  22. package/dist/components/history-viewer.js +64 -0
  23. package/dist/components/menu.d.ts +11 -0
  24. package/dist/components/menu.js +6 -0
  25. package/dist/components/select-input.d.ts +19 -0
  26. package/dist/components/select-input.js +51 -0
  27. package/dist/components/settings.d.ts +5 -0
  28. package/dist/components/settings.js +246 -0
  29. package/dist/lib/config/manager.d.ts +49 -0
  30. package/dist/lib/config/manager.js +152 -0
  31. package/dist/lib/config/schema.d.ts +69 -0
  32. package/dist/lib/config/schema.js +37 -0
  33. package/dist/lib/config/types.d.ts +34 -0
  34. package/dist/lib/config/types.js +4 -0
  35. package/dist/lib/enhancement/engine.d.ts +41 -0
  36. package/dist/lib/enhancement/engine.js +163 -0
  37. package/dist/lib/history/manager.d.ts +45 -0
  38. package/dist/lib/history/manager.js +120 -0
  39. package/dist/lib/providers/base.d.ts +47 -0
  40. package/dist/lib/providers/base.js +30 -0
  41. package/dist/lib/providers/copilot.d.ts +18 -0
  42. package/dist/lib/providers/copilot.js +112 -0
  43. package/dist/lib/providers/gemini.d.ts +13 -0
  44. package/dist/lib/providers/gemini.js +86 -0
  45. package/dist/lib/providers/index.d.ts +26 -0
  46. package/dist/lib/providers/index.js +86 -0
  47. package/dist/lib/providers/kilo.d.ts +22 -0
  48. package/dist/lib/providers/kilo.js +174 -0
  49. package/dist/lib/providers/opencode.d.ts +22 -0
  50. package/dist/lib/providers/opencode.js +174 -0
  51. package/dist/lib/types/index.d.ts +26 -0
  52. package/dist/lib/types/index.js +4 -0
  53. package/dist/lib/utils/copilot-auth.d.ts +14 -0
  54. package/dist/lib/utils/copilot-auth.js +84 -0
  55. package/dist/lib/utils/models-cache.d.ts +12 -0
  56. package/dist/lib/utils/models-cache.js +139 -0
  57. package/dist/lib/utils/paths.d.ts +10 -0
  58. package/dist/lib/utils/paths.js +18 -0
  59. package/package.json +101 -0
  60. package/readme.md +271 -0
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Enhancement engine - orchestrates prompt enhancement across providers
3
+ */
4
+ import { getProvider } from '../providers/index.js';
5
+ export class EnhancementEngine {
6
+ configManager;
7
+ historyManager;
8
+ constructor(configManager, historyManager) {
9
+ this.configManager = configManager;
10
+ this.historyManager = historyManager;
11
+ }
12
+ /**
13
+ * Enhance a prompt using the specified (or default) provider
14
+ */
15
+ async enhance(request) {
16
+ const startTime = Date.now();
17
+ const config = this.configManager.getConfig();
18
+ // Determine which provider to use
19
+ const providerName = request.provider || config.defaultProvider;
20
+ const providerConfig = config.providers[providerName];
21
+ if (!providerConfig?.enabled) {
22
+ throw new Error(`Provider '${providerName}' is not enabled. Please configure it in settings.`);
23
+ }
24
+ // Create credentials from config
25
+ const credentials = {
26
+ apiKey: providerConfig.apiKey || '',
27
+ endpoint: providerConfig.endpoint,
28
+ };
29
+ const provider = getProvider(providerName, credentials);
30
+ if (!provider) {
31
+ throw new Error(`Provider '${providerName}' not found. Available providers: ${Object.keys(config.providers).join(', ')}`);
32
+ }
33
+ // Create enhancement options
34
+ const options = {
35
+ model: request.model || config.defaultModel,
36
+ temperature: request.temperature ?? config.temperature,
37
+ maxTokens: request.maxTokens ?? config.maxTokens,
38
+ };
39
+ // Enhance the prompt
40
+ let enhanced;
41
+ try {
42
+ enhanced = await provider.enhance(request.prompt, options);
43
+ }
44
+ catch (error) {
45
+ throw new Error(`Enhancement failed with ${providerName}: ${error instanceof Error ? error.message : String(error)}`);
46
+ }
47
+ const duration = Date.now() - startTime;
48
+ // Save to history if requested
49
+ if (request.saveToHistory !== false && config.saveHistory) {
50
+ await this.historyManager.addEntry({
51
+ originalPrompt: request.prompt,
52
+ enhancedPrompt: enhanced,
53
+ provider: providerName,
54
+ model: options.model || 'default',
55
+ temperature: options.temperature,
56
+ tokens: options.maxTokens,
57
+ });
58
+ }
59
+ return {
60
+ originalPrompt: request.prompt,
61
+ enhancedPrompt: enhanced,
62
+ provider: providerName,
63
+ model: options.model || 'default',
64
+ duration,
65
+ };
66
+ }
67
+ /**
68
+ * Enhance a prompt with streaming output
69
+ */
70
+ async *enhanceStream(request) {
71
+ const startTime = Date.now();
72
+ const config = this.configManager.getConfig();
73
+ // Determine which provider to use
74
+ const providerName = request.provider || config.defaultProvider;
75
+ const providerConfig = config.providers[providerName];
76
+ if (!providerConfig?.enabled) {
77
+ throw new Error(`Provider '${providerName}' is not enabled. Please configure it in settings.`);
78
+ }
79
+ // Create credentials from config
80
+ const credentials = {
81
+ apiKey: providerConfig.apiKey || '',
82
+ endpoint: providerConfig.endpoint,
83
+ };
84
+ const provider = getProvider(providerName, credentials);
85
+ if (!provider) {
86
+ throw new Error(`Provider '${providerName}' not found. Available providers: ${Object.keys(config.providers).join(', ')}`);
87
+ }
88
+ // Create enhancement options
89
+ const options = {
90
+ model: request.model || config.defaultModel,
91
+ temperature: request.temperature ?? config.temperature,
92
+ maxTokens: request.maxTokens ?? config.maxTokens,
93
+ };
94
+ // Stream enhancement
95
+ let enhancedText = '';
96
+ try {
97
+ for await (const chunk of provider.enhanceStream(request.prompt, options)) {
98
+ enhancedText += chunk;
99
+ yield chunk;
100
+ }
101
+ }
102
+ catch (error) {
103
+ const errorMessage = error instanceof Error ? error.message : String(error);
104
+ throw new Error(`Enhancement failed with ${providerName}: ${errorMessage}`);
105
+ }
106
+ const duration = Date.now() - startTime;
107
+ // Save to history if requested
108
+ if (request.saveToHistory !== false && config.saveHistory) {
109
+ await this.historyManager.addEntry({
110
+ originalPrompt: request.prompt,
111
+ enhancedPrompt: enhancedText,
112
+ provider: providerName,
113
+ model: options.model || 'default',
114
+ temperature: options.temperature,
115
+ tokens: options.maxTokens,
116
+ });
117
+ }
118
+ return {
119
+ originalPrompt: request.prompt,
120
+ enhancedPrompt: enhancedText,
121
+ provider: providerName,
122
+ model: options.model || 'default',
123
+ duration,
124
+ };
125
+ }
126
+ /**
127
+ * Get available models for a provider
128
+ */
129
+ async getAvailableModels(providerName) {
130
+ const config = this.configManager.getConfig();
131
+ const providers = providerName
132
+ ? [providerName]
133
+ : Object.keys(config.providers);
134
+ const result = {};
135
+ for (const pName of providers) {
136
+ const provider = getProvider(pName);
137
+ if (provider) {
138
+ try {
139
+ result[pName] = await provider.getAvailableModels();
140
+ }
141
+ catch {
142
+ result[pName] = []; // Return empty list on error
143
+ }
144
+ }
145
+ }
146
+ return result;
147
+ }
148
+ /**
149
+ * Validate provider credentials
150
+ */
151
+ async validateProvider(providerName) {
152
+ const provider = getProvider(providerName);
153
+ if (!provider) {
154
+ return false;
155
+ }
156
+ try {
157
+ return await provider.validateCredentials();
158
+ }
159
+ catch {
160
+ return false;
161
+ }
162
+ }
163
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * History manager for persisting enhanced prompts
3
+ */
4
+ import type { HistoryEntry, HistoryData } from '../config/schema.js';
5
+ export declare class HistoryManager {
6
+ private history;
7
+ private historyPath;
8
+ constructor(historyPath?: string);
9
+ /**
10
+ * Load history from file
11
+ */
12
+ load(): Promise<HistoryData>;
13
+ /**
14
+ * Save current history to file
15
+ */
16
+ save(): Promise<void>;
17
+ /**
18
+ * Add an entry to history
19
+ */
20
+ addEntry(entry: Omit<HistoryEntry, 'id' | 'timestamp'>): Promise<HistoryEntry>;
21
+ /**
22
+ * Get all history entries
23
+ */
24
+ getEntries(): HistoryEntry[];
25
+ /**
26
+ * Get entries by provider
27
+ */
28
+ getEntriesByProvider(provider: string): HistoryEntry[];
29
+ /**
30
+ * Get recent entries (last N)
31
+ */
32
+ getRecent(count?: number): HistoryEntry[];
33
+ /**
34
+ * Clear all history
35
+ */
36
+ clear(): Promise<void>;
37
+ /**
38
+ * Delete a specific entry
39
+ */
40
+ deleteEntry(id: string): Promise<boolean>;
41
+ /**
42
+ * Export history as JSON
43
+ */
44
+ export(): HistoryData;
45
+ }
@@ -0,0 +1,120 @@
1
+ /**
2
+ * History manager for persisting enhanced prompts
3
+ */
4
+ import { readFile, writeFile, mkdir } from 'fs/promises';
5
+ import { existsSync } from 'fs';
6
+ import { randomUUID } from 'crypto';
7
+ import { HistoryDataSchema } from '../config/schema.js';
8
+ import { CONFIG_DIR, HISTORY_FILE } from '../utils/paths.js';
9
+ const DEFAULT_HISTORY = {
10
+ entries: [],
11
+ version: '1.0.0',
12
+ };
13
+ export class HistoryManager {
14
+ history;
15
+ historyPath;
16
+ constructor(historyPath) {
17
+ this.historyPath = historyPath || HISTORY_FILE;
18
+ this.history = structuredClone(DEFAULT_HISTORY);
19
+ }
20
+ /**
21
+ * Load history from file
22
+ */
23
+ async load() {
24
+ try {
25
+ // Ensure directory exists
26
+ if (!existsSync(CONFIG_DIR)) {
27
+ await mkdir(CONFIG_DIR, { recursive: true });
28
+ }
29
+ // If history file doesn't exist, create it with defaults
30
+ if (!existsSync(this.historyPath)) {
31
+ await this.save();
32
+ return this.history;
33
+ }
34
+ // Read and parse history file
35
+ const content = await readFile(this.historyPath, 'utf-8');
36
+ const parsed = JSON.parse(content);
37
+ // Validate using schema
38
+ const validated = HistoryDataSchema.parse(parsed);
39
+ this.history = validated;
40
+ return this.history;
41
+ }
42
+ catch (error) {
43
+ console.error('Failed to load history:', error);
44
+ throw error;
45
+ }
46
+ }
47
+ /**
48
+ * Save current history to file
49
+ */
50
+ async save() {
51
+ try {
52
+ // Ensure directory exists
53
+ if (!existsSync(CONFIG_DIR)) {
54
+ await mkdir(CONFIG_DIR, { recursive: true });
55
+ }
56
+ // Write history file
57
+ await writeFile(this.historyPath, JSON.stringify(this.history, null, 2), 'utf-8');
58
+ }
59
+ catch (error) {
60
+ console.error('Failed to save history:', error);
61
+ throw error;
62
+ }
63
+ }
64
+ /**
65
+ * Add an entry to history
66
+ */
67
+ async addEntry(entry) {
68
+ const historyEntry = {
69
+ ...entry,
70
+ id: randomUUID(),
71
+ timestamp: Date.now(),
72
+ };
73
+ this.history.entries.push(historyEntry);
74
+ await this.save();
75
+ return historyEntry;
76
+ }
77
+ /**
78
+ * Get all history entries
79
+ */
80
+ getEntries() {
81
+ return this.history.entries;
82
+ }
83
+ /**
84
+ * Get entries by provider
85
+ */
86
+ getEntriesByProvider(provider) {
87
+ return this.history.entries.filter(entry => entry.provider === provider);
88
+ }
89
+ /**
90
+ * Get recent entries (last N)
91
+ */
92
+ getRecent(count = 10) {
93
+ return this.history.entries.slice(-count).reverse();
94
+ }
95
+ /**
96
+ * Clear all history
97
+ */
98
+ async clear() {
99
+ this.history.entries = [];
100
+ await this.save();
101
+ }
102
+ /**
103
+ * Delete a specific entry
104
+ */
105
+ async deleteEntry(id) {
106
+ const index = this.history.entries.findIndex(e => e.id === id);
107
+ if (index !== -1) {
108
+ this.history.entries.splice(index, 1);
109
+ await this.save();
110
+ return true;
111
+ }
112
+ return false;
113
+ }
114
+ /**
115
+ * Export history as JSON
116
+ */
117
+ export() {
118
+ return structuredClone(this.history);
119
+ }
120
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Abstract base class for all LLM providers
3
+ * Defines the interface that all provider implementations must follow
4
+ */
5
+ import type { EnhancementOptions, ProviderCredentials } from '../types/index.js';
6
+ export declare abstract class Provider {
7
+ protected name: string;
8
+ protected credentials: ProviderCredentials;
9
+ protected defaultModel: string;
10
+ constructor(name: string, credentials: ProviderCredentials, defaultModel: string);
11
+ /**
12
+ * Get the provider name
13
+ */
14
+ getName(): string;
15
+ /**
16
+ * Enhance a prompt using this provider
17
+ * @param prompt The prompt to enhance
18
+ * @param options Enhancement options (model, temperature, etc.)
19
+ * @returns The enhanced prompt as a string
20
+ */
21
+ abstract enhance(prompt: string, options?: EnhancementOptions): Promise<string>;
22
+ /**
23
+ * Enhance a prompt with streaming output
24
+ * @param prompt The prompt to enhance
25
+ * @param options Enhancement options
26
+ * @returns AsyncGenerator that yields string chunks as they arrive
27
+ */
28
+ abstract enhanceStream(prompt: string, options?: EnhancementOptions): AsyncGenerator<string, void, unknown>;
29
+ /**
30
+ * Get available models for this provider
31
+ * @returns Array of available model IDs
32
+ */
33
+ abstract getAvailableModels(): Promise<string[]>;
34
+ /**
35
+ * Validate that the provider has valid credentials
36
+ * @returns true if credentials are valid, false otherwise
37
+ */
38
+ abstract validateCredentials(): Promise<boolean>;
39
+ /**
40
+ * Get provider-specific metadata
41
+ */
42
+ getMetadata(): {
43
+ name: string;
44
+ defaultModel: string;
45
+ supportsStreaming: boolean;
46
+ };
47
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Abstract base class for all LLM providers
3
+ * Defines the interface that all provider implementations must follow
4
+ */
5
+ export class Provider {
6
+ name;
7
+ credentials;
8
+ defaultModel;
9
+ constructor(name, credentials, defaultModel) {
10
+ this.name = name;
11
+ this.credentials = credentials;
12
+ this.defaultModel = defaultModel;
13
+ }
14
+ /**
15
+ * Get the provider name
16
+ */
17
+ getName() {
18
+ return this.name;
19
+ }
20
+ /**
21
+ * Get provider-specific metadata
22
+ */
23
+ getMetadata() {
24
+ return {
25
+ name: this.name,
26
+ defaultModel: this.defaultModel,
27
+ supportsStreaming: true,
28
+ };
29
+ }
30
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * GitHub Copilot provider implementation
3
+ * Uses OpenAI-compatible API.
4
+ * Auto-detects OAuth token from ~/.copilot/ and other well-known paths;
5
+ * falls back to manually-configured apiKey.
6
+ */
7
+ import { Provider } from './base.js';
8
+ import type { EnhancementOptions, ProviderCredentials } from '../types/index.js';
9
+ export declare class CopilotProvider extends Provider {
10
+ private client;
11
+ private initialized;
12
+ constructor(credentials: ProviderCredentials);
13
+ private ensureInitialized;
14
+ enhance(prompt: string, options?: EnhancementOptions): Promise<string>;
15
+ enhanceStream(prompt: string, options?: EnhancementOptions): AsyncGenerator<string, void, unknown>;
16
+ getAvailableModels(): Promise<string[]>;
17
+ validateCredentials(): Promise<boolean>;
18
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * GitHub Copilot provider implementation
3
+ * Uses OpenAI-compatible API.
4
+ * Auto-detects OAuth token from ~/.copilot/ and other well-known paths;
5
+ * falls back to manually-configured apiKey.
6
+ */
7
+ import { OpenAI } from 'openai';
8
+ import { Provider } from './base.js';
9
+ import { getCopilotToken } from '../utils/copilot-auth.js';
10
+ export class CopilotProvider extends Provider {
11
+ client;
12
+ initialized = false;
13
+ constructor(credentials) {
14
+ super('copilot', credentials, 'gpt-4o');
15
+ // Async init happens in ensureInitialized() before first use
16
+ }
17
+ async ensureInitialized() {
18
+ if (this.initialized)
19
+ return;
20
+ let apiKey = this.credentials.apiKey;
21
+ // Try auto-detection if no key was manually provided
22
+ if (!apiKey || this.credentials.useOAuth) {
23
+ const autoToken = await getCopilotToken();
24
+ if (autoToken) {
25
+ apiKey = autoToken;
26
+ }
27
+ }
28
+ if (!apiKey) {
29
+ throw new Error('Copilot provider: no API key found. Set an API key in settings or install GitHub Copilot / GitHub CLI so a token can be auto-detected.');
30
+ }
31
+ const config = { apiKey };
32
+ if (this.credentials.endpoint) {
33
+ config.baseURL = this.credentials.endpoint;
34
+ }
35
+ this.client = new OpenAI(config);
36
+ this.initialized = true;
37
+ }
38
+ async enhance(prompt, options) {
39
+ await this.ensureInitialized();
40
+ const systemPrompt = options?.systemPrompt ||
41
+ 'You are an expert at enhancing and improving user prompts for LLMs. Analyze the given prompt and return an improved version that is clearer, more specific, and more likely to produce better results. Return ONLY the enhanced prompt, no explanations.';
42
+ const response = await this.client.chat.completions.create({
43
+ messages: [
44
+ {
45
+ role: 'system',
46
+ content: systemPrompt,
47
+ },
48
+ {
49
+ role: 'user',
50
+ content: `Original prompt:\n${prompt}`,
51
+ },
52
+ ],
53
+ model: options?.model || this.defaultModel,
54
+ temperature: options?.temperature || 0.7,
55
+ max_tokens: options?.maxTokens || 1000,
56
+ });
57
+ const content = response.choices[0]?.message?.content;
58
+ if (!content) {
59
+ throw new Error('No response received from Copilot');
60
+ }
61
+ return content.trim();
62
+ }
63
+ async *enhanceStream(prompt, options) {
64
+ await this.ensureInitialized();
65
+ const systemPrompt = options?.systemPrompt ||
66
+ 'You are an expert at enhancing and improving user prompts for LLMs. Analyze the given prompt and return an improved version that is clearer, more specific, and more likely to produce better results. Return ONLY the enhanced prompt, no explanations.';
67
+ const stream = await this.client.chat.completions.create({
68
+ messages: [
69
+ {
70
+ role: 'system',
71
+ content: systemPrompt,
72
+ },
73
+ {
74
+ role: 'user',
75
+ content: `Original prompt:\n${prompt}`,
76
+ },
77
+ ],
78
+ model: options?.model || this.defaultModel,
79
+ temperature: options?.temperature || 0.7,
80
+ max_tokens: options?.maxTokens || 1000,
81
+ stream: true,
82
+ });
83
+ for await (const event of stream) {
84
+ const content = event.choices[0]?.delta?.content;
85
+ if (content) {
86
+ yield content;
87
+ }
88
+ }
89
+ }
90
+ async getAvailableModels() {
91
+ return ['gpt-4o', 'gpt-4o-mini', 'gpt-4.1', 'claude-sonnet-4', 'o3'];
92
+ }
93
+ async validateCredentials() {
94
+ try {
95
+ await this.ensureInitialized();
96
+ await this.client.chat.completions.create({
97
+ messages: [
98
+ {
99
+ role: 'user',
100
+ content: 'test',
101
+ },
102
+ ],
103
+ model: this.defaultModel,
104
+ max_tokens: 1,
105
+ });
106
+ return true;
107
+ }
108
+ catch {
109
+ return false;
110
+ }
111
+ }
112
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Google Gemini provider implementation
3
+ */
4
+ import { Provider } from './base.js';
5
+ import type { EnhancementOptions, ProviderCredentials } from '../types/index.js';
6
+ export declare class GeminiProvider extends Provider {
7
+ private client;
8
+ constructor(credentials: ProviderCredentials);
9
+ enhance(prompt: string, options?: EnhancementOptions): Promise<string>;
10
+ enhanceStream(prompt: string, options?: EnhancementOptions): AsyncGenerator<string, void, unknown>;
11
+ getAvailableModels(): Promise<string[]>;
12
+ validateCredentials(): Promise<boolean>;
13
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Google Gemini provider implementation
3
+ */
4
+ import { GoogleGenerativeAI } from '@google/generative-ai';
5
+ import { Provider } from './base.js';
6
+ export class GeminiProvider extends Provider {
7
+ client;
8
+ constructor(credentials) {
9
+ super('gemini', credentials, 'gemini-2.5-flash');
10
+ if (!credentials.apiKey) {
11
+ throw new Error('Gemini provider requires an API key');
12
+ }
13
+ this.client = new GoogleGenerativeAI(credentials.apiKey);
14
+ }
15
+ async enhance(prompt, options) {
16
+ const model = this.client.getGenerativeModel({
17
+ model: options?.model || this.defaultModel,
18
+ });
19
+ const systemPrompt = options?.systemPrompt ||
20
+ 'You are an expert at enhancing and improving user prompts for LLMs. Analyze the given prompt and return an improved version that is clearer, more specific, and more likely to produce better results. Return ONLY the enhanced prompt, no explanations.';
21
+ const result = await model.generateContent({
22
+ contents: [
23
+ {
24
+ role: 'user',
25
+ parts: [
26
+ {
27
+ text: `${systemPrompt}\n\nOriginal prompt:\n${prompt}`,
28
+ },
29
+ ],
30
+ },
31
+ ],
32
+ });
33
+ const response = result.response;
34
+ const text = response.text();
35
+ if (!text) {
36
+ throw new Error('No response received from Gemini');
37
+ }
38
+ return text.trim();
39
+ }
40
+ async *enhanceStream(prompt, options) {
41
+ const model = this.client.getGenerativeModel({
42
+ model: options?.model || this.defaultModel,
43
+ });
44
+ const systemPrompt = options?.systemPrompt ||
45
+ 'You are an expert at enhancing and improving user prompts for LLMs. Analyze the given prompt and return an improved version that is clearer, more specific, and more likely to produce better results. Return ONLY the enhanced prompt, no explanations.';
46
+ const result = await model.generateContentStream({
47
+ contents: [
48
+ {
49
+ role: 'user',
50
+ parts: [
51
+ {
52
+ text: `${systemPrompt}\n\nOriginal prompt:\n${prompt}`,
53
+ },
54
+ ],
55
+ },
56
+ ],
57
+ });
58
+ for await (const chunk of result.stream) {
59
+ const text = chunk.text();
60
+ if (text) {
61
+ yield text;
62
+ }
63
+ }
64
+ }
65
+ async getAvailableModels() {
66
+ // Gemini models available as of 2025
67
+ return [
68
+ 'gemini-2.5-flash',
69
+ 'gemini-2.0-flash',
70
+ 'gemini-1.5-pro',
71
+ 'gemini-1.5-flash',
72
+ ];
73
+ }
74
+ async validateCredentials() {
75
+ try {
76
+ const model = this.client.getGenerativeModel({
77
+ model: this.defaultModel,
78
+ });
79
+ await model.countTokens('test prompt');
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Provider factory and registry
3
+ * Manages creation and registration of provider instances
4
+ */
5
+ import { Provider } from './base.js';
6
+ import type { ProviderCredentials } from '../types/index.js';
7
+ export type ProviderType = 'gemini' | 'copilot' | 'kilo' | 'opencode';
8
+ export declare class ProviderFactory {
9
+ private registry;
10
+ createProvider(type: ProviderType, credentials: ProviderCredentials): Provider;
11
+ registerProvider(name: string, provider: Provider): void;
12
+ getProvider(name: string): Provider | undefined;
13
+ getAllProviders(): Provider[];
14
+ hasProvider(name: string): boolean;
15
+ listProviders(): string[];
16
+ clearProviders(): void;
17
+ }
18
+ export declare const providerFactory: ProviderFactory;
19
+ /**
20
+ * Get or create a provider by type with credentials
21
+ */
22
+ export declare function getProvider(type: ProviderType, credentials?: ProviderCredentials): Provider;
23
+ /**
24
+ * Get list of supported provider types
25
+ */
26
+ export declare function getSupportedProviders(): ProviderType[];