protoagent 0.0.5 → 0.1.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 (58) hide show
  1. package/README.md +99 -19
  2. package/dist/App.js +602 -0
  3. package/dist/agentic-loop.js +492 -525
  4. package/dist/cli.js +39 -0
  5. package/dist/components/CollapsibleBox.js +26 -0
  6. package/dist/components/ConfigDialog.js +40 -0
  7. package/dist/components/ConsolidatedToolMessage.js +41 -0
  8. package/dist/components/FormattedMessage.js +93 -0
  9. package/dist/components/Table.js +275 -0
  10. package/dist/config.js +171 -0
  11. package/dist/mcp.js +170 -0
  12. package/dist/providers.js +137 -0
  13. package/dist/sessions.js +161 -0
  14. package/dist/skills.js +229 -0
  15. package/dist/sub-agent.js +103 -0
  16. package/dist/system-prompt.js +131 -0
  17. package/dist/tools/bash.js +178 -0
  18. package/dist/tools/edit-file.js +65 -171
  19. package/dist/tools/index.js +79 -134
  20. package/dist/tools/list-directory.js +20 -73
  21. package/dist/tools/read-file.js +57 -101
  22. package/dist/tools/search-files.js +74 -162
  23. package/dist/tools/todo.js +57 -140
  24. package/dist/tools/webfetch.js +310 -0
  25. package/dist/tools/write-file.js +44 -135
  26. package/dist/utils/approval.js +69 -0
  27. package/dist/utils/compactor.js +87 -0
  28. package/dist/utils/cost-tracker.js +26 -81
  29. package/dist/utils/format-message.js +26 -0
  30. package/dist/utils/logger.js +101 -307
  31. package/dist/utils/path-validation.js +74 -0
  32. package/package.json +45 -51
  33. package/LICENSE +0 -21
  34. package/dist/config/client.js +0 -315
  35. package/dist/config/commands.js +0 -223
  36. package/dist/config/manager.js +0 -117
  37. package/dist/config/mcp-commands.js +0 -266
  38. package/dist/config/mcp-manager.js +0 -240
  39. package/dist/config/mcp-types.js +0 -28
  40. package/dist/config/providers.js +0 -229
  41. package/dist/config/setup.js +0 -209
  42. package/dist/config/system-prompt.js +0 -397
  43. package/dist/config/types.js +0 -4
  44. package/dist/index.js +0 -229
  45. package/dist/tools/create-directory.js +0 -76
  46. package/dist/tools/directory-operations.js +0 -195
  47. package/dist/tools/file-operations.js +0 -211
  48. package/dist/tools/run-shell-command.js +0 -746
  49. package/dist/tools/search-operations.js +0 -179
  50. package/dist/tools/shell-operations.js +0 -342
  51. package/dist/tools/task-complete.js +0 -26
  52. package/dist/tools/view-directory-tree.js +0 -125
  53. package/dist/tools.js +0 -2
  54. package/dist/utils/conversation-compactor.js +0 -140
  55. package/dist/utils/enhanced-prompt.js +0 -23
  56. package/dist/utils/file-operations-approval.js +0 -373
  57. package/dist/utils/interrupt-handler.js +0 -127
  58. package/dist/utils/user-cancellation.js +0 -34
