kimiflare 0.96.1 → 0.97.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 CHANGED
@@ -17,7 +17,10 @@
17
17
  </p>
18
18
 
19
19
  <p align="center">
20
- <img src="docs/screenshot.png" alt="kimiflare TUI" width="900">
20
+ <img src="docs/demos/onboarding.gif" alt="kimiflare TUI demo" width="900">
21
+ </p>
22
+ <p align="center">
23
+ <a href="https://kimiflare.com">Watch full demos →</a>
21
24
  </p>
22
25
 
23
26
  ## How it works
package/dist/index.js CHANGED
@@ -85,12 +85,14 @@ function readProviderKeysEnv() {
85
85
  const anthropic = process.env.ANTHROPIC_API_KEY || process.env.KIMIFLARE_ANTHROPIC_KEY;
86
86
  const openai = process.env.OPENAI_API_KEY || process.env.KIMIFLARE_OPENAI_KEY;
87
87
  const google = process.env.GOOGLE_API_KEY || process.env.KIMIFLARE_GOOGLE_KEY;
88
+ const moonshotai = process.env.MOONSHOT_API_KEY || process.env.KIMIFLARE_MOONSHOT_KEY;
88
89
  const generic = process.env.KIMIFLARE_OPENAI_COMPAT_KEY;
89
- if (!anthropic && !openai && !google && !generic) return void 0;
90
+ if (!anthropic && !openai && !google && !moonshotai && !generic) return void 0;
90
91
  const out = {};
91
92
  if (anthropic) out.anthropic = anthropic;
92
93
  if (openai) out.openai = openai;
93
94
  if (google) out.google = google;
95
+ if (moonshotai) out.moonshotai = moonshotai;
94
96
  if (generic) out["openai-compatible"] = generic;
95
97
  return out;
96
98
  }
@@ -395,7 +397,7 @@ var init_config = __esm({
395
397
  "use strict";
396
398
  EFFORTS = ["low", "medium", "high"];
397
399
  DEFAULT_MODEL = "@cf/moonshotai/kimi-k2.6";
398
- DEFAULT_CLOUD_MODEL = "@cf/moonshotai/kimi-k2.7-code";
400
+ DEFAULT_CLOUD_MODEL = "moonshotai/kimi-k3";
399
401
  DEFAULT_REASONING_EFFORT = "medium";
400
402
  }
401
403
  });
@@ -2039,6 +2041,7 @@ function inferProvider(id) {
2039
2041
  if (id.startsWith("anthropic/")) return "anthropic";
2040
2042
  if (id.startsWith("openai/")) return "openai";
2041
2043
  if (id.startsWith("google-ai-studio/") || id.startsWith("google/")) return "google";
2044
+ if (id.startsWith("moonshotai/")) return "moonshotai";
2042
2045
  return "openai-compatible";
2043
2046
  }
