kimiflare 0.36.0 → 0.36.2
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/index.js +63 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -483,6 +483,9 @@ function isRetryable(err, attempt) {
|
|
|
483
483
|
return false;
|
|
484
484
|
}
|
|
485
485
|
async function* runKimi(opts2) {
|
|
486
|
+
if (opts2.cloudMode && !opts2.cloudToken) {
|
|
487
|
+
throw new KimiApiError("kimiflare: cloud mode requires a cloud token. Run `kimiflare auth cloud` to authenticate.", void 0, 401);
|
|
488
|
+
}
|
|
486
489
|
const { url, headers: gatewayHeaders } = buildKimiRequestTarget(opts2);
|
|
487
490
|
const body = {
|
|
488
491
|
messages: sanitizeMessagesForApi(opts2.messages),
|
|
@@ -556,9 +559,11 @@ function validateModelId(model) {
|
|
|
556
559
|
function buildKimiRequestTarget(opts2) {
|
|
557
560
|
validateModelId(opts2.model);
|
|
558
561
|
if (opts2.cloudMode) {
|
|
562
|
+
const headers2 = opts2.cloudToken ? { Authorization: `Bearer ${opts2.cloudToken}` } : {};
|
|
563
|
+
if (opts2.cloudDeviceId) headers2["X-Device-ID"] = opts2.cloudDeviceId;
|
|
559
564
|
return {
|
|
560
565
|
url: "https://api.kimiflare.com/v1/chat",
|
|
561
|
-
headers:
|
|
566
|
+
headers: headers2
|
|
562
567
|
};
|
|
563
568
|
}
|
|
564
569
|
if (!opts2.gateway?.id) {
|
|
@@ -1757,7 +1762,8 @@ Use console.log() to return results. Only console.log output will be sent back t
|
|
|
1757
1762
|
sessionId: opts2.sessionId,
|
|
1758
1763
|
gateway: opts2.gateway,
|
|
1759
1764
|
cloudMode: opts2.cloudMode,
|
|
1760
|
-
cloudToken: opts2.cloudToken
|
|
1765
|
+
cloudToken: opts2.cloudToken,
|
|
1766
|
+
cloudDeviceId: opts2.cloudDeviceId
|
|
1761
1767
|
});
|
|
1762
1768
|
for await (const ev of events) {
|
|
1763
1769
|
switch (ev.type) {
|
|
@@ -4661,24 +4667,30 @@ function generateCode() {
|
|
|
4661
4667
|
}
|
|
4662
4668
|
return out;
|
|
4663
4669
|
}
|
|
4670
|
+
function generateDeviceId() {
|
|
4671
|
+
const arr = new Uint8Array(16);
|
|
4672
|
+
crypto.getRandomValues(arr);
|
|
4673
|
+
return Array.from(arr, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
4674
|
+
}
|
|
4664
4675
|
function generateDeviceCodes() {
|
|
4665
4676
|
const deviceCode = `device-${generateCode()}-${Date.now()}`;
|
|
4666
4677
|
const userCode = `${generateCode()}-${generateCode()}`;
|
|
4667
4678
|
const authUrl = `${CLOUD_API_URL}/auth/github?code=${encodeURIComponent(userCode)}`;
|
|
4668
|
-
|
|
4679
|
+
const deviceId = generateDeviceId();
|
|
4680
|
+
return { deviceCode, userCode, authUrl, deviceId };
|
|
4669
4681
|
}
|
|
4670
4682
|
async function registerDevice(codes) {
|
|
4671
4683
|
const registerRes = await fetch(`${CLOUD_API_URL}/auth/device`, {
|
|
4672
4684
|
method: "POST",
|
|
4673
4685
|
headers: { "Content-Type": "application/json" },
|
|
4674
|
-
body: JSON.stringify({ device_code: codes.deviceCode, user_code: codes.userCode })
|
|
4686
|
+
body: JSON.stringify({ device_code: codes.deviceCode, user_code: codes.userCode, device_id: codes.deviceId })
|
|
4675
4687
|
});
|
|
4676
4688
|
if (!registerRes.ok) {
|
|
4677
4689
|
const err = await registerRes.json().catch(() => ({}));
|
|
4678
4690
|
throw new Error(`Failed to register device: ${err.error || registerRes.statusText}`);
|
|
4679
4691
|
}
|
|
4680
4692
|
}
|
|
4681
|
-
async function pollForToken(deviceCode) {
|
|
4693
|
+
async function pollForToken(deviceCode, deviceId) {
|
|
4682
4694
|
const pollRes = await fetch(`${CLOUD_API_URL}/auth/poll`, {
|
|
4683
4695
|
method: "POST",
|
|
4684
4696
|
headers: { "Content-Type": "application/json" },
|
|
@@ -4689,26 +4701,36 @@ async function pollForToken(deviceCode) {
|
|
|
4689
4701
|
if (pollData.status === "approved" && pollData.access_token) {
|
|
4690
4702
|
const creds = {
|
|
4691
4703
|
accessToken: pollData.access_token,
|
|
4692
|
-
expiresAt: Math.floor(Date.now() / 1e3) + 7 * 24 * 60 * 60
|
|
4704
|
+
expiresAt: Math.floor(Date.now() / 1e3) + 7 * 24 * 60 * 60,
|
|
4693
4705
|
// 7 days
|
|
4706
|
+
deviceId
|
|
4694
4707
|
};
|
|
4695
4708
|
await saveCloudCredentials(creds);
|
|
4696
4709
|
return creds;
|
|
4697
4710
|
}
|
|
4698
4711
|
return null;
|
|
4699
4712
|
}
|
|
4700
|
-
async function fetchCloudUsage(token) {
|
|
4701
|
-
const
|
|
4702
|
-
|
|
4703
|
-
});
|
|
4713
|
+
async function fetchCloudUsage(token, deviceId) {
|
|
4714
|
+
const headers = { Authorization: `Bearer ${token}` };
|
|
4715
|
+
if (deviceId) headers["X-Device-ID"] = deviceId;
|
|
4716
|
+
const res = await fetch(`${CLOUD_API_URL}/v1/usage`, { headers });
|
|
4704
4717
|
if (!res.ok) return null;
|
|
4705
|
-
|
|
4718
|
+
const data = await res.json();
|
|
4719
|
+
if (typeof data.remaining !== "number" || typeof data.input_token_limit !== "number" || typeof data.input_tokens_used !== "number" || typeof data.expires_at !== "string") {
|
|
4720
|
+
return null;
|
|
4721
|
+
}
|
|
4722
|
+
return {
|
|
4723
|
+
input_token_limit: data.input_token_limit,
|
|
4724
|
+
input_tokens_used: data.input_tokens_used,
|
|
4725
|
+
remaining: data.remaining,
|
|
4726
|
+
expires_at: data.expires_at
|
|
4727
|
+
};
|
|
4706
4728
|
}
|
|
4707
4729
|
async function loadCloudCredentials() {
|
|
4708
4730
|
try {
|
|
4709
4731
|
const raw = await readFile11(cloudCredPath(), "utf8");
|
|
4710
4732
|
const parsed = JSON.parse(raw);
|
|
4711
|
-
if (parsed.expiresAt && parsed.expiresAt > Date.now() / 1e3) {
|
|
4733
|
+
if (parsed.expiresAt && parsed.expiresAt > Date.now() / 1e3 && parsed.accessToken) {
|
|
4712
4734
|
return parsed;
|
|
4713
4735
|
}
|
|
4714
4736
|
} catch {
|
|
@@ -4734,7 +4756,7 @@ async function authenticateDevice(onStatus) {
|
|
|
4734
4756
|
while (Date.now() - startTime < POLL_TIMEOUT_MS) {
|
|
4735
4757
|
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
4736
4758
|
onStatus({ url: codes.authUrl, userCode: codes.userCode, polling: true });
|
|
4737
|
-
const creds = await pollForToken(codes.deviceCode);
|
|
4759
|
+
const creds = await pollForToken(codes.deviceCode, codes.deviceId);
|
|
4738
4760
|
if (creds) return creds;
|
|
4739
4761
|
}
|
|
4740
4762
|
throw new Error("Authentication timed out. Please try again.");
|
|
@@ -7966,9 +7988,9 @@ function Onboarding({ onDone, onCancel }) {
|
|
|
7966
7988
|
return;
|
|
7967
7989
|
}
|
|
7968
7990
|
try {
|
|
7969
|
-
const creds = await pollForToken(cloudAuth.codes.deviceCode);
|
|
7991
|
+
const creds = await pollForToken(cloudAuth.codes.deviceCode, cloudAuth.codes.deviceId);
|
|
7970
7992
|
if (creds && !cancelled) {
|
|
7971
|
-
const usage = await fetchCloudUsage(creds.accessToken);
|
|
7993
|
+
const usage = await fetchCloudUsage(creds.accessToken, creds.deviceId);
|
|
7972
7994
|
if (usage && !cancelled) {
|
|
7973
7995
|
setCloudAuth({
|
|
7974
7996
|
phase: "success",
|
|
@@ -12971,12 +12993,15 @@ function App({
|
|
|
12971
12993
|
initialUpdateResult,
|
|
12972
12994
|
initialLspScope,
|
|
12973
12995
|
initialLspProjectPath,
|
|
12974
|
-
initialCloudToken
|
|
12996
|
+
initialCloudToken,
|
|
12997
|
+
initialCloudDeviceId
|
|
12975
12998
|
}) {
|
|
12976
12999
|
const { exit } = useApp();
|
|
12977
13000
|
const [cfg, setCfg] = useState10(initialCfg);
|
|
12978
13001
|
const [lspScope, setLspScope] = useState10(initialLspScope);
|
|
12979
13002
|
const [lspProjectPath, setLspProjectPath] = useState10(initialLspProjectPath);
|
|
13003
|
+
const [cloudToken, setCloudToken] = useState10(initialCloudToken);
|
|
13004
|
+
const [cloudDeviceId, setCloudDeviceId] = useState10(initialCloudDeviceId);
|
|
12980
13005
|
const [events, setRawEvents] = useState10([]);
|
|
12981
13006
|
const setEvents = useCallback2(
|
|
12982
13007
|
(updater) => {
|
|
@@ -13030,7 +13055,7 @@ function App({
|
|
|
13030
13055
|
let cancelled = false;
|
|
13031
13056
|
const fetchBudget = async () => {
|
|
13032
13057
|
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
13033
|
-
const usage2 = await fetchCloudUsage2(initialCloudToken);
|
|
13058
|
+
const usage2 = await fetchCloudUsage2(initialCloudToken, cloudDeviceId ?? initialCloudDeviceId);
|
|
13034
13059
|
if (usage2 && !cancelled) {
|
|
13035
13060
|
setCloudBudget({ remaining: usage2.remaining, limit: usage2.input_token_limit });
|
|
13036
13061
|
}
|
|
@@ -13953,7 +13978,8 @@ function App({
|
|
|
13953
13978
|
memoryManager: memoryManagerRef.current,
|
|
13954
13979
|
codeMode: effectiveCodeMode,
|
|
13955
13980
|
cloudMode: cfg.cloudMode,
|
|
13956
|
-
cloudToken: initialCloudToken,
|
|
13981
|
+
cloudToken: cloudToken ?? initialCloudToken,
|
|
13982
|
+
cloudDeviceId: cloudDeviceId ?? initialCloudDeviceId,
|
|
13957
13983
|
onIterationEnd,
|
|
13958
13984
|
onFileChange: (path, content) => {
|
|
13959
13985
|
if (content) {
|
|
@@ -15163,7 +15189,8 @@ ${lines.join("\n")}` }]);
|
|
|
15163
15189
|
keepLastImageTurns: cfg.imageHistoryTurns ?? 2,
|
|
15164
15190
|
codeMode: effectiveCodeMode,
|
|
15165
15191
|
cloudMode: cfg.cloudMode,
|
|
15166
|
-
cloudToken: initialCloudToken,
|
|
15192
|
+
cloudToken: cloudToken ?? initialCloudToken,
|
|
15193
|
+
cloudDeviceId: cloudDeviceId ?? initialCloudDeviceId,
|
|
15167
15194
|
onIterationEnd,
|
|
15168
15195
|
intentClassification: classification,
|
|
15169
15196
|
onFileChange: (path, content2) => {
|
|
@@ -15362,6 +15389,7 @@ ${lines.join("\n")}` }]);
|
|
|
15362
15389
|
const { loadCloudCredentials: loadCloudCredentials2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15363
15390
|
const creds = await loadCloudCredentials2();
|
|
15364
15391
|
if (creds) {
|
|
15392
|
+
setCloudToken(creds.accessToken);
|
|
15365
15393
|
setEvents((e) => [
|
|
15366
15394
|
...e,
|
|
15367
15395
|
{ kind: "info", key: mkKey(), text: "configuration saved \u2014 welcome to kimiflare! (cloud mode)" }
|
|
@@ -15664,7 +15692,7 @@ ${lines.join("\n")}` }]);
|
|
|
15664
15692
|
] })
|
|
15665
15693
|
] }) });
|
|
15666
15694
|
}
|
|
15667
|
-
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken) {
|
|
15695
|
+
async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath = null, cloudToken, cloudDeviceId) {
|
|
15668
15696
|
const instance = render(
|
|
15669
15697
|
/* @__PURE__ */ jsx23(
|
|
15670
15698
|
App,
|
|
@@ -15673,7 +15701,8 @@ async function renderApp(cfg, updateResult, lspScope = "global", lspProjectPath
|
|
|
15673
15701
|
initialUpdateResult: updateResult,
|
|
15674
15702
|
initialLspScope: lspScope,
|
|
15675
15703
|
initialLspProjectPath: lspProjectPath,
|
|
15676
|
-
initialCloudToken: cloudToken
|
|
15704
|
+
initialCloudToken: cloudToken,
|
|
15705
|
+
initialCloudDeviceId: cloudDeviceId
|
|
15677
15706
|
}
|
|
15678
15707
|
),
|
|
15679
15708
|
{
|
|
@@ -15886,14 +15915,12 @@ program.command("usage").description("Show Kimiflare Cloud token usage (requires
|
|
|
15886
15915
|
console.error("Not authenticated with Kimiflare Cloud. Run: kimiflare auth cloud");
|
|
15887
15916
|
process.exit(1);
|
|
15888
15917
|
}
|
|
15889
|
-
const
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
15893
|
-
console.error(`Failed to fetch usage: ${res.status} ${res.statusText}`);
|
|
15918
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15919
|
+
const usage = await fetchCloudUsage2(creds.accessToken, creds.deviceId);
|
|
15920
|
+
if (!usage) {
|
|
15921
|
+
console.error("Failed to fetch usage: invalid response from server");
|
|
15894
15922
|
process.exit(1);
|
|
15895
15923
|
}
|
|
15896
|
-
const usage = await res.json();
|
|
15897
15924
|
console.log(`Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
|
|
15898
15925
|
console.log(`Used: ${usage.input_tokens_used.toLocaleString()}`);
|
|
15899
15926
|
console.log(`Grant expires: ${usage.expires_at}`);
|
|
@@ -15931,11 +15958,9 @@ Kimiflare Cloud Authentication`);
|
|
|
15931
15958
|
}
|
|
15932
15959
|
});
|
|
15933
15960
|
console.log(`Authenticated! Token expires at ${new Date(creds.expiresAt * 1e3).toISOString()}`);
|
|
15934
|
-
const
|
|
15935
|
-
|
|
15936
|
-
|
|
15937
|
-
if (usageRes.ok) {
|
|
15938
|
-
const usage = await usageRes.json();
|
|
15961
|
+
const { fetchCloudUsage: fetchCloudUsage2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15962
|
+
const usage = await fetchCloudUsage2(creds.accessToken, creds.deviceId);
|
|
15963
|
+
if (usage) {
|
|
15939
15964
|
console.log(`
|
|
15940
15965
|
Token budget: ${usage.remaining.toLocaleString()} / ${usage.input_token_limit.toLocaleString()} remaining`);
|
|
15941
15966
|
console.log(`Grant expires: ${usage.expires_at}`);
|
|
@@ -15969,6 +15994,7 @@ async function main() {
|
|
|
15969
15994
|
}
|
|
15970
15995
|
const cloudMode = opts.cloud ?? cfg?.cloudMode ?? false;
|
|
15971
15996
|
let cloudToken;
|
|
15997
|
+
let cloudDeviceId;
|
|
15972
15998
|
if (cloudMode) {
|
|
15973
15999
|
const { loadCloudCredentials: loadCloudCredentials2, authenticateDevice: authenticateDevice2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
15974
16000
|
let cloudCreds = await loadCloudCredentials2();
|
|
@@ -15977,6 +16003,7 @@ async function main() {
|
|
|
15977
16003
|
process.exit(2);
|
|
15978
16004
|
}
|
|
15979
16005
|
cloudToken = cloudCreds.accessToken;
|
|
16006
|
+
cloudDeviceId = cloudCreds.deviceId;
|
|
15980
16007
|
cfg = {
|
|
15981
16008
|
...cfg ?? { accountId: "", apiToken: "", model: DEFAULT_MODEL },
|
|
15982
16009
|
cloudMode: true
|
|
@@ -15998,6 +16025,7 @@ async function main() {
|
|
|
15998
16025
|
showReasoning: !!opts.reasoning,
|
|
15999
16026
|
codeMode: cfg.codeMode,
|
|
16000
16027
|
cloudToken,
|
|
16028
|
+
cloudDeviceId,
|
|
16001
16029
|
continueOnLimit: !!opts.continueOnLimit,
|
|
16002
16030
|
maxInputTokens: opts.maxInputTokens,
|
|
16003
16031
|
updateResult
|
|
@@ -16013,9 +16041,9 @@ async function main() {
|
|
|
16013
16041
|
const { renderApp: renderApp2 } = await Promise.resolve().then(() => (init_app(), app_exports));
|
|
16014
16042
|
if (cfg) {
|
|
16015
16043
|
const model = opts.model ?? cfg.model ?? DEFAULT_MODEL;
|
|
16016
|
-
await renderApp2({ ...cfg, model }, updateResult, lspScope, lspProjectPath, cloudToken);
|
|
16044
|
+
await renderApp2({ ...cfg, model }, updateResult, lspScope, lspProjectPath, cloudToken, cloudDeviceId);
|
|
16017
16045
|
} else {
|
|
16018
|
-
await renderApp2(null, updateResult, lspScope, lspProjectPath, cloudToken);
|
|
16046
|
+
await renderApp2(null, updateResult, lspScope, lspProjectPath, cloudToken, cloudDeviceId);
|
|
16019
16047
|
}
|
|
16020
16048
|
}
|
|
16021
16049
|
function gatewayFromPrintOpts(opts2) {
|
|
@@ -16067,6 +16095,7 @@ async function runPrintMode(opts2) {
|
|
|
16067
16095
|
maxInputTokens: opts2.maxInputTokens,
|
|
16068
16096
|
cloudMode: opts2.cloudMode,
|
|
16069
16097
|
cloudToken: opts2.cloudToken,
|
|
16098
|
+
cloudDeviceId: opts2.cloudDeviceId,
|
|
16070
16099
|
coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "kimiflare@proton.me" } : void 0,
|
|
16071
16100
|
callbacks: {
|
|
16072
16101
|
onReasoningDelta: opts2.showReasoning ? (delta) => {
|