@redonvn/cli 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.
- package/README.md +99 -0
- package/bin/redai.js +22 -0
- package/dist/auth/client-id.d.ts +8 -0
- package/dist/auth/client-id.js +41 -0
- package/dist/auth/client-id.js.map +1 -0
- package/dist/auth/store.d.ts +16 -0
- package/dist/auth/store.js +39 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/cli/commands/login.d.ts +6 -0
- package/dist/cli/commands/login.js +82 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +1 -0
- package/dist/cli/commands/logout.js +18 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/oauth.d.ts +11 -0
- package/dist/cli/commands/oauth.js +311 -0
- package/dist/cli/commands/oauth.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.js +24 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/start.d.ts +1 -0
- package/dist/cli/commands/start.js +26 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +1 -0
- package/dist/cli/commands/status.js +51 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +127 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli-router/detect.d.ts +13 -0
- package/dist/cli-router/detect.js +58 -0
- package/dist/cli-router/detect.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/router.d.ts +17 -0
- package/dist/daemon/router.js +39 -0
- package/dist/daemon/router.js.map +1 -0
- package/dist/daemon/tunnel.d.ts +10 -0
- package/dist/daemon/tunnel.js +156 -0
- package/dist/daemon/tunnel.js.map +1 -0
- package/dist/llm/llm-request.d.ts +9 -0
- package/dist/llm/llm-request.js +98 -0
- package/dist/llm/llm-request.js.map +1 -0
- package/dist/llm/oauth/antigravity-oauth.d.ts +22 -0
- package/dist/llm/oauth/antigravity-oauth.js +128 -0
- package/dist/llm/oauth/antigravity-oauth.js.map +1 -0
- package/dist/llm/oauth/callback-server.d.ts +18 -0
- package/dist/llm/oauth/callback-server.js +78 -0
- package/dist/llm/oauth/callback-server.js.map +1 -0
- package/dist/llm/oauth/claude-oauth.d.ts +29 -0
- package/dist/llm/oauth/claude-oauth.js +115 -0
- package/dist/llm/oauth/claude-oauth.js.map +1 -0
- package/dist/llm/oauth/codex-oauth.d.ts +21 -0
- package/dist/llm/oauth/codex-oauth.js +137 -0
- package/dist/llm/oauth/codex-oauth.js.map +1 -0
- package/dist/llm/oauth/gemini-oauth.d.ts +26 -0
- package/dist/llm/oauth/gemini-oauth.js +132 -0
- package/dist/llm/oauth/gemini-oauth.js.map +1 -0
- package/dist/llm/oauth/iflow-oauth.d.ts +26 -0
- package/dist/llm/oauth/iflow-oauth.js +151 -0
- package/dist/llm/oauth/iflow-oauth.js.map +1 -0
- package/dist/llm/oauth/kimi-oauth.d.ts +16 -0
- package/dist/llm/oauth/kimi-oauth.js +126 -0
- package/dist/llm/oauth/kimi-oauth.js.map +1 -0
- package/dist/llm/oauth/open-browser.d.ts +5 -0
- package/dist/llm/oauth/open-browser.js +32 -0
- package/dist/llm/oauth/open-browser.js.map +1 -0
- package/dist/llm/oauth/pkce.d.ts +12 -0
- package/dist/llm/oauth/pkce.js +27 -0
- package/dist/llm/oauth/pkce.js.map +1 -0
- package/dist/llm/oauth/qwen-oauth.d.ts +27 -0
- package/dist/llm/oauth/qwen-oauth.js +138 -0
- package/dist/llm/oauth/qwen-oauth.js.map +1 -0
- package/dist/llm/oauth/store.d.ts +34 -0
- package/dist/llm/oauth/store.js +72 -0
- package/dist/llm/oauth/store.js.map +1 -0
- package/dist/llm/oauth/xai-oauth.d.ts +28 -0
- package/dist/llm/oauth/xai-oauth.js +132 -0
- package/dist/llm/oauth/xai-oauth.js.map +1 -0
- package/dist/llm/providers/antigravity.d.ts +23 -0
- package/dist/llm/providers/antigravity.js +103 -0
- package/dist/llm/providers/antigravity.js.map +1 -0
- package/dist/llm/providers/claude.d.ts +36 -0
- package/dist/llm/providers/claude.js +148 -0
- package/dist/llm/providers/claude.js.map +1 -0
- package/dist/llm/providers/codex.d.ts +23 -0
- package/dist/llm/providers/codex.js +122 -0
- package/dist/llm/providers/codex.js.map +1 -0
- package/dist/llm/providers/gemini.d.ts +23 -0
- package/dist/llm/providers/gemini.js +112 -0
- package/dist/llm/providers/gemini.js.map +1 -0
- package/dist/llm/providers/generic-client.d.ts +45 -0
- package/dist/llm/providers/generic-client.js +98 -0
- package/dist/llm/providers/generic-client.js.map +1 -0
- package/dist/llm/providers/iflow.d.ts +8 -0
- package/dist/llm/providers/iflow.js +15 -0
- package/dist/llm/providers/iflow.js.map +1 -0
- package/dist/llm/providers/kimi.d.ts +8 -0
- package/dist/llm/providers/kimi.js +16 -0
- package/dist/llm/providers/kimi.js.map +1 -0
- package/dist/llm/providers/qwen.d.ts +8 -0
- package/dist/llm/providers/qwen.js +15 -0
- package/dist/llm/providers/qwen.js.map +1 -0
- package/dist/llm/providers/xai.d.ts +8 -0
- package/dist/llm/providers/xai.js +15 -0
- package/dist/llm/providers/xai.js.map +1 -0
- package/dist/llm/selector.d.ts +14 -0
- package/dist/llm/selector.js +81 -0
- package/dist/llm/selector.js.map +1 -0
- package/dist/server/http-server.d.ts +22 -0
- package/dist/server/http-server.js +194 -0
- package/dist/server/http-server.js.map +1 -0
- package/dist/tools/bash.d.ts +7 -0
- package/dist/tools/bash.js +61 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit.d.ts +4 -0
- package/dist/tools/edit.js +35 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/glob.d.ts +5 -0
- package/dist/tools/glob.js +27 -0
- package/dist/tools/glob.js.map +1 -0
- package/dist/tools/grep.d.ts +5 -0
- package/dist/tools/grep.js +63 -0
- package/dist/tools/grep.js.map +1 -0
- package/dist/tools/read.d.ts +6 -0
- package/dist/tools/read.js +25 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/registry.d.ts +8 -0
- package/dist/tools/registry.js +43 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/run-cli.d.ts +7 -0
- package/dist/tools/run-cli.js +83 -0
- package/dist/tools/run-cli.js.map +1 -0
- package/dist/tools/webfetch.d.ts +7 -0
- package/dist/tools/webfetch.js +26 -0
- package/dist/tools/webfetch.js.map +1 -0
- package/dist/tools/write.d.ts +5 -0
- package/dist/tools/write.js +29 -0
- package/dist/tools/write.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.oauthDir = oauthDir;
|
|
7
|
+
exports.oauthFilePath = oauthFilePath;
|
|
8
|
+
exports.saveToken = saveToken;
|
|
9
|
+
exports.loadToken = loadToken;
|
|
10
|
+
exports.listAccounts = listAccounts;
|
|
11
|
+
exports.deleteToken = deleteToken;
|
|
12
|
+
exports.listProvidersWithLogin = listProvidersWithLogin;
|
|
13
|
+
const fs_1 = __importDefault(require("fs"));
|
|
14
|
+
const path_1 = __importDefault(require("path"));
|
|
15
|
+
const config_1 = require("../../config");
|
|
16
|
+
function oauthDir(provider) {
|
|
17
|
+
return path_1.default.join(config_1.REDAI_CONFIG_DIR, 'oauth', provider);
|
|
18
|
+
}
|
|
19
|
+
function oauthFilePath(provider, account = 'default') {
|
|
20
|
+
return path_1.default.join(oauthDir(provider), `${account}.json`);
|
|
21
|
+
}
|
|
22
|
+
function ensureDir(provider) {
|
|
23
|
+
const dir = oauthDir(provider);
|
|
24
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
25
|
+
fs_1.default.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function saveToken(provider, token) {
|
|
29
|
+
ensureDir(provider);
|
|
30
|
+
const filePath = oauthFilePath(provider, token.account);
|
|
31
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify(token, null, 2), {
|
|
32
|
+
encoding: 'utf8',
|
|
33
|
+
mode: 0o600,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function loadToken(provider, account = 'default') {
|
|
37
|
+
const filePath = oauthFilePath(provider, account);
|
|
38
|
+
if (!fs_1.default.existsSync(filePath))
|
|
39
|
+
return null;
|
|
40
|
+
try {
|
|
41
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
42
|
+
return JSON.parse(raw);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function listAccounts(provider) {
|
|
49
|
+
const dir = oauthDir(provider);
|
|
50
|
+
if (!fs_1.default.existsSync(dir))
|
|
51
|
+
return [];
|
|
52
|
+
return fs_1.default
|
|
53
|
+
.readdirSync(dir)
|
|
54
|
+
.filter((f) => f.endsWith('.json'))
|
|
55
|
+
.map((f) => f.replace(/\.json$/, ''));
|
|
56
|
+
}
|
|
57
|
+
function deleteToken(provider, account = 'default') {
|
|
58
|
+
const filePath = oauthFilePath(provider, account);
|
|
59
|
+
if (fs_1.default.existsSync(filePath))
|
|
60
|
+
fs_1.default.unlinkSync(filePath);
|
|
61
|
+
}
|
|
62
|
+
function listProvidersWithLogin() {
|
|
63
|
+
const root = path_1.default.join(config_1.REDAI_CONFIG_DIR, 'oauth');
|
|
64
|
+
if (!fs_1.default.existsSync(root))
|
|
65
|
+
return [];
|
|
66
|
+
return fs_1.default
|
|
67
|
+
.readdirSync(root, { withFileTypes: true })
|
|
68
|
+
.filter((d) => d.isDirectory())
|
|
69
|
+
.map((d) => d.name)
|
|
70
|
+
.filter((name) => listAccounts(name).length > 0);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/llm/oauth/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PKCECodes } from './pkce';
|
|
2
|
+
import { OAuthTokenStorage } from './store';
|
|
3
|
+
/**
|
|
4
|
+
* xAI Grok OAuth — port từ `internal/auth/xai/xai.go` + `types.go`.
|
|
5
|
+
*
|
|
6
|
+
* Khác Claude/Codex: dùng OIDC discovery để resolve endpoint thật. PKCE bắt buộc.
|
|
7
|
+
*/
|
|
8
|
+
export declare const XAI_DEFAULT_API_BASE = "https://api.x.ai/v1";
|
|
9
|
+
export declare const XAI_ISSUER = "https://auth.x.ai";
|
|
10
|
+
export declare const XAI_DISCOVERY_URL = "https://auth.x.ai/.well-known/openid-configuration";
|
|
11
|
+
export declare const XAI_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
|
|
12
|
+
export declare const XAI_SCOPE = "openid profile email offline_access grok-cli:access api:access";
|
|
13
|
+
export declare const XAI_DEFAULT_CALLBACK_PORT = 56121;
|
|
14
|
+
export declare const XAI_CALLBACK_PATH = "/callback";
|
|
15
|
+
export interface XAIDiscovery {
|
|
16
|
+
authorizationEndpoint: string;
|
|
17
|
+
tokenEndpoint: string;
|
|
18
|
+
}
|
|
19
|
+
export interface XAIAuthSession {
|
|
20
|
+
authUrl: string;
|
|
21
|
+
state: string;
|
|
22
|
+
pkce: PKCECodes;
|
|
23
|
+
redirectUri: string;
|
|
24
|
+
discovery: XAIDiscovery;
|
|
25
|
+
}
|
|
26
|
+
export declare function startXAIAuth(callbackPort?: number): Promise<XAIAuthSession>;
|
|
27
|
+
export declare function exchangeXAICodeForTokens(code: string, pkce: PKCECodes, redirectUri: string, tokenEndpoint: string, account?: string): Promise<OAuthTokenStorage>;
|
|
28
|
+
export declare function refreshXAIToken(current: OAuthTokenStorage): Promise<OAuthTokenStorage>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XAI_CALLBACK_PATH = exports.XAI_DEFAULT_CALLBACK_PORT = exports.XAI_SCOPE = exports.XAI_CLIENT_ID = exports.XAI_DISCOVERY_URL = exports.XAI_ISSUER = exports.XAI_DEFAULT_API_BASE = void 0;
|
|
4
|
+
exports.startXAIAuth = startXAIAuth;
|
|
5
|
+
exports.exchangeXAICodeForTokens = exchangeXAICodeForTokens;
|
|
6
|
+
exports.refreshXAIToken = refreshXAIToken;
|
|
7
|
+
const undici_1 = require("undici");
|
|
8
|
+
const pkce_1 = require("./pkce");
|
|
9
|
+
/**
|
|
10
|
+
* xAI Grok OAuth — port từ `internal/auth/xai/xai.go` + `types.go`.
|
|
11
|
+
*
|
|
12
|
+
* Khác Claude/Codex: dùng OIDC discovery để resolve endpoint thật. PKCE bắt buộc.
|
|
13
|
+
*/
|
|
14
|
+
exports.XAI_DEFAULT_API_BASE = 'https://api.x.ai/v1';
|
|
15
|
+
exports.XAI_ISSUER = 'https://auth.x.ai';
|
|
16
|
+
exports.XAI_DISCOVERY_URL = `${exports.XAI_ISSUER}/.well-known/openid-configuration`;
|
|
17
|
+
exports.XAI_CLIENT_ID = 'b1a00492-073a-47ea-816f-4c329264a828';
|
|
18
|
+
exports.XAI_SCOPE = 'openid profile email offline_access grok-cli:access api:access';
|
|
19
|
+
exports.XAI_DEFAULT_CALLBACK_PORT = 56121;
|
|
20
|
+
exports.XAI_CALLBACK_PATH = '/callback';
|
|
21
|
+
async function fetchDiscovery() {
|
|
22
|
+
const res = await (0, undici_1.request)(exports.XAI_DISCOVERY_URL, {
|
|
23
|
+
method: 'GET',
|
|
24
|
+
headers: { Accept: 'application/json' },
|
|
25
|
+
headersTimeout: 10000,
|
|
26
|
+
bodyTimeout: 10000,
|
|
27
|
+
});
|
|
28
|
+
const text = await res.body.text();
|
|
29
|
+
if (res.statusCode !== 200) {
|
|
30
|
+
throw new Error(`xAI discovery failed (${res.statusCode}): ${text}`);
|
|
31
|
+
}
|
|
32
|
+
const parsed = JSON.parse(text);
|
|
33
|
+
if (!parsed.authorization_endpoint || !parsed.token_endpoint) {
|
|
34
|
+
throw new Error('xAI discovery missing endpoints');
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
authorizationEndpoint: parsed.authorization_endpoint,
|
|
38
|
+
tokenEndpoint: parsed.token_endpoint,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function startXAIAuth(callbackPort = exports.XAI_DEFAULT_CALLBACK_PORT) {
|
|
42
|
+
const discovery = await fetchDiscovery();
|
|
43
|
+
const pkce = (0, pkce_1.generatePKCECodes)();
|
|
44
|
+
const state = (0, pkce_1.generateRandomState)();
|
|
45
|
+
const redirectUri = `http://127.0.0.1:${callbackPort}${exports.XAI_CALLBACK_PATH}`;
|
|
46
|
+
const params = new URLSearchParams({
|
|
47
|
+
client_id: exports.XAI_CLIENT_ID,
|
|
48
|
+
response_type: 'code',
|
|
49
|
+
redirect_uri: redirectUri,
|
|
50
|
+
scope: exports.XAI_SCOPE,
|
|
51
|
+
state,
|
|
52
|
+
code_challenge: pkce.codeChallenge,
|
|
53
|
+
code_challenge_method: 'S256',
|
|
54
|
+
});
|
|
55
|
+
return {
|
|
56
|
+
authUrl: `${discovery.authorizationEndpoint}?${params.toString()}`,
|
|
57
|
+
state,
|
|
58
|
+
pkce,
|
|
59
|
+
redirectUri,
|
|
60
|
+
discovery,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function exchangeXAICodeForTokens(code, pkce, redirectUri, tokenEndpoint, account = 'default') {
|
|
64
|
+
const data = new URLSearchParams({
|
|
65
|
+
grant_type: 'authorization_code',
|
|
66
|
+
client_id: exports.XAI_CLIENT_ID,
|
|
67
|
+
code,
|
|
68
|
+
redirect_uri: redirectUri,
|
|
69
|
+
code_verifier: pkce.codeVerifier,
|
|
70
|
+
});
|
|
71
|
+
const res = await (0, undici_1.request)(tokenEndpoint, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: {
|
|
74
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
75
|
+
Accept: 'application/json',
|
|
76
|
+
},
|
|
77
|
+
body: data.toString(),
|
|
78
|
+
headersTimeout: 15000,
|
|
79
|
+
bodyTimeout: 30000,
|
|
80
|
+
});
|
|
81
|
+
const text = await res.body.text();
|
|
82
|
+
if (res.statusCode !== 200) {
|
|
83
|
+
throw new Error(`xAI token exchange failed (${res.statusCode}): ${text}`);
|
|
84
|
+
}
|
|
85
|
+
const parsed = JSON.parse(text);
|
|
86
|
+
const now = Date.now();
|
|
87
|
+
return {
|
|
88
|
+
type: 'xai',
|
|
89
|
+
account,
|
|
90
|
+
accessToken: parsed.access_token,
|
|
91
|
+
refreshToken: parsed.refresh_token ?? '',
|
|
92
|
+
idToken: parsed.id_token,
|
|
93
|
+
expiresAt: now + parsed.expires_in * 1000,
|
|
94
|
+
lastRefresh: now,
|
|
95
|
+
metadata: { tokenEndpoint },
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async function refreshXAIToken(current) {
|
|
99
|
+
if (!current.refreshToken)
|
|
100
|
+
throw new Error('xAI refresh token missing');
|
|
101
|
+
const tokenEndpoint = current.metadata?.tokenEndpoint ?? (await fetchDiscovery()).tokenEndpoint;
|
|
102
|
+
const data = new URLSearchParams({
|
|
103
|
+
grant_type: 'refresh_token',
|
|
104
|
+
client_id: exports.XAI_CLIENT_ID,
|
|
105
|
+
refresh_token: current.refreshToken,
|
|
106
|
+
});
|
|
107
|
+
const res = await (0, undici_1.request)(tokenEndpoint, {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
headers: {
|
|
110
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
111
|
+
Accept: 'application/json',
|
|
112
|
+
},
|
|
113
|
+
body: data.toString(),
|
|
114
|
+
headersTimeout: 15000,
|
|
115
|
+
bodyTimeout: 30000,
|
|
116
|
+
});
|
|
117
|
+
const text = await res.body.text();
|
|
118
|
+
if (res.statusCode !== 200) {
|
|
119
|
+
throw new Error(`xAI refresh failed (${res.statusCode}): ${text}`);
|
|
120
|
+
}
|
|
121
|
+
const parsed = JSON.parse(text);
|
|
122
|
+
const now = Date.now();
|
|
123
|
+
return {
|
|
124
|
+
...current,
|
|
125
|
+
accessToken: parsed.access_token,
|
|
126
|
+
refreshToken: parsed.refresh_token ?? current.refreshToken,
|
|
127
|
+
idToken: parsed.id_token ?? current.idToken,
|
|
128
|
+
expiresAt: now + parsed.expires_in * 1000,
|
|
129
|
+
lastRefresh: now,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=xai-oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xai-oauth.js","sourceRoot":"","sources":["../../../src/llm/oauth/xai-oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { OAuthTokenStorage } from '../oauth/store';
|
|
2
|
+
export declare function getValidAntigravityToken(account?: string): Promise<OAuthTokenStorage>;
|
|
3
|
+
export interface AntigravityRequestInput {
|
|
4
|
+
path: string;
|
|
5
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
6
|
+
body?: unknown;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
account?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface AntigravityResponse {
|
|
11
|
+
status: number;
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
body: unknown;
|
|
14
|
+
errorType?: string;
|
|
15
|
+
account: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function callAntigravity(input: AntigravityRequestInput): Promise<AntigravityResponse>;
|
|
18
|
+
export declare function streamAntigravity(input: AntigravityRequestInput): AsyncGenerator<{
|
|
19
|
+
chunk: string;
|
|
20
|
+
}, {
|
|
21
|
+
status: number;
|
|
22
|
+
account: string;
|
|
23
|
+
}, void>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getValidAntigravityToken = getValidAntigravityToken;
|
|
4
|
+
exports.callAntigravity = callAntigravity;
|
|
5
|
+
exports.streamAntigravity = streamAntigravity;
|
|
6
|
+
const undici_1 = require("undici");
|
|
7
|
+
const antigravity_oauth_1 = require("../oauth/antigravity-oauth");
|
|
8
|
+
const store_1 = require("../oauth/store");
|
|
9
|
+
/**
|
|
10
|
+
* Antigravity client — Google `cloudcode-pa.googleapis.com` /v1internal endpoints.
|
|
11
|
+
* (Port từ `internal/runtime/executor/antigravity_executor.go`)
|
|
12
|
+
*/
|
|
13
|
+
const ANTIGRAVITY_DEFAULT_BASE = 'https://cloudcode-pa.googleapis.com';
|
|
14
|
+
const REFRESH_GRACE_MS = 60000;
|
|
15
|
+
function buildHeaders(token, opts) {
|
|
16
|
+
const headers = {
|
|
17
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
'User-Agent': 'antigravity-cli/1.0',
|
|
20
|
+
Accept: opts.stream ? 'text/event-stream' : 'application/json',
|
|
21
|
+
};
|
|
22
|
+
if (opts.override)
|
|
23
|
+
Object.assign(headers, opts.override);
|
|
24
|
+
return headers;
|
|
25
|
+
}
|
|
26
|
+
async function getValidAntigravityToken(account = 'default') {
|
|
27
|
+
const token = (0, store_1.loadToken)('antigravity', account);
|
|
28
|
+
if (!token) {
|
|
29
|
+
throw new Error(`Antigravity not logged in (account=${account}). Run \`redai oauth antigravity\`.`);
|
|
30
|
+
}
|
|
31
|
+
if (token.expiresAt > Date.now() + REFRESH_GRACE_MS)
|
|
32
|
+
return token;
|
|
33
|
+
const refreshed = await (0, antigravity_oauth_1.refreshAntigravityToken)(token);
|
|
34
|
+
(0, store_1.saveToken)('antigravity', refreshed);
|
|
35
|
+
return refreshed;
|
|
36
|
+
}
|
|
37
|
+
async function callAntigravity(input) {
|
|
38
|
+
const account = input.account ?? 'default';
|
|
39
|
+
const token = await getValidAntigravityToken(account);
|
|
40
|
+
let base = ANTIGRAVITY_DEFAULT_BASE;
|
|
41
|
+
let overrideHeaders = input.headers;
|
|
42
|
+
if (overrideHeaders && overrideHeaders['x-base-url']) {
|
|
43
|
+
base = overrideHeaders['x-base-url'].replace(/\/+$/, '');
|
|
44
|
+
overrideHeaders = { ...overrideHeaders };
|
|
45
|
+
delete overrideHeaders['x-base-url'];
|
|
46
|
+
}
|
|
47
|
+
const headers = buildHeaders(token, { stream: false, override: overrideHeaders });
|
|
48
|
+
const res = await (0, undici_1.request)(`${base}${input.path}`, {
|
|
49
|
+
method: input.method ?? 'POST',
|
|
50
|
+
headers,
|
|
51
|
+
body: input.body !== undefined ? JSON.stringify(input.body) : undefined,
|
|
52
|
+
headersTimeout: 30000,
|
|
53
|
+
bodyTimeout: 120000,
|
|
54
|
+
});
|
|
55
|
+
return finalize(res, account);
|
|
56
|
+
}
|
|
57
|
+
async function* streamAntigravity(input) {
|
|
58
|
+
const account = input.account ?? 'default';
|
|
59
|
+
const token = await getValidAntigravityToken(account);
|
|
60
|
+
let base = ANTIGRAVITY_DEFAULT_BASE;
|
|
61
|
+
let overrideHeaders = input.headers;
|
|
62
|
+
if (overrideHeaders && overrideHeaders['x-base-url']) {
|
|
63
|
+
base = overrideHeaders['x-base-url'].replace(/\/+$/, '');
|
|
64
|
+
overrideHeaders = { ...overrideHeaders };
|
|
65
|
+
delete overrideHeaders['x-base-url'];
|
|
66
|
+
}
|
|
67
|
+
const headers = buildHeaders(token, { stream: true, override: overrideHeaders });
|
|
68
|
+
const res = await (0, undici_1.request)(`${base}${input.path}`, {
|
|
69
|
+
method: input.method ?? 'POST',
|
|
70
|
+
headers,
|
|
71
|
+
body: input.body !== undefined ? JSON.stringify(input.body) : undefined,
|
|
72
|
+
headersTimeout: 30000,
|
|
73
|
+
bodyTimeout: 0,
|
|
74
|
+
});
|
|
75
|
+
for await (const chunk of res.body) {
|
|
76
|
+
const text = typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
77
|
+
yield { chunk: text };
|
|
78
|
+
}
|
|
79
|
+
return { status: res.statusCode, account };
|
|
80
|
+
}
|
|
81
|
+
async function finalize(res, account) {
|
|
82
|
+
const rawHeaders = {};
|
|
83
|
+
for (const [k, v] of Object.entries(res.headers)) {
|
|
84
|
+
rawHeaders[k] = Array.isArray(v) ? v.join(', ') : String(v ?? '');
|
|
85
|
+
}
|
|
86
|
+
const text = await res.body.text();
|
|
87
|
+
let parsedBody = text;
|
|
88
|
+
const ct = res.headers['content-type'] ?? '';
|
|
89
|
+
if (ct.includes('application/json')) {
|
|
90
|
+
try {
|
|
91
|
+
parsedBody = JSON.parse(text);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* keep raw */
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
let errorType;
|
|
98
|
+
if (res.statusCode >= 400 && parsedBody && typeof parsedBody === 'object') {
|
|
99
|
+
errorType = parsedBody.error?.status;
|
|
100
|
+
}
|
|
101
|
+
return { status: res.statusCode, headers: rawHeaders, body: parsedBody, errorType, account };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=antigravity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"antigravity.js","sourceRoot":"","sources":["../../../src/llm/providers/antigravity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { OAuthTokenStorage } from '../oauth/store';
|
|
2
|
+
/**
|
|
3
|
+
* Lấy access token còn hạn. Nếu sắp expire → refresh + save lại.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getValidClaudeToken(account?: string): Promise<OAuthTokenStorage>;
|
|
6
|
+
export interface ClaudeRequestInput {
|
|
7
|
+
/** Path đầy đủ, vd `/v1/messages`. */
|
|
8
|
+
path: string;
|
|
9
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
10
|
+
body?: unknown;
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
account?: string;
|
|
13
|
+
stream?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ClaudeResponse {
|
|
16
|
+
status: number;
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
body: unknown;
|
|
19
|
+
errorType?: string;
|
|
20
|
+
account: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Non-streaming: gom toàn bộ response, parse JSON. Dùng cho `/v1/messages`
|
|
24
|
+
* không stream và các endpoint metadata.
|
|
25
|
+
*/
|
|
26
|
+
export declare function callClaude(input: ClaudeRequestInput): Promise<ClaudeResponse>;
|
|
27
|
+
/**
|
|
28
|
+
* Streaming: trả async iterable yield SSE event text chunks. Caller chịu trách
|
|
29
|
+
* nhiệm forward lên TOOL_STREAM event.
|
|
30
|
+
*/
|
|
31
|
+
export declare function streamClaude(input: ClaudeRequestInput): AsyncGenerator<{
|
|
32
|
+
chunk: string;
|
|
33
|
+
}, {
|
|
34
|
+
status: number;
|
|
35
|
+
account: string;
|
|
36
|
+
}, void>;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getValidClaudeToken = getValidClaudeToken;
|
|
4
|
+
exports.callClaude = callClaude;
|
|
5
|
+
exports.streamClaude = streamClaude;
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
7
|
+
const undici_1 = require("undici");
|
|
8
|
+
const claude_oauth_1 = require("../oauth/claude-oauth");
|
|
9
|
+
const store_1 = require("../oauth/store");
|
|
10
|
+
const ANTHROPIC_BASE = 'https://api.anthropic.com';
|
|
11
|
+
const REFRESH_GRACE_MS = 60000; // refresh sớm 60s trước khi expire
|
|
12
|
+
/**
|
|
13
|
+
* Header spoofing chuẩn Claude Code 2.1.63 — port từ
|
|
14
|
+
* `internal/runtime/executor/claude_executor.go` + `helps/claude_device_profile.go`.
|
|
15
|
+
*
|
|
16
|
+
* Anthropic check fingerprint chặt: thiếu/lệch User-Agent, Stainless headers
|
|
17
|
+
* hoặc anthropic-version → có thể bị flag là 3rd-party access và trả 403.
|
|
18
|
+
*/
|
|
19
|
+
const CLAUDE_DEVICE_PROFILE = {
|
|
20
|
+
userAgent: 'claude-cli/2.1.63 (external, cli)',
|
|
21
|
+
packageVersion: '0.74.0',
|
|
22
|
+
runtimeVersion: 'v24.3.0',
|
|
23
|
+
os: 'MacOS',
|
|
24
|
+
arch: 'arm64',
|
|
25
|
+
};
|
|
26
|
+
function buildClaudeHeaders(accessToken, opts) {
|
|
27
|
+
const headers = {
|
|
28
|
+
Authorization: `Bearer ${accessToken}`,
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
'Anthropic-Version': '2023-06-01',
|
|
31
|
+
'Anthropic-Beta': 'oauth-2025-04-20,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14',
|
|
32
|
+
'X-App': 'cli',
|
|
33
|
+
'X-Stainless-Retry-Count': '0',
|
|
34
|
+
'X-Stainless-Runtime': 'node',
|
|
35
|
+
'X-Stainless-Lang': 'js',
|
|
36
|
+
'X-Stainless-Timeout': '600',
|
|
37
|
+
'X-Stainless-Package-Version': CLAUDE_DEVICE_PROFILE.packageVersion,
|
|
38
|
+
'X-Stainless-Runtime-Version': CLAUDE_DEVICE_PROFILE.runtimeVersion,
|
|
39
|
+
'X-Stainless-Os': CLAUDE_DEVICE_PROFILE.os,
|
|
40
|
+
'X-Stainless-Arch': CLAUDE_DEVICE_PROFILE.arch,
|
|
41
|
+
'X-Claude-Code-Session-Id': opts.sessionId ?? (0, crypto_1.randomUUID)(),
|
|
42
|
+
'x-client-request-id': (0, crypto_1.randomUUID)(),
|
|
43
|
+
'User-Agent': CLAUDE_DEVICE_PROFILE.userAgent,
|
|
44
|
+
Connection: 'keep-alive',
|
|
45
|
+
};
|
|
46
|
+
if (opts.stream) {
|
|
47
|
+
headers.Accept = 'text/event-stream';
|
|
48
|
+
headers['Accept-Encoding'] = 'identity';
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
headers.Accept = 'application/json';
|
|
52
|
+
headers['Accept-Encoding'] = 'gzip, deflate, br';
|
|
53
|
+
}
|
|
54
|
+
if (opts.override)
|
|
55
|
+
Object.assign(headers, opts.override);
|
|
56
|
+
return headers;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Lấy access token còn hạn. Nếu sắp expire → refresh + save lại.
|
|
60
|
+
*/
|
|
61
|
+
async function getValidClaudeToken(account = 'default') {
|
|
62
|
+
const token = (0, store_1.loadToken)('claude', account);
|
|
63
|
+
if (!token) {
|
|
64
|
+
throw new Error(`Claude not logged in (account=${account}). Run \`redai oauth claude\`.`);
|
|
65
|
+
}
|
|
66
|
+
if (token.expiresAt > Date.now() + REFRESH_GRACE_MS) {
|
|
67
|
+
return token;
|
|
68
|
+
}
|
|
69
|
+
// Refresh
|
|
70
|
+
const refreshed = await (0, claude_oauth_1.refreshClaudeToken)(token);
|
|
71
|
+
(0, store_1.saveToken)('claude', refreshed);
|
|
72
|
+
return refreshed;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Non-streaming: gom toàn bộ response, parse JSON. Dùng cho `/v1/messages`
|
|
76
|
+
* không stream và các endpoint metadata.
|
|
77
|
+
*/
|
|
78
|
+
async function callClaude(input) {
|
|
79
|
+
const account = input.account ?? 'default';
|
|
80
|
+
const token = await getValidClaudeToken(account);
|
|
81
|
+
const method = input.method ?? 'POST';
|
|
82
|
+
const url = `${ANTHROPIC_BASE}${input.path}`;
|
|
83
|
+
const headers = buildClaudeHeaders(token.accessToken, {
|
|
84
|
+
stream: false,
|
|
85
|
+
override: input.headers,
|
|
86
|
+
});
|
|
87
|
+
const res = await (0, undici_1.request)(url, {
|
|
88
|
+
method,
|
|
89
|
+
headers,
|
|
90
|
+
body: input.body !== undefined ? JSON.stringify(input.body) : undefined,
|
|
91
|
+
bodyTimeout: 120000,
|
|
92
|
+
headersTimeout: 30000,
|
|
93
|
+
});
|
|
94
|
+
const rawHeaders = {};
|
|
95
|
+
for (const [k, v] of Object.entries(res.headers)) {
|
|
96
|
+
rawHeaders[k] = Array.isArray(v) ? v.join(', ') : String(v ?? '');
|
|
97
|
+
}
|
|
98
|
+
const text = await res.body.text();
|
|
99
|
+
let parsedBody = text;
|
|
100
|
+
const ct = res.headers['content-type'] ?? '';
|
|
101
|
+
if (ct.includes('application/json')) {
|
|
102
|
+
try {
|
|
103
|
+
parsedBody = JSON.parse(text);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// keep raw
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Anthropic error envelope: {"type":"error","error":{"type":"...","message":"..."}}
|
|
110
|
+
let errorType;
|
|
111
|
+
if (res.statusCode >= 400 && parsedBody && typeof parsedBody === 'object') {
|
|
112
|
+
const errObj = parsedBody.error;
|
|
113
|
+
errorType = errObj?.type;
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
status: res.statusCode,
|
|
117
|
+
headers: rawHeaders,
|
|
118
|
+
body: parsedBody,
|
|
119
|
+
errorType,
|
|
120
|
+
account,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Streaming: trả async iterable yield SSE event text chunks. Caller chịu trách
|
|
125
|
+
* nhiệm forward lên TOOL_STREAM event.
|
|
126
|
+
*/
|
|
127
|
+
async function* streamClaude(input) {
|
|
128
|
+
const account = input.account ?? 'default';
|
|
129
|
+
const token = await getValidClaudeToken(account);
|
|
130
|
+
const url = `${ANTHROPIC_BASE}${input.path}`;
|
|
131
|
+
const headers = buildClaudeHeaders(token.accessToken, {
|
|
132
|
+
stream: true,
|
|
133
|
+
override: input.headers,
|
|
134
|
+
});
|
|
135
|
+
const res = await (0, undici_1.request)(url, {
|
|
136
|
+
method: input.method ?? 'POST',
|
|
137
|
+
headers,
|
|
138
|
+
body: input.body !== undefined ? JSON.stringify(input.body) : undefined,
|
|
139
|
+
headersTimeout: 30000,
|
|
140
|
+
bodyTimeout: 0, // streaming có thể lâu, không timeout body
|
|
141
|
+
});
|
|
142
|
+
for await (const chunk of res.body) {
|
|
143
|
+
const text = typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
144
|
+
yield { chunk: text };
|
|
145
|
+
}
|
|
146
|
+
return { status: res.statusCode, account };
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/llm/providers/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { OAuthTokenStorage } from '../oauth/store';
|
|
2
|
+
export declare function getValidCodexToken(account?: string): Promise<OAuthTokenStorage>;
|
|
3
|
+
export interface CodexRequestInput {
|
|
4
|
+
path: string;
|
|
5
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
6
|
+
body?: unknown;
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
account?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CodexResponse {
|
|
11
|
+
status: number;
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
body: unknown;
|
|
14
|
+
errorType?: string;
|
|
15
|
+
account: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function streamCodex(input: CodexRequestInput): AsyncGenerator<{
|
|
18
|
+
chunk: string;
|
|
19
|
+
}, {
|
|
20
|
+
status: number;
|
|
21
|
+
account: string;
|
|
22
|
+
}, void>;
|
|
23
|
+
export declare function callCodex(input: CodexRequestInput): Promise<CodexResponse>;
|