dsh-grok-subscription 1.0.19 → 1.0.20
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.en.md +1 -1
- package/README.md +1 -1
- package/lib/client.js +4 -4
- package/lib/index.js +50 -175
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -209,7 +209,7 @@ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-grok-subscrip
|
|
|
209
209
|
|
|
210
210
|
- **`dsh` is not recognized**: the official npm route never creates a global `dsh` command — use the full `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` command above;
|
|
211
211
|
- **The model list is empty**: nothing is exposed while signed out. Finish signing in, then click **Pull from Grok CLI**;
|
|
212
|
-
- **Sign-in opens no browser / chat fails with `fetch failed` / usage says "Billing request timed out"**: all three have one cause — `accounts.x.ai` and `cli-chat-proxy.grok.com` need a tunnel on some networks.
|
|
212
|
+
- **Sign-in opens no browser / chat fails with `fetch failed` / usage says "Billing request timed out"**: all three have one cause — `accounts.x.ai` and `cli-chat-proxy.grok.com` need a tunnel on some networks. This plugin does not configure a proxy of its own. When a tunnel is required, set the standard `https_proxy` / `http_proxy` in the launching environment or in `~/.dsh/.env` (never in a project `.env`). `@deepseek-ai/dsh-http-proxy` then routes `fetch` and the `grok` CLI this plugin spawns. Restart the client afterwards; the sign-in link is handed to your browser and the panel also shows the one-time code and a clickable link.
|
|
213
213
|
- **Nothing changed after upgrading**: the plugin keeps running the old `lib/` — reinstall the plugin, restart `dsh web`, and hard-refresh (Ctrl+Shift+R);
|
|
214
214
|
- **It reports `auth.json` permissions**: apply the `chmod 600` above; the plugin refuses symlinks and group- or other-readable files;
|
|
215
215
|
- **"No reply" after sending a message**: upgrade to `1.0.1` or later. `1.0.0` had a defect where tool-calling turns aborted with a non-serializable stream chunk, leaving no reply in the UI at all.
|
package/README.md
CHANGED
|
@@ -209,7 +209,7 @@ npx -y @deepseek-ai/dsh@0.1.5-rc.2 plugin --profile web remove dsh-grok-subscrip
|
|
|
209
209
|
|
|
210
210
|
- **`dsh` 无法识别**:官方 npm 方式本来就不会创建全局 `dsh` 命令,请使用上面的完整 `npx -y @deepseek-ai/dsh@0.1.5-rc.2 ...` 命令;
|
|
211
211
|
- **模型列表是空的**:未登录时插件不暴露任何模型。先完成登录,再点 **从 Grok CLI 拉取**;
|
|
212
|
-
- **登录不弹浏览器 / 聊天报 `fetch failed` / 用量「Billing request timed out」**:这三件事都指向同一个原因——`accounts.x.ai` 与 `cli-chat-proxy.grok.com`
|
|
212
|
+
- **登录不弹浏览器 / 聊天报 `fetch failed` / 用量「Billing request timed out」**:这三件事都指向同一个原因——`accounts.x.ai` 与 `cli-chat-proxy.grok.com` 在部分网络里必须走隧道。插件不再自己配代理。需要隧道时,在启动环境或 `~/.dsh/.env` 里写标准变量 `https_proxy` / `http_proxy`(不要写进项目目录的 `.env`),宿主的 `@deepseek-ai/dsh-http-proxy` 会让 `fetch` 和本插件拉起的 `grok` CLI 一起走它。写好后重启客户端;登录链接会交给系统浏览器打开,面板里同时显示一次性验证码与可点链接。
|
|
213
213
|
- **升级后界面没变化**:插件会继续运行旧的 `lib/`,请重新安装插件并重启 `dsh web`,然后硬刷新(Ctrl+Shift+R);
|
|
214
214
|
- **提示 `auth.json` 权限不正确**:按上面的 `chmod 600` 处理;插件拒绝读取符号链接或组/其他用户可读的文件;
|
|
215
215
|
- **出现「没有回复」**:请升级到 `1.0.1` 或更高版本。`1.0.0` 存在一个缺陷:工具调用轮次会因流片段无法无损序列化而整轮中止,界面上完全没有回复。
|
package/lib/client.js
CHANGED
|
@@ -39,7 +39,7 @@ var import_react2 = require("react");
|
|
|
39
39
|
var zh = {
|
|
40
40
|
nav: "Grok \u8BA2\u9605",
|
|
41
41
|
title: "Grok \u8BA2\u9605",
|
|
42
|
-
subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 1.0.
|
|
42
|
+
subtitle: "\u7528 SuperGrok / X Premium\uFF08Grok Build\uFF09\u4F1A\u8BDD\uFF0C\u800C\u4E0D\u662F XAI_API_KEY\u3002\xB7 1.0.20",
|
|
43
43
|
signedIn: "\u5DF2\u767B\u5F55",
|
|
44
44
|
signedOut: "\u672A\u767B\u5F55",
|
|
45
45
|
account: "\u8D26\u6237",
|
|
@@ -58,7 +58,7 @@ var zh = {
|
|
|
58
58
|
deviceHint: "\u8BBE\u5907\u7801\u767B\u5F55\u4F1A\u8BA9 CLI \u6253\u5370\u4E00\u6B21\u6027\u9A8C\u8BC1\u7801\u548C\u94FE\u63A5\u3002\u82E5\u6D4F\u89C8\u5668\u6CA1\u6709\u81EA\u52A8\u6253\u5F00\uFF0C\u70B9\u63D0\u793A\u91CC\u7684\u201C\u6253\u5F00\u767B\u5F55\u9875\u9762\u201D\u5E76\u786E\u8BA4\u9A8C\u8BC1\u7801\u3002",
|
|
59
59
|
loginWaiting: "\u7B49\u5F85\u6D4F\u89C8\u5668\u6388\u6743\u2026",
|
|
60
60
|
loginOpenBrowser: "\u6253\u5F00\u767B\u5F55\u9875\u9762",
|
|
61
|
-
loginNoUrl: "\u6CA1\u62FF\u5230\u767B\u5F55\u94FE\u63A5\uFF1A\u8BF7\u786E\u8BA4 grok CLI \u80FD\u8BBF\u95EE x.ai\
|
|
61
|
+
loginNoUrl: "\u6CA1\u62FF\u5230\u767B\u5F55\u94FE\u63A5\uFF1A\u8BF7\u786E\u8BA4 grok CLI \u80FD\u8BBF\u95EE x.ai\u3002\u684C\u9762\u7248\u9700\u8981\u4EE3\u7406\u65F6\uFF0C\u5728 ~/.dsh/.env \u8BBE\u7F6E https_proxy \u540E\u91CD\u542F\u3002",
|
|
62
62
|
loginTimeout: "\u7B49\u5F85\u6388\u6743\u8D85\u65F6\uFF0C\u8BF7\u91CD\u65B0\u70B9\u51FB\u767B\u5F55\u3002",
|
|
63
63
|
pullHint: "\u5B89\u5168\u8BFB\u53D6 ~/.grok/auth.json\uFF08\u62D2\u7EDD\u7B26\u53F7\u94FE\u63A5\u4E0E\u7EC4/\u5176\u4ED6\u4EBA\u53EF\u8BFB\uFF09\uFF0C\u53EA\u628A\u77ED\u671F access token \u5199\u5165 DSH\u3002",
|
|
64
64
|
loginHelp: "\u767B\u5F55\u65B9\u5F0F\u8BF4\u660E",
|
|
@@ -119,7 +119,7 @@ var zh = {
|
|
|
119
119
|
var en = {
|
|
120
120
|
nav: "Grok Subscription",
|
|
121
121
|
title: "Grok Subscription",
|
|
122
|
-
subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.0.
|
|
122
|
+
subtitle: "Use a SuperGrok / X Premium (Grok Build) session, not XAI_API_KEY. \xB7 1.0.20",
|
|
123
123
|
signedIn: "Signed in",
|
|
124
124
|
signedOut: "Signed out",
|
|
125
125
|
account: "Account",
|
|
@@ -138,7 +138,7 @@ var en = {
|
|
|
138
138
|
deviceHint: "Device-code login makes the CLI print a one-time code and link. If no browser opened, use \u201COpen the sign-in page\u201D in the status line and confirm the code.",
|
|
139
139
|
loginWaiting: "Waiting for browser authorization\u2026",
|
|
140
140
|
loginOpenBrowser: "Open the sign-in page",
|
|
141
|
-
loginNoUrl: "No sign-in link was returned: make sure the grok CLI can reach x.ai
|
|
141
|
+
loginNoUrl: "No sign-in link was returned: make sure the grok CLI can reach x.ai. If the desktop app needs a proxy, set https_proxy in ~/.dsh/.env and restart.",
|
|
142
142
|
loginTimeout: "Timed out waiting for authorization; click sign-in again.",
|
|
143
143
|
pullHint: "Reads ~/.grok/auth.json securely (refuses symlinks and group/other-readable files) and stores only the short-lived access token in DSH.",
|
|
144
144
|
loginHelp: "How signing in works",
|
package/lib/index.js
CHANGED
|
@@ -42,9 +42,9 @@ var LOGIN_START_TIMEOUT_MS = 1e4;
|
|
|
42
42
|
var LOGIN_HANDLER_TIMEOUT_MS = 2e4;
|
|
43
43
|
|
|
44
44
|
// src/session.js
|
|
45
|
-
import { existsSync as
|
|
45
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
46
46
|
import { spawn } from "node:child_process";
|
|
47
|
-
import { join as
|
|
47
|
+
import { join as join3 } from "node:path";
|
|
48
48
|
|
|
49
49
|
// src/auth-file.js
|
|
50
50
|
import { lstatSync, openSync, readFileSync, closeSync, constants as fsConstants } from "node:fs";
|
|
@@ -322,89 +322,6 @@ async function readResponseJson(response, options = {}) {
|
|
|
322
322
|
return JSON.parse(await readResponseText(response, options));
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
-
// src/proxy.js
|
|
326
|
-
import { existsSync as existsSync2 } from "node:fs";
|
|
327
|
-
import { dirname, join as join2 } from "node:path";
|
|
328
|
-
import { pathToFileURL } from "node:url";
|
|
329
|
-
var HTTP_PROXY_PATTERN = /^https?:\/\//iu;
|
|
330
|
-
var HOST_PROXY_PACKAGE = "@deepseek-ai/dsh-http-proxy";
|
|
331
|
-
var GROK_ORIGIN = "https://cli-chat-proxy.grok.com/";
|
|
332
|
-
var cached;
|
|
333
|
-
var dependencies = { undici: void 0, hostProxies: void 0, hostProxyEnv: void 0 };
|
|
334
|
-
function apiProxyUrl(env = process.env) {
|
|
335
|
-
const named = [env?.GROK_API_PROXY, env?.GROK_PROXY];
|
|
336
|
-
for (const candidate of named) {
|
|
337
|
-
if (typeof candidate === "string" && candidate.trim()) return candidate.trim();
|
|
338
|
-
}
|
|
339
|
-
return void 0;
|
|
340
|
-
}
|
|
341
|
-
async function loadHostUndici() {
|
|
342
|
-
let dir = dirname(process.argv[1] ?? "");
|
|
343
|
-
for (let depth = 0; depth < 6 && dir && dir !== dirname(dir); depth++) {
|
|
344
|
-
const entry = join2(dir, "node_modules", "undici", "index.js");
|
|
345
|
-
if (existsSync2(entry)) {
|
|
346
|
-
try {
|
|
347
|
-
return await import(pathToFileURL(entry).href);
|
|
348
|
-
} catch {
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
dir = dirname(dir);
|
|
353
|
-
}
|
|
354
|
-
try {
|
|
355
|
-
return await import("undici");
|
|
356
|
-
} catch {
|
|
357
|
-
return void 0;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
async function hostProxyModule() {
|
|
361
|
-
try {
|
|
362
|
-
return await import(HOST_PROXY_PACKAGE);
|
|
363
|
-
} catch {
|
|
364
|
-
return void 0;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
async function hostAlreadyProxiesGrok() {
|
|
368
|
-
if (typeof dependencies.hostProxies === "function") return dependencies.hostProxies();
|
|
369
|
-
const mod = await hostProxyModule();
|
|
370
|
-
try {
|
|
371
|
-
return mod?.proxyRouteFor?.(GROK_ORIGIN)?.proxied === true;
|
|
372
|
-
} catch {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
var CHILD_PROXY_NAMES = ["http_proxy", "https_proxy", "all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY"];
|
|
377
|
-
function proxyOverlay(value) {
|
|
378
|
-
if (!value || typeof value !== "object") return void 0;
|
|
379
|
-
return CHILD_PROXY_NAMES.some((name2) => typeof value[name2] === "string" && value[name2].trim()) ? value : void 0;
|
|
380
|
-
}
|
|
381
|
-
async function hostProxyEnvironment() {
|
|
382
|
-
if (typeof dependencies.hostProxyEnv === "function") return proxyOverlay(dependencies.hostProxyEnv());
|
|
383
|
-
const mod = await hostProxyModule();
|
|
384
|
-
try {
|
|
385
|
-
const overlay = typeof mod?.proxyEnvironmentForChild === "function" ? mod.proxyEnvironmentForChild() : void 0;
|
|
386
|
-
return proxyOverlay(overlay);
|
|
387
|
-
} catch {
|
|
388
|
-
return void 0;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
async function grokFetch(env = process.env) {
|
|
392
|
-
const url = apiProxyUrl(env);
|
|
393
|
-
if (!url || !HTTP_PROXY_PATTERN.test(url)) return void 0;
|
|
394
|
-
if (await hostAlreadyProxiesGrok()) return void 0;
|
|
395
|
-
if (cached?.url === url) return cached.fetch;
|
|
396
|
-
const undici = dependencies.undici ?? await loadHostUndici();
|
|
397
|
-
if (typeof undici?.fetch !== "function" || typeof undici?.ProxyAgent !== "function") return void 0;
|
|
398
|
-
try {
|
|
399
|
-
const dispatcher = new undici.ProxyAgent(url);
|
|
400
|
-
const fetchImpl = (input, init) => undici.fetch(input, { ...init, dispatcher });
|
|
401
|
-
cached = { url, fetch: fetchImpl };
|
|
402
|
-
return fetchImpl;
|
|
403
|
-
} catch {
|
|
404
|
-
return void 0;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
325
|
// src/catalog.js
|
|
409
326
|
var REASONING_LEVELS = Object.freeze(["low", "medium", "high", "xhigh"]);
|
|
410
327
|
function asId(value) {
|
|
@@ -527,7 +444,7 @@ function toLlmModels(models) {
|
|
|
527
444
|
});
|
|
528
445
|
}
|
|
529
446
|
async function fetchLiveCatalog(accessToken, options = {}) {
|
|
530
|
-
const fetchImpl = options.fetch ??
|
|
447
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
531
448
|
const signal = options.signal ?? AbortSignal.timeout(options.timeoutMs ?? CATALOG_TIMEOUT_MS);
|
|
532
449
|
const response = await fetchImpl(MODELS_V2_URL, {
|
|
533
450
|
method: "GET",
|
|
@@ -773,8 +690,7 @@ async function fetchBillingUsageOnce(accessToken, options = {}) {
|
|
|
773
690
|
let response;
|
|
774
691
|
try {
|
|
775
692
|
const signal = options.signal ?? AbortSignal.timeout(options.timeoutMs ?? USAGE_TIMEOUT_MS);
|
|
776
|
-
|
|
777
|
-
response = await (tunnelFetch ?? fetchImpl)(BILLING_CREDITS_URL, {
|
|
693
|
+
response = await fetchImpl(BILLING_CREDITS_URL, {
|
|
778
694
|
method: "GET",
|
|
779
695
|
headers: {
|
|
780
696
|
Accept: "application/json",
|
|
@@ -850,11 +766,11 @@ async function fetchBillingUsage(accessToken, options = {}) {
|
|
|
850
766
|
}
|
|
851
767
|
|
|
852
768
|
// src/adapter.js
|
|
853
|
-
import { existsSync as
|
|
769
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
854
770
|
import { createRequire } from "node:module";
|
|
855
771
|
import { homedir as homedir2 } from "node:os";
|
|
856
|
-
import { dirname
|
|
857
|
-
import { pathToFileURL
|
|
772
|
+
import { dirname, join as join2 } from "node:path";
|
|
773
|
+
import { pathToFileURL } from "node:url";
|
|
858
774
|
function withImportTimeout(promise, ms, message) {
|
|
859
775
|
let timer;
|
|
860
776
|
return Promise.race([
|
|
@@ -874,28 +790,28 @@ function hostModuleRoots(env = process.env, argv1 = process.argv[1]) {
|
|
|
874
790
|
const override = env.DSH_GROK_PEER_ROOT;
|
|
875
791
|
if (typeof override === "string" && override.trim()) push(override.trim());
|
|
876
792
|
if (typeof argv1 === "string" && argv1) {
|
|
877
|
-
let dir =
|
|
878
|
-
for (let depth = 0; depth < 6 && dir && dir !==
|
|
879
|
-
push(
|
|
880
|
-
dir =
|
|
793
|
+
let dir = dirname(argv1);
|
|
794
|
+
for (let depth = 0; depth < 6 && dir && dir !== dirname(dir); depth++) {
|
|
795
|
+
push(join2(dir, "node_modules"));
|
|
796
|
+
dir = dirname(dir);
|
|
881
797
|
}
|
|
882
798
|
}
|
|
883
799
|
const prefix = env.NPM_CONFIG_PREFIX;
|
|
884
|
-
if (typeof prefix === "string" && prefix.trim()) push(
|
|
800
|
+
if (typeof prefix === "string" && prefix.trim()) push(join2(prefix.trim(), "lib", "node_modules"));
|
|
885
801
|
if (typeof process.execPath === "string" && process.execPath) {
|
|
886
|
-
push(
|
|
802
|
+
push(join2(dirname(process.execPath), "..", "lib", "node_modules"));
|
|
887
803
|
}
|
|
888
|
-
push(
|
|
889
|
-
push(
|
|
804
|
+
push(join2("/opt/homebrew", "lib", "node_modules"));
|
|
805
|
+
push(join2("/usr/local", "lib", "node_modules"));
|
|
890
806
|
for (const segment of ["Library/pnpm", ".local/share/pnpm", ".pnpm-global"]) {
|
|
891
|
-
push(
|
|
807
|
+
push(join2(homedir2(), segment, "node_modules"));
|
|
892
808
|
}
|
|
893
809
|
if (typeof env.DSH_PORTABLE_HOME === "string" && env.DSH_PORTABLE_HOME.trim()) {
|
|
894
|
-
push(
|
|
810
|
+
push(join2(env.DSH_PORTABLE_HOME.trim(), "node_modules"));
|
|
895
811
|
}
|
|
896
|
-
push(
|
|
897
|
-
const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME.trim() ? env.DSH_HOME.trim() :
|
|
898
|
-
push(
|
|
812
|
+
push(join2(homedir2(), ".local", "lib", "node_modules"));
|
|
813
|
+
const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME.trim() ? env.DSH_HOME.trim() : join2(homedir2(), ".dsh");
|
|
814
|
+
push(join2(dshHome, "profiles", "node_modules"));
|
|
899
815
|
return roots;
|
|
900
816
|
}
|
|
901
817
|
function splitSpecifier(specifier) {
|
|
@@ -939,14 +855,14 @@ function resolveExportsTarget(exportsField, subpath) {
|
|
|
939
855
|
function resolveHostSpecifierManually(root, specifier) {
|
|
940
856
|
const { name: name2, subpath } = splitSpecifier(specifier);
|
|
941
857
|
const candidates = [
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
858
|
+
join2(root, name2),
|
|
859
|
+
join2(root, "node_modules", name2),
|
|
860
|
+
join2(root, "@deepseek-ai", "dsh", "node_modules", name2),
|
|
861
|
+
join2(root, "node_modules", "@deepseek-ai", "dsh", "node_modules", name2)
|
|
946
862
|
];
|
|
947
863
|
for (const pkgDir of candidates) {
|
|
948
|
-
const manifest =
|
|
949
|
-
if (!
|
|
864
|
+
const manifest = join2(pkgDir, "package.json");
|
|
865
|
+
if (!existsSync2(manifest)) continue;
|
|
950
866
|
let pkg;
|
|
951
867
|
try {
|
|
952
868
|
pkg = JSON.parse(readFileSync3(manifest, "utf8"));
|
|
@@ -955,15 +871,15 @@ function resolveHostSpecifierManually(root, specifier) {
|
|
|
955
871
|
}
|
|
956
872
|
const target = pkg.exports !== void 0 ? resolveExportsTarget(pkg.exports, subpath) : subpath === "." ? pkg.module ?? pkg.main ?? "index.js" : void 0;
|
|
957
873
|
if (typeof target !== "string" || !target) continue;
|
|
958
|
-
const file =
|
|
959
|
-
if (
|
|
874
|
+
const file = join2(pkgDir, target);
|
|
875
|
+
if (existsSync2(file)) return file;
|
|
960
876
|
}
|
|
961
877
|
return void 0;
|
|
962
878
|
}
|
|
963
879
|
function resolveHostSpecifier(specifier, roots = hostModuleRoots()) {
|
|
964
880
|
for (const root of roots) {
|
|
965
881
|
try {
|
|
966
|
-
const resolved = createRequire(
|
|
882
|
+
const resolved = createRequire(join2(root, "noop.js")).resolve(specifier);
|
|
967
883
|
if (typeof resolved === "string" && resolved) return resolved;
|
|
968
884
|
} catch {
|
|
969
885
|
}
|
|
@@ -979,7 +895,7 @@ async function optionalImport(specifier, options = {}) {
|
|
|
979
895
|
const candidates = [specifier];
|
|
980
896
|
if (!injected && !specifier.startsWith(".") && !specifier.startsWith("/") && !specifier.startsWith("file:")) {
|
|
981
897
|
const resolved = resolveHostSpecifier(specifier, options.hostRoots ?? hostModuleRoots());
|
|
982
|
-
if (resolved) candidates.push(
|
|
898
|
+
if (resolved) candidates.push(pathToFileURL(resolved).href);
|
|
983
899
|
}
|
|
984
900
|
for (const candidate of candidates) {
|
|
985
901
|
try {
|
|
@@ -1194,7 +1110,6 @@ function jsonSafeChunk(value) {
|
|
|
1194
1110
|
return out;
|
|
1195
1111
|
}
|
|
1196
1112
|
async function* streamResponsesUnsafe(options, token) {
|
|
1197
|
-
const fetchImpl = await grokFetch() ?? globalThis.fetch;
|
|
1198
1113
|
const headers = {
|
|
1199
1114
|
Accept: "text/event-stream",
|
|
1200
1115
|
"Content-Type": "application/json",
|
|
@@ -1220,7 +1135,7 @@ async function* streamResponsesUnsafe(options, token) {
|
|
|
1220
1135
|
const tools = cacheStableTools(options.tools);
|
|
1221
1136
|
if (tools.length) body.tools = tools;
|
|
1222
1137
|
if (options.reasoningEffort) body.reasoning = { effort: options.reasoningEffort };
|
|
1223
|
-
const response = await
|
|
1138
|
+
const response = await fetch(RESPONSES_URL, {
|
|
1224
1139
|
method: "POST",
|
|
1225
1140
|
headers,
|
|
1226
1141
|
body: JSON.stringify(body),
|
|
@@ -1558,10 +1473,9 @@ function buildAuthConfig() {
|
|
|
1558
1473
|
}
|
|
1559
1474
|
};
|
|
1560
1475
|
}
|
|
1561
|
-
function withEncryptedReasoningInclude(api
|
|
1476
|
+
function withEncryptedReasoningInclude(api) {
|
|
1562
1477
|
const inject2 = (options) => ({
|
|
1563
1478
|
...options,
|
|
1564
|
-
...typeof fetchImpl === "function" ? { fetch: fetchImpl } : {},
|
|
1565
1479
|
samplingParams: {
|
|
1566
1480
|
...options?.samplingParams,
|
|
1567
1481
|
include: ["reasoning.encrypted_content"]
|
|
@@ -1631,7 +1545,7 @@ async function createGrokBuildAdapter(session, options = {}) {
|
|
|
1631
1545
|
if (!responsesApi) {
|
|
1632
1546
|
return { adapter: asHostAdapter(duck), kind: "custom-mvp", note: "openai-responses API module is unavailable; using the custom adapter." };
|
|
1633
1547
|
}
|
|
1634
|
-
responsesApi = withEncryptedReasoningInclude(responsesApi
|
|
1548
|
+
responsesApi = withEncryptedReasoningInclude(responsesApi);
|
|
1635
1549
|
const store = createStore(session);
|
|
1636
1550
|
const authModels = piAi.createModels({
|
|
1637
1551
|
credentials: store,
|
|
@@ -1722,54 +1636,17 @@ async function createGrokBuildAdapter(session, options = {}) {
|
|
|
1722
1636
|
}
|
|
1723
1637
|
|
|
1724
1638
|
// src/session.js
|
|
1725
|
-
function resolveGrokBin(env = process.env, exists =
|
|
1639
|
+
function resolveGrokBin(env = process.env, exists = existsSync3) {
|
|
1726
1640
|
if (typeof env.DSH_GROK_BIN === "string" && env.DSH_GROK_BIN.trim()) return env.DSH_GROK_BIN.trim();
|
|
1727
|
-
const local =
|
|
1641
|
+
const local = join3(grokHome(env), "bin", "grok");
|
|
1728
1642
|
if (exists(local)) return local;
|
|
1729
1643
|
return "grok";
|
|
1730
1644
|
}
|
|
1731
|
-
function grokCliAvailable(env = process.env, exists =
|
|
1645
|
+
function grokCliAvailable(env = process.env, exists = existsSync3) {
|
|
1732
1646
|
const bin = resolveGrokBin(env, exists);
|
|
1733
1647
|
if (bin.includes("/") || bin.includes("\\")) return exists(bin);
|
|
1734
1648
|
const delimiter = process.platform === "win32" ? ";" : ":";
|
|
1735
|
-
return String(env.PATH ?? "").split(delimiter).some((dir) => dir && exists(
|
|
1736
|
-
}
|
|
1737
|
-
var STANDARD_PROXY_NAMES = [
|
|
1738
|
-
"http_proxy",
|
|
1739
|
-
"https_proxy",
|
|
1740
|
-
"all_proxy",
|
|
1741
|
-
"no_proxy",
|
|
1742
|
-
"HTTP_PROXY",
|
|
1743
|
-
"HTTPS_PROXY",
|
|
1744
|
-
"ALL_PROXY",
|
|
1745
|
-
"NO_PROXY"
|
|
1746
|
-
];
|
|
1747
|
-
function cliProxyEnv(env = process.env) {
|
|
1748
|
-
const base = env ?? process.env;
|
|
1749
|
-
const declared = STANDARD_PROXY_NAMES.some((name2) => typeof base[name2] === "string" && base[name2].trim() !== "");
|
|
1750
|
-
if (declared) return base;
|
|
1751
|
-
const named = [base.GROK_CLI_PROXY, base.GROK_PROXY].find((value) => typeof value === "string" && value.trim() !== "");
|
|
1752
|
-
const proxy = typeof named === "string" ? named.trim() : "";
|
|
1753
|
-
if (!proxy) return base;
|
|
1754
|
-
const bypass = typeof base.GROK_CLI_NO_PROXY === "string" && base.GROK_CLI_NO_PROXY.trim() ? base.GROK_CLI_NO_PROXY.trim() : "localhost,127.0.0.1,::1";
|
|
1755
|
-
const httpish = /^https?:\/\//iu.test(proxy);
|
|
1756
|
-
return {
|
|
1757
|
-
...base,
|
|
1758
|
-
...httpish ? { http_proxy: proxy, https_proxy: proxy } : {},
|
|
1759
|
-
all_proxy: proxy,
|
|
1760
|
-
no_proxy: bypass
|
|
1761
|
-
};
|
|
1762
|
-
}
|
|
1763
|
-
async function resolveCliEnv(env = process.env) {
|
|
1764
|
-
const base = env ?? process.env;
|
|
1765
|
-
const overlay = await hostProxyEnvironment();
|
|
1766
|
-
if (!overlay) return cliProxyEnv(base);
|
|
1767
|
-
const next = { ...base };
|
|
1768
|
-
for (const [key, value] of Object.entries(overlay)) {
|
|
1769
|
-
if (value === void 0) delete next[key];
|
|
1770
|
-
else next[key] = value;
|
|
1771
|
-
}
|
|
1772
|
-
return next;
|
|
1649
|
+
return String(env.PATH ?? "").split(delimiter).some((dir) => dir && exists(join3(dir, bin)));
|
|
1773
1650
|
}
|
|
1774
1651
|
function openExternal(url, options = {}) {
|
|
1775
1652
|
const spawnFn = options.spawn ?? spawn;
|
|
@@ -1802,13 +1679,12 @@ async function spawnGrokLogin(options = {}) {
|
|
|
1802
1679
|
const args = options.device ? ["login", "--device-auth"] : ["login"];
|
|
1803
1680
|
const startTimeoutMs = typeof options.startTimeoutMs === "number" && options.startTimeoutMs > 0 ? options.startTimeoutMs : LOGIN_START_TIMEOUT_MS;
|
|
1804
1681
|
const openUrl = options.openUrl ?? ((url) => openExternal(url, { spawn: options.openSpawn }));
|
|
1805
|
-
const childEnv = await resolveCliEnv(options.env);
|
|
1806
1682
|
return new Promise((resolve, reject) => {
|
|
1807
1683
|
let child;
|
|
1808
1684
|
try {
|
|
1809
1685
|
child = spawnFn(bin, args, {
|
|
1810
1686
|
stdio: options.stdio ?? ["ignore", "pipe", "pipe"],
|
|
1811
|
-
env:
|
|
1687
|
+
env: options.env ?? process.env
|
|
1812
1688
|
});
|
|
1813
1689
|
} catch (error) {
|
|
1814
1690
|
reject(new Error(`Could not start grok CLI (${bin})`, { cause: error }));
|
|
@@ -1875,13 +1751,12 @@ async function spawnGrokRefresh(options = {}) {
|
|
|
1875
1751
|
const spawnFn = options.spawn ?? spawn;
|
|
1876
1752
|
const bin = resolveGrokBin(options.env, options.exists);
|
|
1877
1753
|
const timeoutMs = typeof options.timeoutMs === "number" && options.timeoutMs > 0 ? options.timeoutMs : CLI_REFRESH_TIMEOUT_MS;
|
|
1878
|
-
const childEnv = await resolveCliEnv(options.env);
|
|
1879
1754
|
return new Promise((resolve, reject) => {
|
|
1880
1755
|
let child;
|
|
1881
1756
|
try {
|
|
1882
1757
|
child = spawnFn(bin, ["models"], {
|
|
1883
1758
|
stdio: options.stdio ?? "ignore",
|
|
1884
|
-
env:
|
|
1759
|
+
env: options.env ?? process.env
|
|
1885
1760
|
});
|
|
1886
1761
|
} catch (error) {
|
|
1887
1762
|
reject(new Error(`Could not start grok CLI (${bin})`, { cause: error }));
|
|
@@ -2248,7 +2123,7 @@ function createSessionService({
|
|
|
2248
2123
|
import { spawn as spawn2 } from "node:child_process";
|
|
2249
2124
|
import { readdir, readFile, realpath } from "node:fs/promises";
|
|
2250
2125
|
import { homedir as homedir3 } from "node:os";
|
|
2251
|
-
import { join as
|
|
2126
|
+
import { join as join4 } from "node:path";
|
|
2252
2127
|
import { fileURLToPath } from "node:url";
|
|
2253
2128
|
var PACKAGE_NAME = PLUGIN_ID;
|
|
2254
2129
|
var NPM_REGISTRY_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
@@ -2297,20 +2172,20 @@ async function findInstall({ dshHome, ownPackageJsonUrl }) {
|
|
|
2297
2172
|
}
|
|
2298
2173
|
let entries = [];
|
|
2299
2174
|
try {
|
|
2300
|
-
entries = await readdir(
|
|
2175
|
+
entries = await readdir(join4(dshHome, "profiles"), { withFileTypes: true });
|
|
2301
2176
|
} catch {
|
|
2302
2177
|
entries = [];
|
|
2303
2178
|
}
|
|
2304
2179
|
const declared = [];
|
|
2305
2180
|
for (const entry of entries) {
|
|
2306
2181
|
if (!entry.isDirectory()) continue;
|
|
2307
|
-
const profileDir =
|
|
2308
|
-
const spec = (await readManifest(
|
|
2182
|
+
const profileDir = join4(dshHome, "profiles", entry.name);
|
|
2183
|
+
const spec = (await readManifest(join4(profileDir, "package.json")))?.dependencies?.[PACKAGE_NAME];
|
|
2309
2184
|
if (typeof spec !== "string") continue;
|
|
2310
2185
|
declared.push({ profile: entry.name, spec });
|
|
2311
2186
|
if (ownReal === void 0) continue;
|
|
2312
2187
|
try {
|
|
2313
|
-
const installed = await realpath(
|
|
2188
|
+
const installed = await realpath(join4(profileDir, "node_modules", PACKAGE_NAME, "package.json"));
|
|
2314
2189
|
if (installed === ownReal) return { kind: classifySpec(spec), profile: entry.name };
|
|
2315
2190
|
} catch {
|
|
2316
2191
|
}
|
|
@@ -2377,8 +2252,8 @@ function createGrokPluginManager({
|
|
|
2377
2252
|
} = {}) {
|
|
2378
2253
|
if (typeof fetchImpl !== "function") throw new Error("Grok plugin manager requires fetch");
|
|
2379
2254
|
if (typeof runCommand !== "function") throw new Error("Grok plugin manager requires runCommand");
|
|
2380
|
-
const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME !== "" ? env.DSH_HOME :
|
|
2381
|
-
let
|
|
2255
|
+
const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME !== "" ? env.DSH_HOME : join4(homedir3(), ".dsh");
|
|
2256
|
+
let cached;
|
|
2382
2257
|
let inFlight;
|
|
2383
2258
|
let generation = 0;
|
|
2384
2259
|
let updating = false;
|
|
@@ -2429,11 +2304,11 @@ function createGrokPluginManager({
|
|
|
2429
2304
|
return Object.freeze({
|
|
2430
2305
|
async read({ force = false, signal } = {}) {
|
|
2431
2306
|
signal?.throwIfAborted();
|
|
2432
|
-
if (!force &&
|
|
2307
|
+
if (!force && cached !== void 0 && now() - cached.fetchedAt < ttlMs) return clone(cached);
|
|
2433
2308
|
const createPending = (requestSignal) => {
|
|
2434
2309
|
const observedGeneration = generation;
|
|
2435
2310
|
return load(requestSignal).then((value) => {
|
|
2436
|
-
if (generation === observedGeneration)
|
|
2311
|
+
if (generation === observedGeneration) cached = value;
|
|
2437
2312
|
return value;
|
|
2438
2313
|
});
|
|
2439
2314
|
};
|
|
@@ -2476,7 +2351,7 @@ function createGrokPluginManager({
|
|
|
2476
2351
|
}
|
|
2477
2352
|
if (result.code !== 0) throw new Error("Grok plugin update failed");
|
|
2478
2353
|
generation += 1;
|
|
2479
|
-
|
|
2354
|
+
cached = void 0;
|
|
2480
2355
|
return { version: latest, profile: install.profile };
|
|
2481
2356
|
} finally {
|
|
2482
2357
|
updating = false;
|
|
@@ -2484,7 +2359,7 @@ function createGrokPluginManager({
|
|
|
2484
2359
|
},
|
|
2485
2360
|
invalidate() {
|
|
2486
2361
|
generation += 1;
|
|
2487
|
-
|
|
2362
|
+
cached = void 0;
|
|
2488
2363
|
}
|
|
2489
2364
|
});
|
|
2490
2365
|
}
|