byterover-cli 2.3.3 → 2.4.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.
- package/dist/agent/infra/http/internal-llm-http-service.d.ts +4 -31
- package/dist/agent/infra/http/internal-llm-http-service.js +7 -40
- package/dist/agent/infra/llm/generators/byterover-content-generator.js +2 -2
- package/dist/server/infra/auth/oauth-service.js +6 -0
- package/dist/server/infra/auth/oidc-discovery-service.js +3 -0
- package/dist/server/infra/cogit/http-cogit-push-service.js +3 -0
- package/dist/server/infra/http/authenticated-http-client.js +19 -4
- package/dist/server/infra/http/models-dev-client.js +3 -0
- package/dist/server/infra/http/openrouter-api-client.js +3 -0
- package/dist/server/infra/http/provider-model-fetchers.js +7 -0
- package/dist/server/infra/http/proxy-config.d.ts +5 -0
- package/dist/server/infra/http/proxy-config.js +10 -0
- package/dist/server/infra/hub/hub-install-service.js +3 -0
- package/dist/server/infra/hub/hub-registry-service.js +3 -0
- package/dist/server/infra/memory/http-memory-storage-service.js +3 -0
- package/dist/server/infra/provider-oauth/refresh-token-exchange.js +3 -0
- package/dist/server/infra/provider-oauth/token-exchange.js +3 -0
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
|
@@ -51,8 +51,6 @@ export declare class ByteRoverLlmHttpService {
|
|
|
51
51
|
* Call ByteRover REST LLM service to generate content.
|
|
52
52
|
*
|
|
53
53
|
* Simple forward to remote REST API - delegates all formatting to backend.
|
|
54
|
-
* Supports both Gemini and Claude formats - the correct format is determined
|
|
55
|
-
* automatically based on the model name.
|
|
56
54
|
*
|
|
57
55
|
* Parameter structure differs by provider:
|
|
58
56
|
* - Gemini: contents = Content[], config = GenerateContentConfig
|
|
@@ -60,27 +58,22 @@ export declare class ByteRoverLlmHttpService {
|
|
|
60
58
|
*
|
|
61
59
|
* @param contents - For Gemini: Content[]. For Claude: MessageCreateParamsNonStreaming (complete body)
|
|
62
60
|
* @param config - For Gemini: GenerateContentConfig. For Claude: RequestOptions (optional HTTP options)
|
|
63
|
-
* @param model - Model to use (detects provider from model name)
|
|
64
61
|
* @param executionMetadata - Optional execution metadata (mode, executionContext)
|
|
65
62
|
* @returns Response in GenerateContentResponse format
|
|
66
63
|
*/
|
|
67
|
-
generateContent(contents: Content[] | MessageCreateParamsNonStreaming, config: GenerateContentConfig | RequestOptions,
|
|
64
|
+
generateContent(contents: Content[] | MessageCreateParamsNonStreaming, config: GenerateContentConfig | RequestOptions, executionMetadata?: Record<string, unknown>): Promise<GenerateContentResponse>;
|
|
68
65
|
/**
|
|
69
66
|
* Call ByteRover REST LLM service to generate content with streaming.
|
|
70
67
|
*
|
|
71
|
-
* Currently falls back to non-streaming endpoint
|
|
72
|
-
*
|
|
73
|
-
* response and yields them as separate chunks.
|
|
74
|
-
*
|
|
75
|
-
* When backend streaming is available, this will use SSE for true streaming.
|
|
68
|
+
* Currently falls back to non-streaming endpoint. Extracts thinking/reasoning
|
|
69
|
+
* from the complete response and yields them as separate chunks.
|
|
76
70
|
*
|
|
77
71
|
* @param contents - For Gemini: Content[]. For Claude: MessageCreateParamsNonStreaming (complete body)
|
|
78
72
|
* @param config - For Gemini: GenerateContentConfig. For Claude: RequestOptions (optional HTTP options)
|
|
79
|
-
* @param model - Model to use (detects provider from model name)
|
|
80
73
|
* @param executionMetadata - Optional execution metadata (mode, executionContext)
|
|
81
74
|
* @yields GenerateContentChunk objects as they are generated
|
|
82
75
|
*/
|
|
83
|
-
generateContentStream(contents: Content[] | MessageCreateParamsNonStreaming, config: GenerateContentConfig | RequestOptions,
|
|
76
|
+
generateContentStream(contents: Content[] | MessageCreateParamsNonStreaming, config: GenerateContentConfig | RequestOptions, executionMetadata?: Record<string, unknown>): AsyncGenerator<GenerateContentChunk>;
|
|
84
77
|
/**
|
|
85
78
|
* Call the ByteRover REST Generate endpoint.
|
|
86
79
|
*
|
|
@@ -91,26 +84,6 @@ export declare class ByteRoverLlmHttpService {
|
|
|
91
84
|
* @throws Error if the request fails
|
|
92
85
|
*/
|
|
93
86
|
private callHttpGenerate;
|
|
94
|
-
/**
|
|
95
|
-
* Detect LLM provider from model identifier.
|
|
96
|
-
*
|
|
97
|
-
* Determines which provider (Claude or Gemini) to use based on the model name.
|
|
98
|
-
* Defaults to Gemini if the model doesn't match Claude patterns.
|
|
99
|
-
*
|
|
100
|
-
* @param model - Model identifier (e.g., 'claude-3-5-sonnet', 'gemini-2.5-flash')
|
|
101
|
-
* @returns Provider name: 'claude' or 'gemini'
|
|
102
|
-
*/
|
|
103
|
-
private detectProviderFromModel;
|
|
104
|
-
/**
|
|
105
|
-
* Detect appropriate GCP region from model identifier.
|
|
106
|
-
*
|
|
107
|
-
* Routes Claude models to us-east5 and Gemini models to global.
|
|
108
|
-
* This ensures compatibility with the provider's available regions on Vertex AI.
|
|
109
|
-
*
|
|
110
|
-
* @param model - Model identifier (e.g., 'claude-3-5-sonnet', 'gemini-2.5-flash')
|
|
111
|
-
* @returns GCP region identifier ('us-east5' or 'global')
|
|
112
|
-
*/
|
|
113
|
-
private detectRegionFromModel;
|
|
114
87
|
/**
|
|
115
88
|
* Extract content chunks from a complete response.
|
|
116
89
|
*
|
|
@@ -33,7 +33,7 @@ export class ByteRoverLlmHttpService {
|
|
|
33
33
|
this.config = {
|
|
34
34
|
apiBaseUrl: config.apiBaseUrl,
|
|
35
35
|
projectId: config.projectId ?? 'byterover',
|
|
36
|
-
region: config.region ?? '
|
|
36
|
+
region: config.region ?? 'global',
|
|
37
37
|
sessionKey: config.sessionKey,
|
|
38
38
|
spaceId: config.spaceId,
|
|
39
39
|
teamId: config.teamId,
|
|
@@ -44,8 +44,6 @@ export class ByteRoverLlmHttpService {
|
|
|
44
44
|
* Call ByteRover REST LLM service to generate content.
|
|
45
45
|
*
|
|
46
46
|
* Simple forward to remote REST API - delegates all formatting to backend.
|
|
47
|
-
* Supports both Gemini and Claude formats - the correct format is determined
|
|
48
|
-
* automatically based on the model name.
|
|
49
47
|
*
|
|
50
48
|
* Parameter structure differs by provider:
|
|
51
49
|
* - Gemini: contents = Content[], config = GenerateContentConfig
|
|
@@ -53,21 +51,18 @@ export class ByteRoverLlmHttpService {
|
|
|
53
51
|
*
|
|
54
52
|
* @param contents - For Gemini: Content[]. For Claude: MessageCreateParamsNonStreaming (complete body)
|
|
55
53
|
* @param config - For Gemini: GenerateContentConfig. For Claude: RequestOptions (optional HTTP options)
|
|
56
|
-
* @param model - Model to use (detects provider from model name)
|
|
57
54
|
* @param executionMetadata - Optional execution metadata (mode, executionContext)
|
|
58
55
|
* @returns Response in GenerateContentResponse format
|
|
59
56
|
*/
|
|
60
|
-
async generateContent(contents, config,
|
|
57
|
+
async generateContent(contents, config, executionMetadata) {
|
|
61
58
|
const request = {
|
|
62
59
|
executionMetadata: JSON.stringify(executionMetadata ?? {}),
|
|
63
60
|
params: {
|
|
64
61
|
config,
|
|
65
62
|
contents,
|
|
66
|
-
model,
|
|
67
63
|
},
|
|
68
64
|
project_id: typeof this.config.projectId === 'function' ? this.config.projectId() : this.config.projectId,
|
|
69
|
-
|
|
70
|
-
region: this.detectRegionFromModel(model),
|
|
65
|
+
region: this.config.region,
|
|
71
66
|
spaceId: typeof this.config.spaceId === 'function' ? this.config.spaceId() : this.config.spaceId,
|
|
72
67
|
teamId: typeof this.config.teamId === 'function' ? this.config.teamId() : this.config.teamId,
|
|
73
68
|
};
|
|
@@ -76,22 +71,18 @@ export class ByteRoverLlmHttpService {
|
|
|
76
71
|
/**
|
|
77
72
|
* Call ByteRover REST LLM service to generate content with streaming.
|
|
78
73
|
*
|
|
79
|
-
* Currently falls back to non-streaming endpoint
|
|
80
|
-
*
|
|
81
|
-
* response and yields them as separate chunks.
|
|
82
|
-
*
|
|
83
|
-
* When backend streaming is available, this will use SSE for true streaming.
|
|
74
|
+
* Currently falls back to non-streaming endpoint. Extracts thinking/reasoning
|
|
75
|
+
* from the complete response and yields them as separate chunks.
|
|
84
76
|
*
|
|
85
77
|
* @param contents - For Gemini: Content[]. For Claude: MessageCreateParamsNonStreaming (complete body)
|
|
86
78
|
* @param config - For Gemini: GenerateContentConfig. For Claude: RequestOptions (optional HTTP options)
|
|
87
|
-
* @param model - Model to use (detects provider from model name)
|
|
88
79
|
* @param executionMetadata - Optional execution metadata (mode, executionContext)
|
|
89
80
|
* @yields GenerateContentChunk objects as they are generated
|
|
90
81
|
*/
|
|
91
|
-
async *generateContentStream(contents, config,
|
|
82
|
+
async *generateContentStream(contents, config, executionMetadata) {
|
|
92
83
|
// Fall back to non-streaming endpoint and simulate streaming
|
|
93
84
|
// by extracting thinking from the complete response
|
|
94
|
-
const response = await this.generateContent(contents, config,
|
|
85
|
+
const response = await this.generateContent(contents, config, executionMetadata);
|
|
95
86
|
// Extract and yield thinking/reasoning chunks first
|
|
96
87
|
yield* this.extractThinkingFromResponse(response);
|
|
97
88
|
// Then yield the final content
|
|
@@ -115,30 +106,6 @@ export class ByteRoverLlmHttpService {
|
|
|
115
106
|
});
|
|
116
107
|
return httpResponse.data;
|
|
117
108
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Detect LLM provider from model identifier.
|
|
120
|
-
*
|
|
121
|
-
* Determines which provider (Claude or Gemini) to use based on the model name.
|
|
122
|
-
* Defaults to Gemini if the model doesn't match Claude patterns.
|
|
123
|
-
*
|
|
124
|
-
* @param model - Model identifier (e.g., 'claude-3-5-sonnet', 'gemini-2.5-flash')
|
|
125
|
-
* @returns Provider name: 'claude' or 'gemini'
|
|
126
|
-
*/
|
|
127
|
-
detectProviderFromModel(model) {
|
|
128
|
-
return model.toLowerCase().startsWith('claude') ? 'claude' : 'gemini';
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Detect appropriate GCP region from model identifier.
|
|
132
|
-
*
|
|
133
|
-
* Routes Claude models to us-east5 and Gemini models to global.
|
|
134
|
-
* This ensures compatibility with the provider's available regions on Vertex AI.
|
|
135
|
-
*
|
|
136
|
-
* @param model - Model identifier (e.g., 'claude-3-5-sonnet', 'gemini-2.5-flash')
|
|
137
|
-
* @returns GCP region identifier ('us-east5' or 'global')
|
|
138
|
-
*/
|
|
139
|
-
detectRegionFromModel(model) {
|
|
140
|
-
return model.toLowerCase().startsWith('claude') ? 'us-east5' : 'global';
|
|
141
|
-
}
|
|
142
109
|
/**
|
|
143
110
|
* Extract content chunks from a complete response.
|
|
144
111
|
*
|
|
@@ -87,7 +87,7 @@ export class ByteRoverContentGenerator {
|
|
|
87
87
|
};
|
|
88
88
|
// // Debug: Log taskId for tracking
|
|
89
89
|
// appendFileSync('debug-taskid.log', `[${new Date().toISOString()}] taskId from request: "${request.taskId}"\n`)
|
|
90
|
-
const rawResponse = await this.httpService.generateContent(contents, config,
|
|
90
|
+
const rawResponse = await this.httpService.generateContent(contents, config, executionMetadata);
|
|
91
91
|
// Parse response to internal format
|
|
92
92
|
const messages = this.formatter.parseResponse(rawResponse);
|
|
93
93
|
const lastMessage = messages.at(-1);
|
|
@@ -143,7 +143,7 @@ export class ByteRoverContentGenerator {
|
|
|
143
143
|
const contents = this.providerType === 'claude' ? genConfig : formattedMessages;
|
|
144
144
|
const config = this.providerType === 'claude' ? {} : genConfig;
|
|
145
145
|
// Stream from HTTP service
|
|
146
|
-
yield* this.httpService.generateContentStream(contents, config,
|
|
146
|
+
yield* this.httpService.generateContentStream(contents, config, executionMetadata);
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* Build Claude-specific generation configuration.
|
|
@@ -3,6 +3,7 @@ import axios, { isAxiosError } from 'axios';
|
|
|
3
3
|
import crypto from 'node:crypto';
|
|
4
4
|
import { OAuthTokenData } from '../../core/domain/entities/oauth-token-data.js';
|
|
5
5
|
import { AuthenticationError } from '../../core/domain/errors/auth-error.js';
|
|
6
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
6
7
|
export const NETWORK_ERROR_CODE = {
|
|
7
8
|
EAI_AGAIN: 'EAI_AGAIN',
|
|
8
9
|
ECONNABORTED: 'ECONNABORTED',
|
|
@@ -49,6 +50,8 @@ export class OAuthService {
|
|
|
49
50
|
headers: {
|
|
50
51
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
51
52
|
},
|
|
53
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
54
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
52
55
|
});
|
|
53
56
|
return this.parseTokenResponse(response.data);
|
|
54
57
|
}
|
|
@@ -91,6 +94,9 @@ export class OAuthService {
|
|
|
91
94
|
client_secret: this.config.clientSecret,
|
|
92
95
|
grant_type: 'refresh_token',
|
|
93
96
|
refresh_token: refreshToken,
|
|
97
|
+
}, {
|
|
98
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
99
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
94
100
|
});
|
|
95
101
|
return this.parseTokenResponse(response.data);
|
|
96
102
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
2
|
import { DiscoveryError, DiscoveryNetworkError, DiscoveryTimeoutError } from '../../core/domain/errors/discovery-error.js';
|
|
3
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
3
4
|
/**
|
|
4
5
|
* OIDC discovery service implementation.
|
|
5
6
|
* Fetches OIDC configuration from the well-known endpoint with in-memory caching.
|
|
@@ -76,6 +77,8 @@ export class OidcDiscoveryService {
|
|
|
76
77
|
try {
|
|
77
78
|
const wellKnownUrl = `${issuerUrl}/.well-known/openid-configuration`;
|
|
78
79
|
const response = await axios.get(wellKnownUrl, {
|
|
80
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
81
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
79
82
|
timeout: this.timeoutMs,
|
|
80
83
|
});
|
|
81
84
|
// Validate required fields
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { CogitPushResponse } from '../../core/domain/entities/cogit-push-response.js';
|
|
4
4
|
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
5
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
5
6
|
/**
|
|
6
7
|
* Extracts the current SHA from an error response details field.
|
|
7
8
|
* Error format: "...Expected SHA 'xxx' but current SHA is 'yyy'..."
|
|
@@ -96,6 +97,8 @@ export class HttpCogitPushService {
|
|
|
96
97
|
headers: {
|
|
97
98
|
'x-byterover-session-id': params.sessionKey,
|
|
98
99
|
},
|
|
100
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
101
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
99
102
|
timeout: this.config.timeout,
|
|
100
103
|
});
|
|
101
104
|
return CogitPushResponse.fromJson(response.data);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
2
3
|
/**
|
|
3
4
|
* HTTP client implementation that automatically adds authentication headers to all requests.
|
|
4
5
|
*
|
|
@@ -27,6 +28,8 @@ export class AuthenticatedHttpClient {
|
|
|
27
28
|
try {
|
|
28
29
|
const axiosConfig = {
|
|
29
30
|
headers: this.buildHeaders(config?.headers),
|
|
31
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
32
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
30
33
|
timeout: config?.timeout,
|
|
31
34
|
};
|
|
32
35
|
const response = await axios.get(url, axiosConfig);
|
|
@@ -48,6 +51,8 @@ export class AuthenticatedHttpClient {
|
|
|
48
51
|
try {
|
|
49
52
|
const axiosConfig = {
|
|
50
53
|
headers: this.buildHeaders(config?.headers),
|
|
54
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
55
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
51
56
|
timeout: config?.timeout,
|
|
52
57
|
};
|
|
53
58
|
const response = await axios.post(url, data, axiosConfig);
|
|
@@ -69,6 +74,8 @@ export class AuthenticatedHttpClient {
|
|
|
69
74
|
try {
|
|
70
75
|
const axiosConfig = {
|
|
71
76
|
headers: this.buildHeaders(config?.headers),
|
|
77
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
78
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
72
79
|
timeout: config?.timeout,
|
|
73
80
|
};
|
|
74
81
|
const response = await axios.put(url, data, axiosConfig);
|
|
@@ -107,13 +114,21 @@ export class AuthenticatedHttpClient {
|
|
|
107
114
|
// Server responded with error status
|
|
108
115
|
return new Error(`HTTP ${error.response.status}: ${error.response.statusText}`);
|
|
109
116
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return new Error(`
|
|
117
|
+
// Enterprise Proxy / SSL Checks
|
|
118
|
+
if (error.code === 'SELF_SIGNED_CERT_IN_CHAIN' || error.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || error.code === 'CERT_HAS_EXPIRED') {
|
|
119
|
+
return new Error(`SSL Certificate Validation Failed (${error.code}). Your company may be using SSL Inspection.\n` +
|
|
120
|
+
`Solution: Set the NODE_EXTRA_CA_CERTS environment variable to your corporate CA certificate path.\n` +
|
|
121
|
+
`Example: export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem`);
|
|
122
|
+
}
|
|
123
|
+
const isTimeout = error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT' || error.message.includes('timeout');
|
|
124
|
+
const isRefused = error.code === 'ECONNREFUSED';
|
|
125
|
+
if (isTimeout || isRefused) {
|
|
126
|
+
return new Error(`Connection Failed (${error.code || 'TIMEOUT'}). If you are behind a corporate firewall, configure your proxy:\n` +
|
|
127
|
+
` export HTTPS_PROXY=http://proxy-host:port`);
|
|
113
128
|
}
|
|
114
129
|
if (error.request) {
|
|
115
130
|
// Request was made but no response received
|
|
116
|
-
return new Error('Network error: No response received from server');
|
|
131
|
+
return new Error('Network error: No response received from server. Check your proxy or internet connection.');
|
|
117
132
|
}
|
|
118
133
|
}
|
|
119
134
|
// Generic error
|
|
@@ -10,6 +10,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
10
10
|
import { dirname, join } from 'node:path';
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import { getGlobalDataDir } from '../../utils/global-data-path.js';
|
|
13
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
13
14
|
const CacheEnvelopeSchema = z.object({
|
|
14
15
|
data: z.record(z.unknown()),
|
|
15
16
|
timestamp: z.number(),
|
|
@@ -57,6 +58,8 @@ export class ModelsDevClient {
|
|
|
57
58
|
}
|
|
58
59
|
async fetchAndCache() {
|
|
59
60
|
const response = await axios.get(MODELS_DEV_URL, {
|
|
61
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
62
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
60
63
|
timeout: FETCH_TIMEOUT_MS,
|
|
61
64
|
});
|
|
62
65
|
const { data } = response;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Uses the OpenRouter REST API: https://openrouter.ai/api/v1
|
|
9
9
|
*/
|
|
10
10
|
import axios, { isAxiosError } from 'axios';
|
|
11
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
11
12
|
const DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
12
13
|
const DEFAULT_CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
|
13
14
|
/**
|
|
@@ -100,6 +101,8 @@ export class OpenRouterApiClient {
|
|
|
100
101
|
'HTTP-Referer': this.httpReferer,
|
|
101
102
|
'X-Title': this.xTitle,
|
|
102
103
|
},
|
|
104
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
105
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
103
106
|
timeout: 30_000,
|
|
104
107
|
});
|
|
105
108
|
return response.data.data.map((model) => this.normalizeModel(model));
|
|
@@ -16,6 +16,7 @@ import { APICallError, generateText } from 'ai';
|
|
|
16
16
|
import axios, { isAxiosError } from 'axios';
|
|
17
17
|
import OpenAI from 'openai';
|
|
18
18
|
import { getModelsDevClient as getModelsDevClientDefault } from './models-dev-client.js';
|
|
19
|
+
import { ProxyConfig } from './proxy-config.js';
|
|
19
20
|
const DEFAULT_CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
|
20
21
|
const ANTHROPIC_KNOWN_MODELS = {
|
|
21
22
|
'claude-3-5-haiku-20241022': { contextLength: 200_000, inputPerM: 0.8, outputPerM: 4 },
|
|
@@ -346,6 +347,8 @@ export class OpenAICompatibleModelFetcher {
|
|
|
346
347
|
}
|
|
347
348
|
const response = await axios.get(`${this.baseUrl}/models`, {
|
|
348
349
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
350
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
351
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
349
352
|
timeout: 30_000,
|
|
350
353
|
});
|
|
351
354
|
// Handle different response formats:
|
|
@@ -376,6 +379,8 @@ export class OpenAICompatibleModelFetcher {
|
|
|
376
379
|
try {
|
|
377
380
|
await axios.get(`${this.baseUrl}/models`, {
|
|
378
381
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
382
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
383
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
379
384
|
timeout: 15_000,
|
|
380
385
|
});
|
|
381
386
|
return { isValid: true };
|
|
@@ -431,6 +436,8 @@ export class ChatBasedModelFetcher {
|
|
|
431
436
|
Authorization: `Bearer ${apiKey}`,
|
|
432
437
|
'Content-Type': 'application/json',
|
|
433
438
|
},
|
|
439
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
440
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
434
441
|
timeout: 15_000,
|
|
435
442
|
});
|
|
436
443
|
return { isValid: true };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import axios, { isAxiosError } from 'axios';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { BRV_DIR, CONTEXT_TREE_DIR } from '../../constants.js';
|
|
4
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
4
5
|
import { buildAuthHeaders } from './hub-auth-headers.js';
|
|
5
6
|
export class HubInstallService {
|
|
6
7
|
fileService;
|
|
@@ -30,6 +31,8 @@ export class HubInstallService {
|
|
|
30
31
|
const headers = buildAuthHeaders(auth ?? {});
|
|
31
32
|
const response = await axios.get(url, {
|
|
32
33
|
headers,
|
|
34
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
35
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
33
36
|
responseType: 'text',
|
|
34
37
|
timeout: 15_000,
|
|
35
38
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import axios, { isAxiosError } from 'axios';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
4
5
|
import { buildAuthHeaders } from './hub-auth-headers.js';
|
|
5
6
|
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
6
7
|
const HubEntrySchema = z.object({
|
|
@@ -69,6 +70,8 @@ export class HubRegistryService {
|
|
|
69
70
|
});
|
|
70
71
|
const response = await axios.get(this.registryUrl, {
|
|
71
72
|
headers,
|
|
73
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
74
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
72
75
|
timeout: this.timeoutMs,
|
|
73
76
|
});
|
|
74
77
|
const validated = this.parseRegistryResponse(response.data);
|
|
@@ -4,6 +4,7 @@ import { PresignedUrl } from '../../core/domain/entities/presigned-url.js';
|
|
|
4
4
|
import { PresignedUrlsResponse } from '../../core/domain/entities/presigned-urls-response.js';
|
|
5
5
|
import { getErrorMessage } from '../../utils/error-helpers.js';
|
|
6
6
|
import { AuthenticatedHttpClient } from '../http/authenticated-http-client.js';
|
|
7
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
7
8
|
/**
|
|
8
9
|
* HTTP implementation of IMemoryStorageService for ByteRover CoGit service.
|
|
9
10
|
* Handles uploading playbooks to blob storage.
|
|
@@ -55,6 +56,8 @@ export class HttpMemoryStorageService {
|
|
|
55
56
|
headers: {
|
|
56
57
|
'Content-Type': 'application/json',
|
|
57
58
|
},
|
|
59
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
60
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
58
61
|
timeout: this.config.timeout,
|
|
59
62
|
});
|
|
60
63
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import axios, { isAxiosError } from 'axios';
|
|
3
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
3
4
|
import { extractOAuthErrorFields, ProviderTokenExchangeError } from './errors.js';
|
|
4
5
|
import { ProviderTokenResponseSchema } from './types.js';
|
|
5
6
|
/**
|
|
@@ -20,6 +21,8 @@ export async function exchangeRefreshToken(params) {
|
|
|
20
21
|
headers: {
|
|
21
22
|
'Content-Type': params.contentType,
|
|
22
23
|
},
|
|
24
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
25
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
23
26
|
timeout: 30_000,
|
|
24
27
|
});
|
|
25
28
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import axios, { isAxiosError } from 'axios';
|
|
3
|
+
import { ProxyConfig } from '../http/proxy-config.js';
|
|
3
4
|
import { extractOAuthErrorFields, ProviderTokenExchangeError } from './errors.js';
|
|
4
5
|
import { ProviderTokenResponseSchema } from './types.js';
|
|
5
6
|
/**
|
|
@@ -25,6 +26,8 @@ export async function exchangeCodeForTokens(params) {
|
|
|
25
26
|
headers: {
|
|
26
27
|
'Content-Type': params.contentType,
|
|
27
28
|
},
|
|
29
|
+
httpAgent: ProxyConfig.getProxyAgent(),
|
|
30
|
+
httpsAgent: ProxyConfig.getProxyAgent(),
|
|
28
31
|
timeout: 30_000,
|
|
29
32
|
});
|
|
30
33
|
}
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "byterover-cli",
|
|
3
3
|
"description": "ByteRover's CLI",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"author": "ByteRover",
|
|
6
6
|
"bin": {
|
|
7
7
|
"brv": "./bin/run.js"
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"officeparser": "^6.0.4",
|
|
56
56
|
"open": "^10.2.0",
|
|
57
57
|
"openai": "^6.9.1",
|
|
58
|
+
"proxy-agent": "^7.0.0",
|
|
58
59
|
"react": "^19.2.1",
|
|
59
60
|
"react-router-dom": "^7.13.0",
|
|
60
61
|
"remark-parse": "^11.0.0",
|