2044
2047
  function listModels() {
@@ -2068,6 +2071,19 @@ var init_registry = __esm({
2068
2071
  supports: { tools: true, reasoning: true, streaming: true, vision: true },
2069
2072
  billingMode: "unified"
2070
2073
  },
2074
+ // ── Kimi K3 (AI Gateway / Moonshot AI, provider-native routing) ──────────
2075
+ {
2076
+ id: "moonshotai/kimi-k3",
2077
+ provider: "moonshotai",
2078
+ contextWindow: 1e6,
2079
+ maxOutputTokens: 32768,
2080
+ // Placeholder pricing — verify against Cloudflare AI Gateway docs once rendered.
2081
+ pricing: { inputPerMtok: 3, outputPerMtok: 15 },
2082
+ supports: { tools: true, reasoning: true, streaming: true, vision: true },
2083
+ // Cloudflare Unified Billing does not currently cover Moonshot AI.
2084
+ // Use a Moonshot API key (BYOK) via cf-aig-authorization.
2085
+ billingMode: "byok"
2086
+ },
2071
2087
  {
2072
2088
  id: "@cf/moonshotai/kimi-k2.6",
2073
2089
  provider: "workers-ai",
@@ -2387,7 +2403,7 @@ function buildKimiRequestTarget(opts2) {
2387
2403
  }
2388
2404
  const headers = gatewayHeadersFor(opts2);
2389
2405
  if (entry.provider !== "workers-ai") {
2390
- const useUnified = !!opts2.unifiedBilling;
2406
+ const useUnified = !!opts2.unifiedBilling && isUnifiedEligible(entry);
2391
2407
  const alias = opts2.providerKeyAliases?.[entry.provider];
2392
2408
  const providerKey = opts2.providerKeys?.[entry.provider];
2393
2409
  if (useUnified) {
@@ -2583,6 +2599,7 @@ var init_client = __esm({
2583
2599
  anthropic: { name: "Anthropic", where: "https://console.anthropic.com/settings/keys" },
2584
2600
  openai: { name: "OpenAI", where: "https://platform.openai.com/api-keys" },
2585
2601
  google: { name: "Google AI Studio", where: "https://aistudio.google.com/app/apikey" },
2602
+ moonshotai: { name: "Moonshot AI", where: "https://platform.moonshot.cn/" },
2586
2603
  "openai-compatible": { name: "your provider", where: "your provider's dashboard" }
2587
2604
  };
2588
2605
  DEFAULT_IDLE_TIMEOUT_MS = 6e4;
@@ -19467,12 +19484,12 @@ function buildRowsFlat(opts2) {
19467
19484
  }
19468
19485
  return rows;
19469
19486
  }
19470
- function ModelPicker({ current, onPick }) {
19487
+ function ModelPicker({ current, onPick, models }) {
19471
19488
  const theme = useTheme();
19472
19489
  const [query, setQuery] = useState11("");
19473
19490
  const [page, setPage] = useState11(0);
19474
19491
  const [selectedIndex, setSelectedIndex] = useState11(0);
19475
- const allModels = useMemo2(() => listModels(), []);
19492
+ const allModels = useMemo2(() => models ?? listModels(), [models]);
19476
19493
  const filtered = useMemo2(() => {
19477
19494
  if (!query.trim()) return allModels;
19478
19495
  return fuzzyFilter(allModels, query, (m) => `${m.id} ${m.provider}`);
@@ -19608,6 +19625,7 @@ var init_model_picker = __esm({
19608
19625
  init_fuzzy();
19609
19626
  PROVIDER_ORDER = [
19610
19627
  "workers-ai",
19628
+ "moonshotai",
19611
19629
  "anthropic",
19612
19630
  "openai",
19613
19631
  "google",
@@ -19615,6 +19633,7 @@ var init_model_picker = __esm({
19615
19633
  ];
19616
19634
  PROVIDER_LABEL = {
19617
19635
  "workers-ai": "Cloudflare Workers AI",
19636
+ moonshotai: "Moonshot AI",
19618
19637
  anthropic: "Anthropic",
19619
19638
  openai: "OpenAI",
19620
19639
  google: "Google",
@@ -19671,6 +19690,7 @@ var init_billing_chooser = __esm({
19671
19690
  init_theme_context();
19672
19691
  PROVIDER_NAME = {
19673
19692
  "workers-ai": "Cloudflare Workers AI",
19693
+ moonshotai: "Moonshot AI",
19674
19694
  anthropic: "Anthropic",
19675
19695
  openai: "OpenAI",
19676
19696
  google: "Google AI Studio",
@@ -19992,7 +20012,7 @@ function UnifiedBillingStatus({
19992
20012
  /* @__PURE__ */ jsx19(Text18, { bold: true, children: `"I've enabled it \u2014 try again"` }),
19993
20013
  "."
19994
20014
  ] }),
19995
- /* @__PURE__ */ jsx19(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text18, { color: theme.muted?.color ?? theme.info.color, dimColor: true, children: "Credits are one account-wide pool. Confirmed providers: OpenAI & Anthropic. Others (Google, Groq, xAI) may not be supported yet \u2014 the retry will tell you." }) }),
20015
+ /* @__PURE__ */ jsx19(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text18, { color: theme.muted?.color ?? theme.info.color, dimColor: true, children: "Credits are one account-wide pool. Confirmed providers: OpenAI & Anthropic. Others (Google, Groq, xAI, Moonshot AI) may not be supported yet \u2014 the retry will tell you." }) }),
19996
20016
  /* @__PURE__ */ jsx19(Box18, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx19(Text18, { color: theme.muted?.color ?? theme.info.color, dimColor: true, children: 'Hint: if you already have credits, your gateway probably has Authentication turned off. CF needs it ON for Unified Billing to activate. Picking "Enable Authentication" above flips it for you.' }) }),
19997
20017
  phase.eventId ? /* @__PURE__ */ jsxs17(Box18, { marginTop: 1, flexDirection: "column", children: [
19998
20018
  /* @__PURE__ */ jsxs17(Text18, { color: theme.muted?.color ?? theme.info.color, dimColor: true, children: [
@@ -20081,6 +20101,7 @@ var init_unified_billing_status = __esm({
20081
20101
  init_ai_gateway_api();
20082
20102
  PROVIDER_NAME2 = {
20083
20103
  "workers-ai": "Cloudflare Workers AI",
20104
+ moonshotai: "Moonshot AI",
20084
20105
  anthropic: "Anthropic",
20085
20106
  openai: "OpenAI",
20086
20107
  google: "Google AI Studio",
@@ -20391,6 +20412,11 @@ var init_key_entry_modal = __esm({
20391
20412
  url: "https://dash.cloudflare.com/profile/api-tokens",
20392
20413
  hint: "Use a token with the Workers AI permission."
20393
20414
  },
20415
+ moonshotai: {
20416
+ name: "Moonshot AI",
20417
+ url: "https://platform.moonshot.cn/",
20418
+ hint: "Create a key in the Moonshot console. Starts with `sk-`."
20419
+ },
20394
20420
  anthropic: {
20395
20421
  name: "Anthropic",
20396
20422
  url: "https://console.anthropic.com/settings/keys",
@@ -20885,7 +20911,8 @@ function Onboarding({ onDone, onCancel }) {
20885
20911
  setCloudMode(true);
20886
20912
  setAccountId("");
20887
20913
  setApiToken("");
20888
- setStep("confirm");
20914
+ setModel(DEFAULT_CLOUD_MODEL);
20915
+ setStep("cloudModel");
20889
20916
  }).catch((err) => {
20890
20917
  setCloudAuthError(err instanceof Error ? err.message : String(err));
20891
20918
  });
@@ -20898,6 +20925,10 @@ function Onboarding({ onDone, onCancel }) {
20898
20925
  }
20899
20926
  setModel(picked.id);
20900
20927
  setPickedEntry(picked);
20928
+ if (cloudMode) {
20929
+ setStep("confirm");
20930
+ return;
20931
+ }
20901
20932
  if (picked.provider === "workers-ai") {
20902
20933
  setStep("confirm");
20903
20934
  } else if (isUnifiedEligible(picked)) {
@@ -20961,6 +20992,13 @@ function Onboarding({ onDone, onCancel }) {
20961
20992
  setSavedPath(`error: ${e.message}`);
20962
20993
  }
20963
20994
  };
20995
+ const CLOUD_MODEL_IDS = [
20996
+ "moonshotai/kimi-k3",
20997
+ "@cf/moonshotai/kimi-k2.7-code",
20998
+ "@cf/moonshotai/kimi-k2.6",
20999
+ "@cf/moonshotai/kimi-k2.5"
21000
+ ];
21001
+ const cloudModels = CLOUD_MODEL_IDS.map((id) => getModel(id)).filter((m) => !!m);
20964
21002
  const visibleSteps = ["mode", "accountId", "apiToken", "routingMode", "model", "confirm"];
20965
21003
  const stepIndex = Math.max(1, visibleSteps.indexOf(step) === -1 ? 3 : visibleSteps.indexOf(step) + 1);
20966
21004
  const totalSteps = visibleSteps.length;
@@ -21141,6 +21179,16 @@ function Onboarding({ onDone, onCancel }) {
21141
21179
  ") and continues."
21142
21180
  ] }) })
21143
21181
  ] }),
21182
+ step === "cloudModel" && /* @__PURE__ */ jsxs19(Fragment, { children: [
21183
+ /* @__PURE__ */ jsx21(Text20, { children: "Pick a Kimi model for KimiFlare Cloud" }),
21184
+ /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, dimColor: true, children: "K3 runs through Cloudflare AI Gateway; K2.7/2.6/2.5 run on Workers AI." }),
21185
+ /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(ModelPicker, { current: model, onPick: handleModelPick, models: cloudModels }) }),
21186
+ /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, dimColor: true, children: [
21187
+ "Tip: Esc keeps the default (",
21188
+ DEFAULT_CLOUD_MODEL,
21189
+ ") and continues."
21190
+ ] }) })
21191
+ ] }),
21144
21192
  step === "billingChoice" && pickedEntry && /* @__PURE__ */ jsx21(Box20, { marginTop: 1, children: /* @__PURE__ */ jsx21(BillingChooser, { model: pickedEntry, onPick: handleBillingChoice }) }),
21145
21193
  step === "cloudAuth" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", marginTop: 1, children: [
21146
21194
  /* @__PURE__ */ jsx21(Text20, { bold: true, color: theme.accent, children: "Kimiflare Cloud Authentication" }),
@@ -21211,6 +21259,10 @@ function Onboarding({ onDone, onCancel }) {
21211
21259
  "AI Gateway: ",
21212
21260
  aiGatewayId
21213
21261
  ] }) : /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "Routing: Workers AI (direct)" })),
21262
+ cloudMode && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
21263
+ "Model: ",
21264
+ model
21265
+ ] }),
21214
21266
  cloudMode && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "Billing: KimiFlare Cloud (free 5M tokens, then $10/mo Pro)" }),