@@ -1,229 +0,0 @@
1
- /**
2
- * OpenAI provider configuration for ProtoAgent
3
- */
4
- export const openaiModels = {
5
- models: [
6
- 'gpt-5-nano-2025-08-07',
7
- 'gpt-5-mini-2025-08-07',
8
- 'gpt-5-2025-08-07',
9
- 'gpt-4o-mini-2024-07-18',
10
- 'gpt-4o',
11
- 'gpt-4o-2024-11-20',
12
- 'gpt-4-turbo',
13
- 'gpt-3.5-turbo'
14
- ],
15
- defaultModel: 'gpt-5-mini-2025-08-07'
16
- };
17
- export const openaiModelConfigs = {
18
- 'gpt-5-nano-2025-08-07': {
19
- name: 'GPT-5 Nano',
20
- contextWindow: 128000,
21
- pricing: { inputTokens: 0.00000005, outputTokens: 0.0000004 } // $0.05/$0.40 per 1M tokens
22
- },
23
- 'gpt-5-mini-2025-08-07': {
24
- name: 'GPT-5 Mini',
25
- contextWindow: 128000,
26
- pricing: { inputTokens: 0.00000025, outputTokens: 0.000002 } // $0.25/$2.00 per 1M tokens
27
- },
28
- 'gpt-5-2025-08-07': {
29
- name: 'GPT-5',
30
- contextWindow: 128000,
31
- pricing: { inputTokens: 0.00000125, outputTokens: 0.00001 } // $1.25/$10.00 per 1M tokens
32
- },
33
- 'gpt-4o-mini-2024-07-18': {
34
- name: 'GPT-4o Mini',
35
- contextWindow: 128000,
36
- pricing: { inputTokens: 0.00000015, outputTokens: 0.0000006 } // $0.15/$0.60 per 1M tokens
37
- },
38
- 'gpt-4o': {
39
- name: 'GPT-4o',
40
- contextWindow: 128000,
41
- pricing: { inputTokens: 0.0000025, outputTokens: 0.00001 } // $2.50/$10.00 per 1M tokens
42
- },
43
- 'gpt-4o-2024-11-20': {
44
- name: 'GPT-4o (2024-11-20)',
45
- contextWindow: 128000,
46
- pricing: { inputTokens: 0.0000025, outputTokens: 0.00001 } // $2.50/$10.00 per 1M tokens
47
- },
48
- 'gpt-4-turbo': {
49
- name: 'GPT-4 Turbo',
50
- contextWindow: 128000,
51
- pricing: { inputTokens: 0.00001, outputTokens: 0.00003 } // $10.00/$30.00 per 1M tokens
52
- },
53
- 'gpt-3.5-turbo': {
54
- name: 'GPT-3.5 Turbo',
55
- contextWindow: 16385,
56
- pricing: { inputTokens: 0.0000005, outputTokens: 0.0000015 } // $0.50/$1.50 per 1M tokens
57
- }
58
- };
59
- export const openaiProvider = {
60
- id: 'openai',
61
- name: 'OpenAI',
62
- models: openaiModels.models,
63
- defaultModel: 'gpt-5-mini-2025-08-07',
64
- modelConfigs: openaiModelConfigs,
65
- auth: {
66
- type: 'api_key',
67
- envVar: 'OPENAI_API_KEY',
68
- label: 'OpenAI API Key',
69
- helpUrl: 'https://platform.openai.com/api-keys'
70
- }
71
- };
72
- export const geminiModels = {
73
- models: [
74
- 'models/gemini-2.5-pro',
75
- 'models/gemini-2.5-flash',
76
- 'models/gemini-2.5-flash-lite',
77
- 'models/gemini-2.0-flash',
78
- 'models/gemini-2.0-flash-lite'
79
- ],
80
- defaultModel: 'models/gemini-2.5-flash'
81
- };
82
- export const geminiModelConfigs = {
83
- 'models/gemini-2.5-pro': {
84
- name: 'Gemini 2.5 Pro',
85
- contextWindow: 2000000,
86
- pricing: { inputTokens: 0.00000125, outputTokens: 0.00001 } // $1.25/$10.00 per 1M tokens (<=200k prompts)
87
- },
88
- 'models/gemini-2.5-flash': {
89
- name: 'Gemini 2.5 Flash',
90
- contextWindow: 1000000,
91
- pricing: { inputTokens: 0.0000003, outputTokens: 0.0000025 } // $0.30/$2.50 per 1M tokens
92
- },
93
- 'models/gemini-2.5-flash-lite': {
94
- name: 'Gemini 2.5 Flash Lite',
95
- contextWindow: 1000000,
96
- pricing: { inputTokens: 0.0000001, outputTokens: 0.0000004 } // $0.10/$0.40 per 1M tokens
97
- },
98
- 'models/gemini-2.0-flash': {
99
- name: 'Gemini 2.0 Flash',
100
- contextWindow: 1000000,
101
- pricing: { inputTokens: 0.0000001, outputTokens: 0.0000004 } // $0.10/$0.40 per 1M tokens (text/image/video)
102
- },
103
- 'models/gemini-2.0-flash-lite': {
104
- name: 'Gemini 2.0 Flash Lite',
105
- contextWindow: 1000000,
106
- pricing: { inputTokens: 0.000000075, outputTokens: 0.0000003 } // $0.075/$0.30 per 1M tokens
107
- }
108
- };
109
- export const geminiProvider = {
110
- id: 'gemini',
111
- name: 'Gemini',
112
- models: geminiModels.models,
113
- defaultModel: geminiModels.defaultModel,
114
- modelConfigs: geminiModelConfigs,
115
- auth: {
116
- type: 'api_key',
117
- envVar: 'GEMINI_API_KEY',
118
- label: 'Gemini API Key',
119
- helpUrl: 'https://aistudio.google.com/app/apikey'
120
- },
121
- baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai/'
122
- };
123
- export const cerebrasModels = {
124
- models: [
125
- 'gpt-oss-120b',
126
- 'qwen-3-coder-480b'
127
- ],
128
- defaultModel: 'gpt-oss-120b'
129
- };
130
- export const cerebrasModelConfigs = {
131
- 'gpt-oss-120b': {
132
- name: 'GPT OSS 120B',
133
- contextWindow: 128000,
134
- pricing: { inputTokens: 0.00000035, outputTokens: 0.00000075 } // $0.35/$0.75 per 1M tokens
135
- },
136
- 'qwen-3-coder-480b': {
137
- name: 'Qwen 3 Coder 480B',
138
- contextWindow: 128000,
139
- pricing: { inputTokens: 0.000002, outputTokens: 0.000002 } // $2.00/$2.00 per 1M tokens
140
- }
141
- };
142
- export const cerebrasProvider = {
143
- id: 'cerebras',
144
- name: 'Cerebras',
145
- models: cerebrasModels.models,
146
- defaultModel: cerebrasModels.defaultModel,
147
- modelConfigs: cerebrasModelConfigs,
148
- auth: {
149
- type: 'api_key',
150
- envVar: 'CEREBRAS_API_KEY',
151
- label: 'Cerebras API Key',
152
- helpUrl: 'https://cloud.cerebras.ai/platform'
153
- },
154
- baseURL: 'https://api.cerebras.ai/v1'
155
- };
156
- export const anthropicModels = {
157
- models: [
158
- 'claude-3-5-sonnet-4-20250126',
159
- 'claude-3-5-sonnet-20241022',
160
- 'claude-3-5-haiku-20241022',
161
- 'claude-3-opus-20240229',
162
- 'claude-3-sonnet-20240229',
163
- 'claude-3-haiku-20240307'
164
- ],
165
- defaultModel: 'claude-3-5-sonnet-4-20250126'
166
- };
167
- export const anthropicModelConfigs = {
168
- 'claude-3-5-sonnet-4-20250126': {
169
- name: 'Claude 3.5 Sonnet 4',
170
- contextWindow: 200000,
171
- pricing: { inputTokens: 0.000003, outputTokens: 0.000015 } // $3.00/$15.00 per 1M tokens
172
- },
173
- 'claude-3-5-sonnet-20241022': {
174
- name: 'Claude 3.5 Sonnet',
175
- contextWindow: 200000,
176
- pricing: { inputTokens: 0.000003, outputTokens: 0.000015 } // $3.00/$15.00 per 1M tokens
177
- },
178
- 'claude-3-5-haiku-20241022': {
179
- name: 'Claude 3.5 Haiku',
180
- contextWindow: 200000,
181
- pricing: { inputTokens: 0.0000008, outputTokens: 0.000004 } // $0.80/$4.00 per 1M tokens
182
- },
183
- 'claude-3-opus-20240229': {
184
- name: 'Claude 3 Opus',
185
- contextWindow: 200000,
186
- pricing: { inputTokens: 0.000015, outputTokens: 0.000075 } // $15.00/$75.00 per 1M tokens
187
- },
188
- 'claude-3-sonnet-20240229': {
189
- name: 'Claude 3 Sonnet',
190
- contextWindow: 200000,
191
- pricing: { inputTokens: 0.000003, outputTokens: 0.000015 } // $3.00/$15.00 per 1M tokens
192
- },
193
- 'claude-3-haiku-20240307': {
194
- name: 'Claude 3 Haiku',
195
- contextWindow: 200000,
196
- pricing: { inputTokens: 0.00000025, outputTokens: 0.00000125 } // $0.25/$1.25 per 1M tokens
197
- }
198
- };
199
- export const anthropicProvider = {
200
- id: 'anthropic',
201
- name: 'Anthropic',
202
- models: anthropicModels.models,
203
- defaultModel: anthropicModels.defaultModel,
204
- modelConfigs: anthropicModelConfigs,
205
- auth: {
206
- type: 'api_key',
207
- envVar: 'ANTHROPIC_API_KEY',
208
- label: 'Anthropic API Key',
209
- helpUrl: 'https://console.anthropic.com/settings/keys'
210
- },
211
- baseURL: 'https://api.anthropic.com/v1'
212
- };
213
- /**
214
- * Get model configuration for any provider
215
- */
216
- export function getModelConfig(provider, model) {
217
- switch (provider) {
218
- case 'openai':
219
- return openaiModelConfigs[model] || null;
220
- case 'gemini':
221
- return geminiModelConfigs[model] || null;
222
- case 'cerebras':
223
- return cerebrasModelConfigs[model] || null;
224
- case 'anthropic':
225
- return anthropicModelConfigs[model] || null;
226
- default:
227
- return null;
228
- }
229
- }
@@ -1,209 +0,0 @@
1
- /**
2
- * Interactive configuration setup for ProtoAgent
3
- */
4
- import inquirer from 'inquirer';
5
- import { openaiProvider, geminiProvider, cerebrasProvider, anthropicProvider } from './providers.js';
6
- import { saveConfig, getConfigDirectory } from './manager.js';
7
- import { logger } from '../utils/logger.js';
8
- /**
9
- * Run interactive configuration setup
10
- */
11
- export async function setupConfig() {
12
- logger.consoleLog('\nšŸ¤– Welcome to ProtoAgent!');
13
- logger.consoleLog("Let's set up your model configuration.\n");
14
- // Step 1: Select provider and model
15
- const modelChoices = [
16
- new inquirer.Separator('--- OpenAI Models ---'),
17
- ...openaiProvider.models.map(model => ({
18
- name: model === openaiProvider.defaultModel ? `${model} (recommended)` : model,
19
- value: { provider: 'openai', model }
20
- })),
21
- new inquirer.Separator('--- Anthropic Models ---'),
22
- ...anthropicProvider.models.map(model => ({
23
- name: model === anthropicProvider.defaultModel ? `${model} (recommended)` : model,
24
- value: { provider: 'anthropic', model }
25
- })),
26
- new inquirer.Separator('--- Gemini Models ---'),
27
- ...geminiProvider.models.map(model => ({
28
- name: model === geminiProvider.defaultModel ? `${model} (recommended)` : model,
29
- value: { provider: 'gemini', model }
30
- })),
31
- new inquirer.Separator('--- Cerebras Models ---'),
32
- ...cerebrasProvider.models.map(model => ({
33
- name: model === cerebrasProvider.defaultModel ? `${model} (recommended)` : model,
34
- value: { provider: 'cerebras', model }
35
- }))
36
- ];
37
- const { selection } = await inquirer.prompt([
38
- {
39
- type: 'list',
40
- name: 'selection',
41
- message: 'Select a model:',
42
- choices: modelChoices,
43
- default: { provider: 'openai', model: openaiProvider.defaultModel }
44
- }
45
- ]);
46
- const provider = selection.provider;
47
- const model = selection.model;
48
- // Step 2: Get API credentials
49
- let apiKey = '';
50
- let credentials = {
51
- OPENAI_API_KEY: '',
52
- GEMINI_API_KEY: '',
53
- CEREBRAS_API_KEY: '',
54
- ANTHROPIC_API_KEY: ''
55
- };
56
- if (provider === 'openai') {
57
- logger.consoleLog(`\nšŸ“ ${openaiProvider.auth.label} Setup`);
58
- logger.consoleLog("You'll need an API key from OpenAI.");
59
- logger.consoleLog(`Get your API key from: ${openaiProvider.auth.helpUrl}`);
60
- const response = await inquirer.prompt([
61
- {
62
- type: 'password',
63
- name: 'apiKey',
64
- message: `Enter your ${openaiProvider.auth.label}:`,
65
- mask: '*',
66
- validate: (input) => {
67
- if (!input || input.trim().length === 0) {
68
- return 'API key is required';
69
- }
70
- if (!input.trim().startsWith('sk-')) {
71
- return 'OpenAI API keys should start with "sk-"';
72
- }
73
- return true;
74
- }
75
- }
76
- ]);
77
- apiKey = response.apiKey;
78
- credentials.OPENAI_API_KEY = apiKey;
79
- }
80
- else if (provider === 'anthropic') {
81
- logger.consoleLog(`\nšŸ“ ${anthropicProvider.auth.label} Setup`);
82
- logger.consoleLog("You'll need an API key from Anthropic.");
83
- logger.consoleLog(`Get your API key from: ${anthropicProvider.auth.helpUrl}`);
84
- const response = await inquirer.prompt([
85
- {
86
- type: 'password',
87
- name: 'apiKey',
88
- message: `Enter your ${anthropicProvider.auth.label}:`,
89
- mask: '*',
90
- validate: (input) => {
91
- if (!input || input.trim().length === 0) {
92
- return 'API key is required';
93
- }
94
- if (!input.trim().startsWith('sk-')) {
95
- return 'Anthropic API keys should start with "sk-"';
96
- }
97
- return true;
98
- }
99
- }
100
- ]);
101
- apiKey = response.apiKey;
102
- credentials.ANTHROPIC_API_KEY = apiKey;
103
- }
104
- else if (provider === 'gemini') {
105
- logger.consoleLog(`\nšŸ“ ${geminiProvider.auth.label} Setup`);
106
- logger.consoleLog("You'll need an API key from Gemini.");
107
- logger.consoleLog(`Get your API key from: ${geminiProvider.auth.helpUrl}`);
108
- const response = await inquirer.prompt([
109
- {
110
- type: 'password',
111
- name: 'apiKey',
112
- message: `Enter your ${geminiProvider.auth.label}:`,
113
- mask: '*',
114
- validate: (input) => {
115
- if (!input || input.trim().length === 0) {
116
- return 'API key is required';
117
- }
118
- // Gemini keys may have different format, so just check non-empty
119
- return true;
120
- }
121
- }
122
- ]);
123
- apiKey = response.apiKey;
124
- credentials.GEMINI_API_KEY = apiKey;
125
- }
126
- else if (provider === 'cerebras') {
127
- logger.consoleLog(`\nšŸ“ ${cerebrasProvider.auth.label} Setup`);
128
- logger.consoleLog("You'll need an API key from Cerebras.");
129
- logger.consoleLog(`Get your API key from: ${cerebrasProvider.auth.helpUrl}`);
130
- const response = await inquirer.prompt([
131
- {
132
- type: 'password',
133
- name: 'apiKey',
134
- message: `Enter your ${cerebrasProvider.auth.label}:`,
135
- mask: '*',
136
- validate: (input) => {
137
- if (!input || input.trim().length === 0) {
138
- return 'API key is required';
139
- }
140
- // Cerebras keys may have different format, so just check non-empty
141
- return true;
142
- }
143
- }
144
- ]);
145
- apiKey = response.apiKey;
146
- credentials.CEREBRAS_API_KEY = apiKey;
147
- }
148
- // Step 3: Confirm configuration
149
- logger.consoleLog('\nšŸ“‹ Configuration Summary:');
150
- let providerName = '';
151
- if (provider === 'openai') {
152
- providerName = openaiProvider.name;
153
- }
154
- else if (provider === 'anthropic') {
155
- providerName = anthropicProvider.name;
156
- }
157
- else if (provider === 'gemini') {
158
- providerName = geminiProvider.name;
159
- }
160
- else if (provider === 'cerebras') {
161
- providerName = cerebrasProvider.name;
162
- }
163
- logger.consoleLog(`Provider: ${providerName}`);
164
- logger.consoleLog(`Model: ${model}`);
165
- logger.consoleLog(`API Key: ${'*'.repeat(Math.min(apiKey.length, 20))}...`);
166
- const { confirm } = await inquirer.prompt([
167
- {
168
- type: 'confirm',
169
- name: 'confirm',
170
- message: 'Save this configuration?',
171
- default: true
172
- }
173
- ]);
174
- if (!confirm) {
175
- logger.consoleLog('Configuration cancelled.');
176
- process.exit(0);
177
- }
178
- // Step 4: Save configuration
179
- const config = {
180
- provider,
181
- model,
182
- credentials
183
- };
184
- try {
185
- await saveConfig(config);
186
- logger.consoleLog(`\nāœ… Configuration saved successfully!`);
187
- logger.consoleLog(`Config location: ${getConfigDirectory()}/config.json`);
188
- logger.consoleLog("\nYou're all set! ProtoAgent is ready to use.\n");
189
- return config;
190
- }
191
- catch (error) {
192
- console.error(`\nāŒ Failed to save configuration: ${error.message}`);
193
- process.exit(1);
194
- }
195
- }
196
- /**
197
- * Prompt to reconfigure
198
- */
199
- export async function promptReconfigure() {
200
- const { reconfigure } = await inquirer.prompt([
201
- {
202
- type: 'confirm',
203
- name: 'reconfigure',
204
- message: 'Would you like to reconfigure ProtoAgent?',
205
- default: false
206
- }
207
- ]);
208
- return reconfigure;
209
- }