hedgequantx 2.5.9 → 2.5.11
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.
- package/package.json +1 -1
- package/src/menus/ai-agent.js +17 -9
- package/src/services/ai/index.js +45 -2
package/package.json
CHANGED
package/src/menus/ai-agent.js
CHANGED
|
@@ -121,7 +121,7 @@ const showExistingTokens = async () => {
|
|
|
121
121
|
// Show found tokens
|
|
122
122
|
console.clear();
|
|
123
123
|
displayBanner();
|
|
124
|
-
|
|
124
|
+
drawBoxHeaderContinue('EXISTING SESSIONS FOUND', boxWidth);
|
|
125
125
|
|
|
126
126
|
console.log(makeLine(chalk.green(`FOUND ${tokens.length} EXISTING SESSION(S)`)));
|
|
127
127
|
console.log(makeLine(''));
|
|
@@ -174,9 +174,17 @@ const showExistingTokens = async () => {
|
|
|
174
174
|
const spinner = ora({ text: 'VALIDATING TOKEN...', color: 'cyan' }).start();
|
|
175
175
|
|
|
176
176
|
try {
|
|
177
|
-
// Validate the token
|
|
178
|
-
const credentials = {
|
|
179
|
-
|
|
177
|
+
// Validate the token - include metadata from scanner
|
|
178
|
+
const credentials = {
|
|
179
|
+
apiKey: selectedToken.token,
|
|
180
|
+
sessionKey: selectedToken.token,
|
|
181
|
+
accessToken: selectedToken.token,
|
|
182
|
+
fromKeychain: selectedToken.sourceId === 'secureStorage' || selectedToken.sourceId === 'keychain',
|
|
183
|
+
subscriptionType: selectedToken.subscriptionType,
|
|
184
|
+
refreshToken: selectedToken.refreshToken,
|
|
185
|
+
expiresAt: selectedToken.expiresAt
|
|
186
|
+
};
|
|
187
|
+
const validation = await aiService.validateConnection(selectedToken.provider, selectedToken.type, credentials);
|
|
180
188
|
|
|
181
189
|
if (!validation.valid) {
|
|
182
190
|
spinner.fail(`TOKEN INVALID OR EXPIRED: ${validation.error}`);
|
|
@@ -236,7 +244,7 @@ const selectCategory = async () => {
|
|
|
236
244
|
|
|
237
245
|
console.clear();
|
|
238
246
|
displayBanner();
|
|
239
|
-
|
|
247
|
+
drawBoxHeaderContinue('SELECT PROVIDER TYPE', boxWidth);
|
|
240
248
|
|
|
241
249
|
const categories = getCategories();
|
|
242
250
|
|
|
@@ -305,7 +313,7 @@ const selectProvider = async (categoryId) => {
|
|
|
305
313
|
|
|
306
314
|
const categories = getCategories();
|
|
307
315
|
const category = categories.find(c => c.id === categoryId);
|
|
308
|
-
|
|
316
|
+
drawBoxHeaderContinue(category.name, boxWidth);
|
|
309
317
|
|
|
310
318
|
const providers = getProvidersByCategory(categoryId);
|
|
311
319
|
|
|
@@ -391,7 +399,7 @@ const selectProviderOption = async (provider) => {
|
|
|
391
399
|
|
|
392
400
|
console.clear();
|
|
393
401
|
displayBanner();
|
|
394
|
-
|
|
402
|
+
drawBoxHeaderContinue(provider.name, boxWidth);
|
|
395
403
|
|
|
396
404
|
console.log(makeLine(chalk.white('SELECT CONNECTION METHOD:')));
|
|
397
405
|
console.log(makeLine(''));
|
|
@@ -539,7 +547,7 @@ const setupConnection = async (provider, option) => {
|
|
|
539
547
|
// Show instructions for this field
|
|
540
548
|
console.clear();
|
|
541
549
|
displayBanner();
|
|
542
|
-
|
|
550
|
+
drawBoxHeaderContinue(`CONNECT TO ${provider.name}`, boxWidth);
|
|
543
551
|
|
|
544
552
|
const instructions = getCredentialInstructions(provider, option, field);
|
|
545
553
|
|
|
@@ -656,7 +664,7 @@ const selectModel = async (provider) => {
|
|
|
656
664
|
|
|
657
665
|
console.clear();
|
|
658
666
|
displayBanner();
|
|
659
|
-
|
|
667
|
+
drawBoxHeaderContinue('SELECT MODEL', boxWidth);
|
|
660
668
|
|
|
661
669
|
const models = provider.models || [];
|
|
662
670
|
|
package/src/services/ai/index.js
CHANGED
|
@@ -150,11 +150,54 @@ const validateConnection = async (providerId, optionId, credentials) => {
|
|
|
150
150
|
// Validation functions for each provider
|
|
151
151
|
const validateAnthropic = async (credentials) => {
|
|
152
152
|
try {
|
|
153
|
+
const token = credentials.apiKey || credentials.sessionKey || credentials.accessToken;
|
|
154
|
+
|
|
155
|
+
// Check if it's an OAuth token (sk-ant-oat...) vs API key (sk-ant-api...)
|
|
156
|
+
const isOAuthToken = token && token.startsWith('sk-ant-oat');
|
|
157
|
+
|
|
158
|
+
if (isOAuthToken) {
|
|
159
|
+
// OAuth tokens use Bearer auth and claude.ai endpoint
|
|
160
|
+
const response = await fetch('https://api.claude.ai/api/organizations', {
|
|
161
|
+
method: 'GET',
|
|
162
|
+
headers: {
|
|
163
|
+
'Authorization': `Bearer ${token}`,
|
|
164
|
+
'Content-Type': 'application/json',
|
|
165
|
+
'User-Agent': 'HQX-CLI/1.0'
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (response.ok) {
|
|
170
|
+
return { valid: true, tokenType: 'oauth', subscriptionType: credentials.subscriptionType || 'max' };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Try alternate endpoint
|
|
174
|
+
const altResponse = await fetch('https://claude.ai/api/auth/session', {
|
|
175
|
+
method: 'GET',
|
|
176
|
+
headers: {
|
|
177
|
+
'Authorization': `Bearer ${token}`,
|
|
178
|
+
'Cookie': `sessionKey=${token}`
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
if (altResponse.ok) {
|
|
183
|
+
return { valid: true, tokenType: 'oauth', subscriptionType: credentials.subscriptionType || 'max' };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// For OAuth tokens from Keychain, trust them without validation
|
|
187
|
+
// since the Keychain already verified the user
|
|
188
|
+
if (credentials.fromKeychain) {
|
|
189
|
+
return { valid: true, tokenType: 'oauth', subscriptionType: credentials.subscriptionType || 'max', trusted: true };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return { valid: false, error: 'OAuth token expired or invalid' };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Standard API key validation
|
|
153
196
|
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
154
197
|
method: 'POST',
|
|
155
198
|
headers: {
|
|
156
199
|
'Content-Type': 'application/json',
|
|
157
|
-
'x-api-key':
|
|
200
|
+
'x-api-key': token,
|
|
158
201
|
'anthropic-version': '2023-06-01'
|
|
159
202
|
},
|
|
160
203
|
body: JSON.stringify({
|
|
@@ -165,7 +208,7 @@ const validateAnthropic = async (credentials) => {
|
|
|
165
208
|
});
|
|
166
209
|
|
|
167
210
|
if (response.ok) {
|
|
168
|
-
return { valid: true };
|
|
211
|
+
return { valid: true, tokenType: 'api_key' };
|
|
169
212
|
}
|
|
170
213
|
|
|
171
214
|
const error = await response.json();
|