21215
21267
  unifiedBilling && /* @__PURE__ */ jsx21(Text20, { color: theme.info.color, children: "Billing: Cloudflare credits (Unified Billing)" }),
21216
21268
  Object.keys(providerKeyAliases).length > 0 && /* @__PURE__ */ jsxs19(Text20, { color: theme.info.color, children: [
@@ -35538,7 +35590,7 @@ function isCloudModeConfigured() {
35538
35590
  }
35539
35591
  }
35540
35592
  var helpDefaultModel = isCloudModeConfigured() ? DEFAULT_CLOUD_MODEL : DEFAULT_MODEL;
35541
- var helpModelName = helpDefaultModel === DEFAULT_CLOUD_MODEL ? "Kimi-K2.7" : "Kimi-K2.6";
35593
+ var helpModelName = helpDefaultModel === DEFAULT_CLOUD_MODEL ? "Kimi-K3" : "Kimi-K2.6";
35542
35594
  var program = new Command2();
35543
35595
  program.name("kimiflare").description(`Terminal coding agent powered by ${helpModelName} on Cloudflare Workers AI.`).version(getAppVersion()).option("-p, --print <prompt>", "one-shot mode: send prompt, stream reply to stdout, exit").option("-m, --model <id>", `model id (defaults to ${helpDefaultModel})`).option("--cloud", "use Kimiflare Cloud (api.kimiflare.com) instead of direct Workers AI").option("--dangerously-allow-all", "auto-approve every permission prompt (print mode only)").option("--reasoning", "include reasoning in stdout (print mode only)").option("--thinking", "alias for --reasoning").option("--continue-on-limit", "reset tool-call counter and continue when the 200-call limit is hit (print mode only)").option("--max-input-tokens <n>", "cumulative prompt token budget; exits 42 when exhausted (print mode only)", (v) => parseInt(v, 10)).option("--emit-events", "emit Camouflage NDJSON events to stdout; requires -p (for initial prompt)").option("--multi-turn", "with --emit-events: keep reading stdin for UserInputSubmitted follow-ups after the initial turn").option("--ui <name>", "render UI with React Ink (the only supported engine). This flag and KIMIFLARE_UI are currently ignored.").option("--mode <mode>", "run mode: interactive (default), print, rpc").option("-c, --continue", "continue the most recent session in the current working directory (print mode only)").option("-S, --session <id>", "resume a specific session by id (print mode only)").option("-f, --file <path>", "attach file(s) to the prompt; repeatable, supports globs (print mode only)", (v, prev) => (prev ?? []).concat(v)).option("--format <mode>", "output format for print mode: text (default), json, stream-json").option("--dir <path>", "run in the specified directory instead of the current one (print mode only)").option("--title <title>", "override the auto-generated session title (print mode only)").option("--attach <url>", "attach to a running kimiflare serve instance (print mode only)");
35544
35596
  program.command("cost").description("Show cost attribution by task type (requires costAttribution enabled)").option("-w, --week", "last 7 days (default)").option("-m, --month", "last 30 days").option("-d, --day", "today only").option("-s, --session <id>", "single session detail").option("-c, --category <name>", "filter by category").option("--json", "machine-readable output").option("--reclassify", "re-run classification on all sessions").option("--local-only", "skip Cloudflare reconciliation").action(async (cmdOpts) => {
@@ -35626,7 +35678,7 @@ Kimiflare Cloud Authentication`);
35626
35678
  await saveConfig({
35627
35679
  accountId: "",
35628
35680
  apiToken: "",
35629
- model: existing?.model ?? DEFAULT_MODEL,
35681
+ model: existing?.model ?? DEFAULT_CLOUD_MODEL,
35630
35682
  cloudMode: true
35631
35683
  });
35632
35684
  console.log("Cloud mode enabled. Run `kimiflare` to start using it.");