grok-search-cli 0.1.1 → 0.1.3
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 +161 -66
- package/README.zh.md +159 -65
- package/dist/cli.js +99 -554
- package/dist/index.js +2 -0
- package/dist/search-DcS355m9.js +573 -0
- package/dist/src/args.d.ts +4 -0
- package/dist/src/cli.d.ts +1 -0
- package/dist/src/config.d.ts +35 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/openrouter.d.ts +38 -0
- package/dist/src/openrouter.test.d.ts +1 -0
- package/dist/src/output.d.ts +19 -0
- package/dist/src/providers.d.ts +12 -0
- package/dist/src/search.d.ts +34 -0
- package/dist/src/skill.d.ts +2 -0
- package/dist/src/types.d.ts +121 -0
- package/package.json +34 -7
package/dist/index.js
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
import { chmodSync as e, existsSync as t, mkdirSync as n, writeFileSync as r } from "node:fs";
|
|
2
|
+
import i from "node:os";
|
|
3
|
+
import a from "node:path";
|
|
4
|
+
import o from "conf";
|
|
5
|
+
import { generateText as s, streamText as c } from "ai";
|
|
6
|
+
import { createOpenAICompatible as l } from "@ai-sdk/openai-compatible";
|
|
7
|
+
import { createXai as ee, xai as u } from "@ai-sdk/xai";
|
|
8
|
+
//#region src/config.ts
|
|
9
|
+
var d = "grok-4-1-fast-non-reasoning", f = a.join(i.homedir(), ".config", "grok-search-cli");
|
|
10
|
+
function p(e) {
|
|
11
|
+
return typeof e == "string" && e.trim() || void 0;
|
|
12
|
+
}
|
|
13
|
+
function m() {
|
|
14
|
+
return {
|
|
15
|
+
XAI_API_KEY: "",
|
|
16
|
+
XAI_MODEL: d,
|
|
17
|
+
XAI_BASE_URL: "",
|
|
18
|
+
XAI_COMPAT_MODE: !1,
|
|
19
|
+
_examples: {
|
|
20
|
+
xai: {
|
|
21
|
+
XAI_API_KEY: "your_xai_api_key",
|
|
22
|
+
XAI_MODEL: "grok-4-1-fast-non-reasoning"
|
|
23
|
+
},
|
|
24
|
+
openrouter: {
|
|
25
|
+
XAI_API_KEY: "your_openrouter_api_key",
|
|
26
|
+
XAI_MODEL: "x-ai/grok-4.1-fast",
|
|
27
|
+
XAI_BASE_URL: "https://openrouter.ai/api/v1"
|
|
28
|
+
},
|
|
29
|
+
yunwu: {
|
|
30
|
+
XAI_API_KEY: "your_yunwu_api_key",
|
|
31
|
+
XAI_MODEL: "grok-4-fast",
|
|
32
|
+
XAI_BASE_URL: "https://yunwu.ai/v1",
|
|
33
|
+
XAI_COMPAT_MODE: !0
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function te() {
|
|
39
|
+
try {
|
|
40
|
+
return new o({
|
|
41
|
+
projectName: "grok-search-cli",
|
|
42
|
+
configName: "config",
|
|
43
|
+
cwd: f,
|
|
44
|
+
defaults: m()
|
|
45
|
+
});
|
|
46
|
+
} catch (e) {
|
|
47
|
+
let t = e instanceof Error ? e.message : String(e);
|
|
48
|
+
throw Error(`Failed to initialize user config: ${t}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
var h = te(), g = h.path;
|
|
52
|
+
function _() {
|
|
53
|
+
if (n(a.dirname(g), { recursive: !0 }), !t(g)) {
|
|
54
|
+
r(g, `${JSON.stringify(m(), null, 2)}\n`, "utf8");
|
|
55
|
+
try {
|
|
56
|
+
e(g, 384);
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
59
|
+
return g;
|
|
60
|
+
}
|
|
61
|
+
function v() {
|
|
62
|
+
let e = h.store;
|
|
63
|
+
return {
|
|
64
|
+
apiKey: p(process.env.XAI_API_KEY) ?? e?.XAI_API_KEY,
|
|
65
|
+
model: p(process.env.XAI_MODEL) ?? e?.XAI_MODEL ?? d,
|
|
66
|
+
baseUrl: p(process.env.XAI_BASE_URL) ?? e?.XAI_BASE_URL,
|
|
67
|
+
compatModeRaw: process.env.XAI_COMPAT_MODE?.trim() ?? e?.XAI_COMPAT_MODE
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function y(e) {
|
|
71
|
+
return e ? {
|
|
72
|
+
apiKey: p(e.apiKey),
|
|
73
|
+
model: p(e.model) ?? d,
|
|
74
|
+
baseUrl: p(e.baseUrl),
|
|
75
|
+
compatModeRaw: e.compatMode
|
|
76
|
+
} : v();
|
|
77
|
+
}
|
|
78
|
+
function b() {
|
|
79
|
+
let e = h.store;
|
|
80
|
+
return {
|
|
81
|
+
apiKey: p(process.env.XAI_API_KEY) ? "env" : e?.XAI_API_KEY ? "config" : "missing",
|
|
82
|
+
model: p(process.env.XAI_MODEL) ? "env" : e?.XAI_MODEL ? "config" : "default",
|
|
83
|
+
baseUrl: p(process.env.XAI_BASE_URL) ? "env" : e?.XAI_BASE_URL ? "config" : "default",
|
|
84
|
+
compatMode: process.env.XAI_COMPAT_MODE?.trim() ? "env" : e?.XAI_COMPAT_MODE == null ? "default" : "config"
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function ne() {
|
|
88
|
+
return y().model;
|
|
89
|
+
}
|
|
90
|
+
function x() {
|
|
91
|
+
return y().baseUrl;
|
|
92
|
+
}
|
|
93
|
+
function re() {
|
|
94
|
+
let e = v(), t = b(), n = T(), r = C(e.baseUrl);
|
|
95
|
+
return {
|
|
96
|
+
configPath: g,
|
|
97
|
+
apiKeyPresent: !!e.apiKey,
|
|
98
|
+
model: e.model,
|
|
99
|
+
baseUrl: e.baseUrl,
|
|
100
|
+
providerKind: r,
|
|
101
|
+
apiMode: n,
|
|
102
|
+
sources: t
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function S(e) {
|
|
106
|
+
if (!e) return !1;
|
|
107
|
+
try {
|
|
108
|
+
let { hostname: t } = new URL(e);
|
|
109
|
+
return t === "openrouter.ai" || t.endsWith(".openrouter.ai");
|
|
110
|
+
} catch {
|
|
111
|
+
return !1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function C(e) {
|
|
115
|
+
if (!e) return "xai";
|
|
116
|
+
if (S(e)) return "openrouter";
|
|
117
|
+
try {
|
|
118
|
+
let { hostname: t } = new URL(e);
|
|
119
|
+
if (t === "x.ai" || t.endsWith(".x.ai")) return "xai";
|
|
120
|
+
} catch {}
|
|
121
|
+
return "third-party";
|
|
122
|
+
}
|
|
123
|
+
function w(e) {
|
|
124
|
+
let { compatModeRaw: t, baseUrl: n } = y(e);
|
|
125
|
+
return C(n) !== "openrouter" && /^(1|true|yes|on)$/i.test(String(t || ""));
|
|
126
|
+
}
|
|
127
|
+
function T(e) {
|
|
128
|
+
return w(e) ? "completion" : "responses";
|
|
129
|
+
}
|
|
130
|
+
function E(e, t = x()) {
|
|
131
|
+
return C(t) === "openrouter" && e === "responses" ? "OpenRouter Responses API Beta" : e === "responses" ? "xAI Responses API" : "OpenAI-compatible /chat/completions";
|
|
132
|
+
}
|
|
133
|
+
function D(e, t) {
|
|
134
|
+
if (e === "xai") {
|
|
135
|
+
console.error(t === "responses" ? "xAI Responses API request failed. Check XAI_API_KEY, model name, and search parameters." : "xAI-compatible completion request failed. Check XAI_API_KEY, model name, and gateway settings.");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (e === "openrouter") {
|
|
139
|
+
console.error("OpenRouter request failed. This CLI uses OpenRouter Responses API web search for openrouter.ai endpoints.");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
console.error("Third-party gateway request failed. Verify the gateway supports the selected API shape and that web search is enabled on the provider side.");
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/output.ts
|
|
146
|
+
function O({ model: e, finishReason: t, requestApi: n, baseUrl: r, durationMs: i, firstTokenLatencyMs: a, usage: o }) {
|
|
147
|
+
let s = o ?? {}, c = s.outputTokens, l = s.outputTokenDetails?.reasoningTokens;
|
|
148
|
+
return {
|
|
149
|
+
model: e,
|
|
150
|
+
finishReason: t,
|
|
151
|
+
requestApi: n,
|
|
152
|
+
baseUrl: r,
|
|
153
|
+
durationMs: i,
|
|
154
|
+
firstTokenLatencyMs: a,
|
|
155
|
+
tokensPerSecond: typeof c == "number" && i > 0 ? Number((c * 1e3 / i).toFixed(2)) : void 0,
|
|
156
|
+
usage: {
|
|
157
|
+
inputTokens: s.inputTokens,
|
|
158
|
+
outputTokens: c,
|
|
159
|
+
reasoningTokens: l,
|
|
160
|
+
totalTokens: s.totalTokens
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function k(e) {
|
|
165
|
+
process.stdout.write("\nVerbose:\n"), process.stdout.write(`Model: ${e.model}\n`), process.stdout.write(`Finish reason: ${e.finishReason}\n`), process.stdout.write(`Request API: ${e.requestApi}\n`), e.baseUrl && process.stdout.write(`Base URL: ${e.baseUrl}\n`);
|
|
166
|
+
let t = [`Duration: ${(e.durationMs / 1e3).toFixed(2)}s`];
|
|
167
|
+
e.firstTokenLatencyMs != null && t.push(`first token ${(e.firstTokenLatencyMs / 1e3).toFixed(2)}s`), process.stdout.write(`${t.join(", ")}\n`);
|
|
168
|
+
let n = [
|
|
169
|
+
e.usage.inputTokens == null ? void 0 : `input=${e.usage.inputTokens}`,
|
|
170
|
+
e.usage.outputTokens == null ? void 0 : `output=${e.usage.outputTokens}`,
|
|
171
|
+
e.usage.reasoningTokens == null ? void 0 : `reasoning=${e.usage.reasoningTokens}`,
|
|
172
|
+
e.usage.totalTokens == null ? void 0 : `total=${e.usage.totalTokens}`
|
|
173
|
+
].filter(Boolean);
|
|
174
|
+
n.length > 0 && process.stdout.write(`Usage: ${n.join(", ")}\n`), e.tokensPerSecond != null && process.stdout.write(`TPS: ${e.tokensPerSecond}\n`);
|
|
175
|
+
}
|
|
176
|
+
function ie(e) {
|
|
177
|
+
process.stdout.write(`${e.text}\n`), e.verbose && k(e.verbose);
|
|
178
|
+
}
|
|
179
|
+
async function ae(e) {
|
|
180
|
+
let t = !1, n = !1, r;
|
|
181
|
+
for await (let i of e.stream.textStream) r ??= Date.now() - e.startedAt, t = !0, n = i.endsWith("\n"), process.stdout.write(i);
|
|
182
|
+
(!t || !n) && process.stdout.write("\n");
|
|
183
|
+
let i = await e.stream.usage, a = await e.stream.finishReason ?? "unknown", o = {
|
|
184
|
+
...e.payload,
|
|
185
|
+
text: await e.stream.text,
|
|
186
|
+
finishReason: a,
|
|
187
|
+
usage: i ?? null,
|
|
188
|
+
sources: await e.stream.sources ?? [],
|
|
189
|
+
verbose: e.includeVerbose ? O({
|
|
190
|
+
model: e.payload.model,
|
|
191
|
+
finishReason: a,
|
|
192
|
+
requestApi: e.requestApi,
|
|
193
|
+
baseUrl: e.baseUrl,
|
|
194
|
+
durationMs: Date.now() - e.startedAt,
|
|
195
|
+
firstTokenLatencyMs: r,
|
|
196
|
+
usage: i
|
|
197
|
+
}) : void 0
|
|
198
|
+
};
|
|
199
|
+
o.verbose && (process.stdout.write("\n"), k(o.verbose));
|
|
200
|
+
}
|
|
201
|
+
//#endregion
|
|
202
|
+
//#region node_modules/.pnpm/p-defer@4.0.1/node_modules/p-defer/index.js
|
|
203
|
+
function oe() {
|
|
204
|
+
let e = {};
|
|
205
|
+
return e.promise = new Promise((t, n) => {
|
|
206
|
+
e.resolve = t, e.reject = n;
|
|
207
|
+
}), e;
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region src/openrouter.ts
|
|
211
|
+
function A(e) {
|
|
212
|
+
let t = {};
|
|
213
|
+
return e.allowedDomains.length > 0 && (t.allowed_domains = e.allowedDomains), e.excludedDomains.length > 0 && (t.excluded_domains = e.excludedDomains), se(t) ? {
|
|
214
|
+
type: "openrouter:web_search",
|
|
215
|
+
parameters: t
|
|
216
|
+
} : { type: "openrouter:web_search" };
|
|
217
|
+
}
|
|
218
|
+
function se(e) {
|
|
219
|
+
return Object.keys(e).length > 0;
|
|
220
|
+
}
|
|
221
|
+
function j(e, t, n) {
|
|
222
|
+
return {
|
|
223
|
+
model: t.model,
|
|
224
|
+
input: e,
|
|
225
|
+
tools: [A(t)],
|
|
226
|
+
stream: n
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
async function M(e) {
|
|
230
|
+
if (!e.ok) throw Error(await e.text());
|
|
231
|
+
return e;
|
|
232
|
+
}
|
|
233
|
+
function N(e) {
|
|
234
|
+
return (e.output?.find((e) => e.type === "message"))?.content?.find((e) => e.type === "output_text")?.text ?? "";
|
|
235
|
+
}
|
|
236
|
+
function P(e) {
|
|
237
|
+
return ((e.output?.find((e) => e.type === "message"))?.content?.find((e) => e.type === "output_text"))?.annotations?.filter((e) => e.type === "url_citation").map((e) => ({
|
|
238
|
+
sourceType: "url_citation",
|
|
239
|
+
url: e.url
|
|
240
|
+
})) ?? [];
|
|
241
|
+
}
|
|
242
|
+
function F(e) {
|
|
243
|
+
return {
|
|
244
|
+
inputTokens: e?.input_tokens,
|
|
245
|
+
outputTokens: e?.output_tokens,
|
|
246
|
+
totalTokens: e?.total_tokens,
|
|
247
|
+
outputTokenDetails: {
|
|
248
|
+
textTokens: e?.output_tokens,
|
|
249
|
+
reasoningTokens: void 0
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function I(e) {
|
|
254
|
+
return {
|
|
255
|
+
text: N(e),
|
|
256
|
+
finishReason: e.status ?? "unknown",
|
|
257
|
+
usage: F(e.usage),
|
|
258
|
+
sources: P(e)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
async function L(e) {
|
|
262
|
+
return M(await fetch(`${e.baseUrl}/responses`, {
|
|
263
|
+
method: "POST",
|
|
264
|
+
headers: {
|
|
265
|
+
Authorization: `Bearer ${e.apiKey}`,
|
|
266
|
+
"Content-Type": "application/json"
|
|
267
|
+
},
|
|
268
|
+
body: JSON.stringify(e.body),
|
|
269
|
+
signal: e.abortSignal
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
272
|
+
function R(e) {
|
|
273
|
+
return (t) => ({
|
|
274
|
+
...t,
|
|
275
|
+
tools: [A(e)]
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
function z(e) {
|
|
279
|
+
if (!e.startsWith("data: ")) return { type: "ignore" };
|
|
280
|
+
let t = e.slice(6);
|
|
281
|
+
if (t === "[DONE]") return { type: "done" };
|
|
282
|
+
let n = JSON.parse(t);
|
|
283
|
+
return n.type === "response.output_text.delta" && typeof n.delta == "string" ? {
|
|
284
|
+
type: "delta",
|
|
285
|
+
text: n.delta
|
|
286
|
+
} : n.type === "response.completed" ? {
|
|
287
|
+
type: "completed",
|
|
288
|
+
response: n.response
|
|
289
|
+
} : { type: "ignore" };
|
|
290
|
+
}
|
|
291
|
+
async function B(e) {
|
|
292
|
+
return I(await (await L({
|
|
293
|
+
baseUrl: e.baseUrl,
|
|
294
|
+
apiKey: e.apiKey,
|
|
295
|
+
body: j(e.prompt, e.options, !1),
|
|
296
|
+
abortSignal: e.abortSignal
|
|
297
|
+
})).json());
|
|
298
|
+
}
|
|
299
|
+
async function V(e) {
|
|
300
|
+
let t = (await L({
|
|
301
|
+
baseUrl: e.baseUrl,
|
|
302
|
+
apiKey: e.apiKey,
|
|
303
|
+
body: j(e.prompt, e.options, !0),
|
|
304
|
+
abortSignal: e.abortSignal
|
|
305
|
+
})).body?.getReader();
|
|
306
|
+
if (!t) throw Error("OpenRouter streaming response body is missing.");
|
|
307
|
+
let n = new TextDecoder(), r = "", i = oe(), a = !1, o = (async function* () {
|
|
308
|
+
try {
|
|
309
|
+
for (;;) {
|
|
310
|
+
let { done: e, value: o } = await t.read();
|
|
311
|
+
if (e) break;
|
|
312
|
+
r += n.decode(o, { stream: !0 });
|
|
313
|
+
let s = r.split("\n");
|
|
314
|
+
r = s.pop() ?? "";
|
|
315
|
+
for (let e of s) {
|
|
316
|
+
let t = z(e);
|
|
317
|
+
if (t.type === "delta") {
|
|
318
|
+
yield t.text;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (t.type === "completed") {
|
|
322
|
+
a = !0, i.resolve(t.response);
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
if (t.type === "done") return;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
a || i.reject(/* @__PURE__ */ Error("OpenRouter stream ended before response.completed."));
|
|
329
|
+
} catch (e) {
|
|
330
|
+
throw i.reject(e), e;
|
|
331
|
+
}
|
|
332
|
+
})(), s = i.promise.then(I);
|
|
333
|
+
return {
|
|
334
|
+
textStream: o,
|
|
335
|
+
text: s.then((e) => e.text),
|
|
336
|
+
finishReason: s.then((e) => e.finishReason),
|
|
337
|
+
usage: s.then((e) => e.usage),
|
|
338
|
+
sources: s.then((e) => e.sources)
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/providers.ts
|
|
343
|
+
function H(e) {
|
|
344
|
+
return e.stream === !0 ? {
|
|
345
|
+
...e,
|
|
346
|
+
stream_options: {
|
|
347
|
+
...typeof e.stream_options == "object" && e.stream_options != null ? e.stream_options : {},
|
|
348
|
+
include_usage: !0
|
|
349
|
+
}
|
|
350
|
+
} : e;
|
|
351
|
+
}
|
|
352
|
+
function U(e) {
|
|
353
|
+
return {
|
|
354
|
+
web_search: u.tools.webSearch({
|
|
355
|
+
allowedDomains: e.allowedDomains.length > 0 ? e.allowedDomains : void 0,
|
|
356
|
+
excludedDomains: e.excludedDomains.length > 0 ? e.excludedDomains : void 0,
|
|
357
|
+
enableImageUnderstanding: e.enableImageUnderstanding || void 0
|
|
358
|
+
}),
|
|
359
|
+
x_search: u.tools.xSearch({
|
|
360
|
+
allowedXHandles: e.allowedHandles.length > 0 ? e.allowedHandles : void 0,
|
|
361
|
+
excludedXHandles: e.excludedHandles.length > 0 ? e.excludedHandles : void 0,
|
|
362
|
+
fromDate: e.fromDate,
|
|
363
|
+
toDate: e.toDate,
|
|
364
|
+
enableImageUnderstanding: e.enableImageUnderstanding || void 0,
|
|
365
|
+
enableVideoUnderstanding: e.enableVideoUnderstanding || void 0
|
|
366
|
+
})
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function W(e) {
|
|
370
|
+
let { baseUrl: t } = e;
|
|
371
|
+
return t ? ee({ baseURL: t }) : u;
|
|
372
|
+
}
|
|
373
|
+
function G(e, t) {
|
|
374
|
+
let { baseUrl: n, apiKey: r } = e, i = S(n) ? R(t) : void 0;
|
|
375
|
+
return l({
|
|
376
|
+
name: "compat",
|
|
377
|
+
apiKey: r,
|
|
378
|
+
baseURL: n || "https://api.x.ai/v1",
|
|
379
|
+
transformRequestBody: (e) => H(i ? i(e) : e)
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
function K(e) {
|
|
383
|
+
return e.allowedDomains.length > 0 || e.excludedDomains.length > 0 || e.allowedHandles.length > 0 || e.excludedHandles.length > 0 || typeof e.fromDate == "string" || typeof e.toDate == "string" || e.enableImageUnderstanding || e.enableVideoUnderstanding;
|
|
384
|
+
}
|
|
385
|
+
function ce(e) {
|
|
386
|
+
return e.allowedHandles.length > 0 || e.excludedHandles.length > 0 || typeof e.fromDate == "string" || typeof e.toDate == "string" || e.enableImageUnderstanding || e.enableVideoUnderstanding;
|
|
387
|
+
}
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/search.ts
|
|
390
|
+
var le = "grok-4-1-fast-non-reasoning";
|
|
391
|
+
function q(e = le) {
|
|
392
|
+
return {
|
|
393
|
+
model: e,
|
|
394
|
+
timeoutMs: 6e4,
|
|
395
|
+
verbose: !1,
|
|
396
|
+
allowedDomains: [],
|
|
397
|
+
excludedDomains: [],
|
|
398
|
+
allowedHandles: [],
|
|
399
|
+
excludedHandles: [],
|
|
400
|
+
enableImageUnderstanding: !1,
|
|
401
|
+
enableVideoUnderstanding: !1
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function ue(e) {
|
|
405
|
+
let t = q(y(e).model);
|
|
406
|
+
return {
|
|
407
|
+
...t,
|
|
408
|
+
model: e.model?.trim() || t.model,
|
|
409
|
+
timeoutMs: e.timeoutMs ?? t.timeoutMs,
|
|
410
|
+
verbose: e.verbose ?? t.verbose,
|
|
411
|
+
allowedDomains: e.allowedDomains ?? t.allowedDomains,
|
|
412
|
+
excludedDomains: e.excludedDomains ?? t.excludedDomains,
|
|
413
|
+
allowedHandles: e.allowedHandles ?? t.allowedHandles,
|
|
414
|
+
excludedHandles: e.excludedHandles ?? t.excludedHandles,
|
|
415
|
+
fromDate: e.fromDate,
|
|
416
|
+
toDate: e.toDate,
|
|
417
|
+
enableImageUnderstanding: e.enableImageUnderstanding ?? t.enableImageUnderstanding,
|
|
418
|
+
enableVideoUnderstanding: e.enableVideoUnderstanding ?? t.enableVideoUnderstanding
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function de(e) {
|
|
422
|
+
let t = y(e);
|
|
423
|
+
if (!t.apiKey) throw Error("Missing XAI_API_KEY in grokSearch config.");
|
|
424
|
+
return t.apiKey;
|
|
425
|
+
}
|
|
426
|
+
function J() {
|
|
427
|
+
let e = y();
|
|
428
|
+
if (!e.apiKey) {
|
|
429
|
+
let e = _();
|
|
430
|
+
throw Error(`Missing XAI_API_KEY.\n\nEdit ${e} or set XAI_API_KEY in your shell environment.\nThis CLI reads credentials from process.env first, then ${g}.`);
|
|
431
|
+
}
|
|
432
|
+
return e.apiKey;
|
|
433
|
+
}
|
|
434
|
+
function fe(e, t, n) {
|
|
435
|
+
return e === "completion" && K(n) && !S(t);
|
|
436
|
+
}
|
|
437
|
+
function Y(e, t) {
|
|
438
|
+
return t === "openrouter" && e === "responses";
|
|
439
|
+
}
|
|
440
|
+
function pe(e, t, n) {
|
|
441
|
+
let r = C(t), i = [];
|
|
442
|
+
return fe(e, t, n) && i.push("Warning: compatibility mode is enabled, so tool-specific filters are not forwarded. Remove XAI_COMPAT_MODE to use xAI Responses API."), Y(e, r) && ce(n) && i.push("Warning: OpenRouter server-tool mode currently forwards web domain filters only. X-specific filters such as handles, dates, image, and video options are ignored."), i;
|
|
443
|
+
}
|
|
444
|
+
function X(e, t, n, r) {
|
|
445
|
+
return {
|
|
446
|
+
prompt: e,
|
|
447
|
+
runtimeConfig: t,
|
|
448
|
+
apiMode: r,
|
|
449
|
+
requestApi: E(r, t.baseUrl),
|
|
450
|
+
providerKind: C(t.baseUrl),
|
|
451
|
+
options: n,
|
|
452
|
+
startedAt: Date.now(),
|
|
453
|
+
abortSignal: AbortSignal.timeout(n.timeoutMs)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function me(e, t) {
|
|
457
|
+
if (!t) throw Error("grokSearch requires an explicit config object.");
|
|
458
|
+
return de(t), X(e, y(t), ue(t), T(t));
|
|
459
|
+
}
|
|
460
|
+
function he(e, t) {
|
|
461
|
+
return J(), X(e, y(), t, T());
|
|
462
|
+
}
|
|
463
|
+
function Z(e) {
|
|
464
|
+
return {
|
|
465
|
+
command: e.command,
|
|
466
|
+
apiMode: e.apiMode,
|
|
467
|
+
model: e.model,
|
|
468
|
+
prompt: e.prompt,
|
|
469
|
+
text: e.result.text,
|
|
470
|
+
finishReason: e.result.finishReason ?? "unknown",
|
|
471
|
+
usage: e.result.usage ?? null,
|
|
472
|
+
sources: e.result.sources ?? [],
|
|
473
|
+
verbose: e.verbose ? O({
|
|
474
|
+
model: e.model,
|
|
475
|
+
finishReason: e.result.finishReason ?? "unknown",
|
|
476
|
+
requestApi: e.requestApi,
|
|
477
|
+
baseUrl: e.baseUrl,
|
|
478
|
+
durationMs: Date.now() - e.startedAt,
|
|
479
|
+
usage: e.result.usage ?? null
|
|
480
|
+
}) : void 0
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
function ge(e) {
|
|
484
|
+
if (e.apiMode === "responses") {
|
|
485
|
+
let t = c({
|
|
486
|
+
model: W(e.runtimeConfig).responses(e.options.model),
|
|
487
|
+
prompt: e.prompt,
|
|
488
|
+
tools: U(e.options),
|
|
489
|
+
abortSignal: e.abortSignal
|
|
490
|
+
});
|
|
491
|
+
return {
|
|
492
|
+
textStream: t.textStream,
|
|
493
|
+
text: t.text,
|
|
494
|
+
finishReason: t.finishReason,
|
|
495
|
+
usage: t.usage,
|
|
496
|
+
sources: t.sources
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
let t = c({
|
|
500
|
+
model: G(e.runtimeConfig, e.options)(e.options.model),
|
|
501
|
+
prompt: e.prompt,
|
|
502
|
+
abortSignal: e.abortSignal
|
|
503
|
+
});
|
|
504
|
+
return {
|
|
505
|
+
textStream: t.textStream,
|
|
506
|
+
text: t.text,
|
|
507
|
+
finishReason: t.finishReason,
|
|
508
|
+
usage: t.usage,
|
|
509
|
+
sources: t.sources
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
async function _e(e) {
|
|
513
|
+
if (e.apiMode === "responses") {
|
|
514
|
+
let t = await s({
|
|
515
|
+
model: W(e.runtimeConfig).responses(e.options.model),
|
|
516
|
+
prompt: e.prompt,
|
|
517
|
+
tools: U(e.options),
|
|
518
|
+
abortSignal: e.abortSignal
|
|
519
|
+
});
|
|
520
|
+
return {
|
|
521
|
+
text: t.text,
|
|
522
|
+
finishReason: t.finishReason ?? "unknown",
|
|
523
|
+
usage: t.usage ?? null,
|
|
524
|
+
sources: t.sources ?? []
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
let t = await s({
|
|
528
|
+
model: G(e.runtimeConfig, e.options)(e.options.model),
|
|
529
|
+
prompt: e.prompt,
|
|
530
|
+
abortSignal: e.abortSignal
|
|
531
|
+
});
|
|
532
|
+
return {
|
|
533
|
+
text: t.text,
|
|
534
|
+
finishReason: t.finishReason ?? "unknown",
|
|
535
|
+
usage: t.usage ?? null,
|
|
536
|
+
sources: t.sources ?? []
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
async function Q(e) {
|
|
540
|
+
return Y(e.apiMode, e.providerKind) ? V({
|
|
541
|
+
prompt: e.prompt,
|
|
542
|
+
options: e.options,
|
|
543
|
+
baseUrl: e.runtimeConfig.baseUrl || "https://openrouter.ai/api/v1",
|
|
544
|
+
apiKey: e.runtimeConfig.apiKey,
|
|
545
|
+
abortSignal: e.abortSignal
|
|
546
|
+
}) : ge(e);
|
|
547
|
+
}
|
|
548
|
+
async function $(e) {
|
|
549
|
+
return Y(e.apiMode, e.providerKind) ? B({
|
|
550
|
+
prompt: e.prompt,
|
|
551
|
+
options: e.options,
|
|
552
|
+
baseUrl: e.runtimeConfig.baseUrl || "https://openrouter.ai/api/v1",
|
|
553
|
+
apiKey: e.runtimeConfig.apiKey,
|
|
554
|
+
abortSignal: e.abortSignal
|
|
555
|
+
}) : _e(e);
|
|
556
|
+
}
|
|
557
|
+
async function ve(e, t) {
|
|
558
|
+
if (!t) throw Error("grokSearch requires an explicit config object.");
|
|
559
|
+
let n = me(e, t), r = await $(n);
|
|
560
|
+
return Z({
|
|
561
|
+
command: "all",
|
|
562
|
+
apiMode: n.apiMode,
|
|
563
|
+
model: n.options.model,
|
|
564
|
+
prompt: n.prompt,
|
|
565
|
+
result: r,
|
|
566
|
+
verbose: n.options.verbose,
|
|
567
|
+
requestApi: n.requestApi,
|
|
568
|
+
baseUrl: n.runtimeConfig.baseUrl,
|
|
569
|
+
startedAt: n.startedAt
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
//#endregion
|
|
573
|
+
export { D as _, pe as a, Q as c, _ as d, T as f, C as g, ne as h, J as i, ie as l, re as m, he as n, ve as o, x as p, Z as r, $ as s, q as t, ae as u };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ApiMode, GrokSearchConfig, ProviderKind } from './types';
|
|
2
|
+
interface RuntimeConfig {
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
model: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
compatModeRaw?: boolean | string;
|
|
7
|
+
}
|
|
8
|
+
interface RuntimeConfigSources {
|
|
9
|
+
apiKey: "env" | "config" | "default" | "missing";
|
|
10
|
+
model: "env" | "config" | "default";
|
|
11
|
+
baseUrl: "env" | "config" | "default";
|
|
12
|
+
compatMode: "env" | "config" | "default";
|
|
13
|
+
}
|
|
14
|
+
export declare const CONFIG_PATH: string;
|
|
15
|
+
export declare function ensureUserConfigFile(): string;
|
|
16
|
+
export declare function resolveRuntimeConfig(config?: GrokSearchConfig): RuntimeConfig;
|
|
17
|
+
export declare function getDefaultModel(): string;
|
|
18
|
+
export declare function getApiKey(): string | undefined;
|
|
19
|
+
export declare function getBaseUrl(): string | undefined;
|
|
20
|
+
export declare function getConfigDoctorSnapshot(): {
|
|
21
|
+
configPath: string;
|
|
22
|
+
apiKeyPresent: boolean;
|
|
23
|
+
model: string;
|
|
24
|
+
baseUrl: string | undefined;
|
|
25
|
+
providerKind: ProviderKind;
|
|
26
|
+
apiMode: ApiMode;
|
|
27
|
+
sources: RuntimeConfigSources;
|
|
28
|
+
};
|
|
29
|
+
export declare function isOpenRouterBaseUrl(baseUrl: string | undefined): boolean;
|
|
30
|
+
export declare function getProviderKind(baseUrl: string | undefined): ProviderKind;
|
|
31
|
+
export declare function isCompatModeEnabled(config?: GrokSearchConfig): boolean;
|
|
32
|
+
export declare function getApiMode(config?: GrokSearchConfig): ApiMode;
|
|
33
|
+
export declare function getRequestApiLabel(apiMode: ApiMode, baseUrl?: string | undefined): "OpenRouter Responses API Beta" | "xAI Responses API" | "OpenAI-compatible /chat/completions";
|
|
34
|
+
export declare function printGatewayError(providerKind: ProviderKind, apiMode: ApiMode): void;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CompletedResult, OpenRouterResponsesBody, SearchOptions, StreamResult } from './types';
|
|
2
|
+
export declare function buildOpenRouterResponsesBody(prompt: string, options: SearchOptions, stream: boolean): Record<string, unknown>;
|
|
3
|
+
export declare function buildOpenRouterRequestTransform(options: SearchOptions): (body: Record<string, unknown>) => {
|
|
4
|
+
tools: ({
|
|
5
|
+
type: string;
|
|
6
|
+
parameters: Record<string, unknown>;
|
|
7
|
+
} | {
|
|
8
|
+
type: string;
|
|
9
|
+
parameters?: undefined;
|
|
10
|
+
})[];
|
|
11
|
+
};
|
|
12
|
+
type OpenRouterStreamEvent = {
|
|
13
|
+
type: "ignore";
|
|
14
|
+
} | {
|
|
15
|
+
type: "done";
|
|
16
|
+
} | {
|
|
17
|
+
type: "delta";
|
|
18
|
+
text: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: "completed";
|
|
21
|
+
response: OpenRouterResponsesBody;
|
|
22
|
+
};
|
|
23
|
+
export declare function parseOpenRouterSseLine(line: string): OpenRouterStreamEvent;
|
|
24
|
+
export declare function fetchOpenRouterResponses(params: {
|
|
25
|
+
prompt: string;
|
|
26
|
+
options: SearchOptions;
|
|
27
|
+
baseUrl: string;
|
|
28
|
+
apiKey: string;
|
|
29
|
+
abortSignal: AbortSignal;
|
|
30
|
+
}): Promise<CompletedResult>;
|
|
31
|
+
export declare function streamOpenRouterResponses(params: {
|
|
32
|
+
prompt: string;
|
|
33
|
+
options: SearchOptions;
|
|
34
|
+
baseUrl: string;
|
|
35
|
+
apiKey: string;
|
|
36
|
+
abortSignal: AbortSignal;
|
|
37
|
+
}): Promise<StreamResult>;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SearchResultPayload, StreamResult, VerbosePayload } from './types';
|
|
2
|
+
export declare function buildVerbosePayload({ model, finishReason, requestApi, baseUrl, durationMs, firstTokenLatencyMs, usage, }: {
|
|
3
|
+
model: string;
|
|
4
|
+
finishReason: string;
|
|
5
|
+
requestApi: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
durationMs: number;
|
|
8
|
+
firstTokenLatencyMs?: number;
|
|
9
|
+
usage: unknown;
|
|
10
|
+
}): VerbosePayload;
|
|
11
|
+
export declare function printPretty(payload: SearchResultPayload): void;
|
|
12
|
+
export declare function streamPretty(params: {
|
|
13
|
+
stream: StreamResult;
|
|
14
|
+
payload: Omit<SearchResultPayload, "text" | "finishReason" | "usage" | "sources" | "verbose">;
|
|
15
|
+
includeVerbose: boolean;
|
|
16
|
+
requestApi: string;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
startedAt: number;
|
|
19
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ToolSet } from 'ai';
|
|
2
|
+
import { SearchOptions } from './types';
|
|
3
|
+
interface ProviderRuntimeConfig {
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function buildTools(options: SearchOptions): ToolSet;
|
|
8
|
+
export declare function getResponsesProvider(runtimeConfig: ProviderRuntimeConfig): import('@ai-sdk/xai').XaiProvider;
|
|
9
|
+
export declare function getCompletionProvider(runtimeConfig: ProviderRuntimeConfig, options: SearchOptions): import('@ai-sdk/openai-compatible').OpenAICompatibleProvider<string, string, string, string>;
|
|
10
|
+
export declare function hasToolSpecificOptions(options: SearchOptions): boolean;
|
|
11
|
+
export declare function hasOpenRouterUnsupportedSearchOptions(options: SearchOptions): boolean;
|
|
12
|
+
export {};
|