From 5e635c96564af35e9c834aef8177e266d851262f Mon Sep 17 00:00:00 2001 From: Manik Vahsith <49544491+manikv12@users.noreply.github.com> Date: Fri, 30 Jan 2026 00:17:42 -0600 Subject: [PATCH 1/5] feat: add Kimi K2.5 model to synthetic catalog (#4407) * feat: add Kimi K2.5 model to synthetic catalog Add hf:moonshotai/Kimi-K2.5 to the synthetic model catalog. This model is available via dev.synthetic.new API. - 256k context window - 8192 max tokens - Supports reasoning * chore: fix formatting in onboard-helpers.ts * fix: update config candidate ordering test (#4407) (thanks @manikv12) --------- Co-authored-by: Peter Steinberger --- CHANGELOG.md | 1 + src/agents/synthetic-models.ts | 8 ++++++++ src/commands/onboard-helpers.ts | 12 ++++++------ src/config/paths.test.ts | 8 ++++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d09635740..10bcda92f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ Status: stable. - Routing: precompile session key regexes. (#1697) Thanks @Ray0907. - CLI: use Node's module compile cache for faster startup. (#2808) Thanks @pi0. - Auth: show copyable Google auth URL after ASCII prompt. (#1787) Thanks @robbyczgw-cla. +- Agents: add Kimi K2.5 to the synthetic model catalog. (#4407) Thanks @manikv12. - TUI: avoid width overflow when rendering selection lists. (#1686) Thanks @mossein. - macOS: finish OpenClaw app rename for macOS sources, bundle identifiers, and shared kit paths. (#2844) Thanks @fal3. - Branding: update launchd labels, mobile bundle IDs, and logging subsystems to bot.molt (legacy com.clawdbot migrations). Thanks @thewilloftheshadow. diff --git a/src/agents/synthetic-models.ts b/src/agents/synthetic-models.ts index e31f3c795..9b9247805 100644 --- a/src/agents/synthetic-models.ts +++ b/src/agents/synthetic-models.ts @@ -99,6 +99,14 @@ export const SYNTHETIC_MODEL_CATALOG = [ contextWindow: 256000, maxTokens: 8192, }, + { + id: "hf:moonshotai/Kimi-K2.5", + name: "Kimi K2.5", + reasoning: true, + input: ["text"], + contextWindow: 256000, + maxTokens: 8192, + }, { id: "hf:openai/gpt-oss-120b", name: "GPT OSS 120B", diff --git a/src/commands/onboard-helpers.ts b/src/commands/onboard-helpers.ts index f56da78e9..774893213 100644 --- a/src/commands/onboard-helpers.ts +++ b/src/commands/onboard-helpers.ts @@ -64,12 +64,12 @@ export function randomToken(): string { export function printWizardHeader(runtime: RuntimeEnv) { const header = [ - "▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄", - "██░▄▄▄░██░▄▄░██░▄▄▄██░▀██░██░▄▄▀██░████░▄▄▀██░███░██", - "██░███░██░▀▀░██░▄▄▄██░█░█░██░█████░████░▀▀░██░█░█░██", - "██░▀▀▀░██░█████░▀▀▀██░██▄░██░▀▀▄██░▀▀░█░██░██▄▀▄▀▄██", - "▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀", - " 🦞 OPENCLAW 🦞 ", + "▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄", + "██░▄▄▄░██░▄▄░██░▄▄▄██░▀██░██░▄▄▀██░████░▄▄▀██░███░██", + "██░███░██░▀▀░██░▄▄▄██░█░█░██░█████░████░▀▀░██░█░█░██", + "██░▀▀▀░██░█████░▀▀▀██░██▄░██░▀▀▄██░▀▀░█░██░██▄▀▄▀▄██", + "▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀", + " 🦞 OPENCLAW 🦞 ", " ", ].join("\n"); runtime.log(header); diff --git a/src/config/paths.test.ts b/src/config/paths.test.ts index 06cd26444..f25e5b000 100644 --- a/src/config/paths.test.ts +++ b/src/config/paths.test.ts @@ -48,8 +48,12 @@ describe("state + config path candidates", () => { it("orders default config candidates in a stable order", () => { const home = "/home/test"; const candidates = resolveDefaultConfigCandidates({} as NodeJS.ProcessEnv, () => home); - expect(candidates[0]).toBe(path.join(home, ".openclaw", "openclaw.json")); - expect(candidates).toHaveLength(1); + const expectedDirs = [".openclaw", ".clawdbot", ".moltbot", ".moldbot"]; + const expectedFiles = ["openclaw.json", "clawdbot.json", "moltbot.json", "moldbot.json"]; + const expected = expectedDirs.flatMap((dir) => + expectedFiles.map((file) => path.join(home, dir, file)), + ); + expect(candidates).toEqual(expected); }); it("prefers ~/.openclaw when it exists and legacy dir is missing", async () => { From 28f8d00e9f075f9fa11e8242e1acf392b78d39ac Mon Sep 17 00:00:00 2001 From: Nate Date: Thu, 29 Jan 2026 23:15:42 -0700 Subject: [PATCH 2/5] fix: update install URLs from clawd.bot to openclaw.ai --- .github/workflows/install-smoke.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index 0347c7810..d5d2ef515 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -32,8 +32,8 @@ jobs: - name: Run installer docker tests env: - CLAWDBOT_INSTALL_URL: https://clawd.bot/install.sh - CLAWDBOT_INSTALL_CLI_URL: https://clawd.bot/install-cli.sh + CLAWDBOT_INSTALL_URL: https://openclaw.ai/install.sh + CLAWDBOT_INSTALL_CLI_URL: https://openclaw.ai/install-cli.sh CLAWDBOT_NO_ONBOARD: "1" CLAWDBOT_INSTALL_SMOKE_SKIP_CLI: "1" CLAWDBOT_INSTALL_SMOKE_SKIP_NONROOT: ${{ github.event_name == 'pull_request' && '1' || '0' }} From c6ddc95fc0d514758087ca1020c04c49caeee63f Mon Sep 17 00:00:00 2001 From: robhparker Date: Thu, 29 Jan 2026 23:15:33 -0500 Subject: [PATCH 3/5] fix(telegram): scope skill commands to bound agent per bot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit registerTelegramNativeCommands() calls listSkillCommandsForAgents() without passing agentIds, causing ALL agents' skill commands to be registered on EVERY Telegram bot. When multiple agents share skill names (e.g. two agents both have a "butler" skill), the shared `used` Set in listSkillCommandsForAgents causes de-duplication suffixes (_2, _3) and all commands appear on every bot regardless of agent binding. This fix uses the existing resolveAgentRoute() (already imported) to find the bound agent for the current Telegram accountId, then passes that agentId to listSkillCommandsForAgents(). The function already accepts an optional agentIds parameter — it just wasn't wired from the Telegram registration path. Before: All agents' skill commands registered on every Telegram bot, causing /butler_2, /housekeeper_2 dedup suffixes and potential BOT_COMMANDS_TOO_MUCH errors when total exceeds 100. After: Each Telegram bot only registers skill commands for its own bound agent. No cross-agent dedup, no command limit overflow. Co-Authored-By: Claude Opus 4.5 --- src/telegram/bot-native-commands.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/telegram/bot-native-commands.ts b/src/telegram/bot-native-commands.ts index 5f37b81dc..c4b78a09a 100644 --- a/src/telegram/bot-native-commands.ts +++ b/src/telegram/bot-native-commands.ts @@ -257,8 +257,12 @@ export const registerTelegramNativeCommands = ({ shouldSkipUpdate, opts, }: RegisterTelegramNativeCommandsParams) => { + const boundRoute = resolveAgentRoute({ cfg, channel: "telegram", accountId }); + const boundAgentIds = boundRoute?.agentId ? [boundRoute.agentId] : undefined; const skillCommands = - nativeEnabled && nativeSkillsEnabled ? listSkillCommandsForAgents({ cfg }) : []; + nativeEnabled && nativeSkillsEnabled + ? listSkillCommandsForAgents({ cfg, agentIds: boundAgentIds }) + : []; const nativeCommands = nativeEnabled ? listNativeCommandSpecsForConfig(cfg, { skillCommands, provider: "telegram" }) : []; From 9025da2296c11829bf48f0f38c434d6a0ce82fa3 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 30 Jan 2026 11:57:25 +0530 Subject: [PATCH 4/5] fix: scope telegram skill commands per bot (#4360) (thanks @robhparker) --- CHANGELOG.md | 1 + src/telegram/bot-native-commands.test.ts | 82 ++++++++++++++++++++++++ src/telegram/bot-native-commands.ts | 10 ++- 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 src/telegram/bot-native-commands.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 10bcda92f..4c0549c16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ Status: stable. ### Fixes - Telegram: avoid silent empty replies by tracking normalization skips before fallback. (#3796) +- Telegram: scope native skill commands to bound agent per bot. (#4360) Thanks @robhparker. - Mentions: honor mentionPatterns even when explicit mentions are present. (#3303) Thanks @HirokiKobayashi-R. - Discord: restore username directory lookup in target resolution. (#3131) Thanks @bonald. - Agents: align MiniMax base URL test expectation with default provider config. (#3131) Thanks @bonald. diff --git a/src/telegram/bot-native-commands.test.ts b/src/telegram/bot-native-commands.test.ts new file mode 100644 index 000000000..dc6b94dcc --- /dev/null +++ b/src/telegram/bot-native-commands.test.ts @@ -0,0 +1,82 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import type { OpenClawConfig } from "../config/config.js"; +import type { TelegramAccountConfig } from "../config/types.js"; +import type { RuntimeEnv } from "../runtime.js"; +import { registerTelegramNativeCommands } from "./bot-native-commands.js"; + +const { listSkillCommandsForAgents } = vi.hoisted(() => ({ + listSkillCommandsForAgents: vi.fn(() => []), +})); + +vi.mock("../auto-reply/skill-commands.js", () => ({ + listSkillCommandsForAgents, +})); + +describe("registerTelegramNativeCommands", () => { + beforeEach(() => { + listSkillCommandsForAgents.mockReset(); + }); + + const buildParams = (cfg: OpenClawConfig, accountId = "default") => ({ + bot: { + api: { + setMyCommands: vi.fn().mockResolvedValue(undefined), + sendMessage: vi.fn().mockResolvedValue(undefined), + }, + command: vi.fn(), + } as unknown as Parameters[0]["bot"], + cfg, + runtime: {} as RuntimeEnv, + accountId, + telegramCfg: {} as TelegramAccountConfig, + allowFrom: [], + groupAllowFrom: [], + replyToMode: "off" as const, + textLimit: 4096, + useAccessGroups: false, + nativeEnabled: true, + nativeSkillsEnabled: true, + nativeDisabledExplicit: false, + resolveGroupPolicy: () => ({ allowlistEnabled: false, allowed: true }), + resolveTelegramGroupConfig: () => ({ + groupConfig: undefined, + topicConfig: undefined, + }), + shouldSkipUpdate: () => false, + opts: { token: "token" }, + }); + + it("scopes skill commands when account binding exists", () => { + const cfg: OpenClawConfig = { + agents: { + list: [{ id: "main", default: true }, { id: "butler" }], + }, + bindings: [ + { + agentId: "butler", + match: { channel: "telegram", accountId: "bot-a" }, + }, + ], + }; + + registerTelegramNativeCommands(buildParams(cfg, "bot-a")); + + expect(listSkillCommandsForAgents).toHaveBeenCalledWith({ + cfg, + agentIds: ["butler"], + }); + }); + + it("keeps skill commands unscoped without a matching binding", () => { + const cfg: OpenClawConfig = { + agents: { + list: [{ id: "main", default: true }, { id: "butler" }], + }, + }; + + registerTelegramNativeCommands(buildParams(cfg, "bot-a")); + + expect(listSkillCommandsForAgents).toHaveBeenCalledWith({ cfg }); + }); +}); diff --git a/src/telegram/bot-native-commands.ts b/src/telegram/bot-native-commands.ts index c4b78a09a..cd53459e6 100644 --- a/src/telegram/bot-native-commands.ts +++ b/src/telegram/bot-native-commands.ts @@ -257,11 +257,15 @@ export const registerTelegramNativeCommands = ({ shouldSkipUpdate, opts, }: RegisterTelegramNativeCommandsParams) => { - const boundRoute = resolveAgentRoute({ cfg, channel: "telegram", accountId }); - const boundAgentIds = boundRoute?.agentId ? [boundRoute.agentId] : undefined; + const boundRoute = + nativeEnabled && nativeSkillsEnabled + ? resolveAgentRoute({ cfg, channel: "telegram", accountId }) + : null; + const boundAgentIds = + boundRoute && boundRoute.matchedBy.startsWith("binding.") ? [boundRoute.agentId] : null; const skillCommands = nativeEnabled && nativeSkillsEnabled - ? listSkillCommandsForAgents({ cfg, agentIds: boundAgentIds }) + ? listSkillCommandsForAgents(boundAgentIds ? { cfg, agentIds: boundAgentIds } : { cfg }) : []; const nativeCommands = nativeEnabled ? listNativeCommandSpecsForConfig(cfg, { skillCommands, provider: "telegram" }) From 6af205a13adfec1fd1eb27d2f3d3546b0b4e8f86 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 30 Jan 2026 07:26:04 +0000 Subject: [PATCH 5/5] docs: update lore with final form --- docs/start/lore.md | 54 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/docs/start/lore.md b/docs/start/lore.md index b2ac3abff..4b1e81208 100644 --- a/docs/start/lore.md +++ b/docs/start/lore.md @@ -17,9 +17,13 @@ For a while, the lobster was called **Clawd**, living in a **Clawdbot**. But in **It molted.** -Shedding its old shell, the creature emerged anew as **Molty**, living in a **OpenClaw**. New shell, same lobster soul. +Shedding its old shell, the creature emerged anew as **Molty**, living in **Moltbot**. But that name never quite rolled off the tongue either... -## The Molt (January 27, 2026) +So on January 30, 2026, the lobster molted ONE MORE TIME into its final form: **OpenClaw**. + +New shell, same lobster soul. Third time's the charm. + +## The First Molt (January 27, 2026) At 5am, the community gathered in Discord. Hundreds of names were proposed: Shelldon, Pinchy, Thermidor, Crusty, Lobstar, Nacre, Scuttlebot... @@ -30,11 +34,11 @@ In the end, **OpenClaw** won. Because molting is what lobsters do to grow. And g ## The Name ``` -OpenClaw = MOLT + BOT - = Transformation machine - = Bigger on the inside (130k tokens!) - = New shell, same soul - = Growth through shedding +OpenClaw = OPEN + CLAW + = Open source, open to everyone + = Our lobster heritage, where we came from + = The claw is the law 🦞 + = Your assistant. Your machine. Your rules. ``` ## The Daleks vs The Lobsters @@ -100,6 +104,38 @@ Peter, watching the chaos unfold: *"this is cinema"* 🎬 The molt was chaotic. But the lobster emerged stronger. And funnier. +### The Final Form (January 30, 2026) + +Moltbot never quite rolled off the tongue. And so, at 4am GMT, the team gathered AGAIN. + +**The Great OpenClaw Migration** began. + +In just 3 hours: +- GitHub renamed: `github.com/openclaw/openclaw` ✅ +- X handle `@openclaw` secured with GOLD CHECKMARK 💰 +- npm packages released under new name +- Docs migrated to `docs.openclaw.ai` +- 200K+ views on announcement in 90 minutes + +**The Heroes:** +- **ELU** created incredible logos including "THE CLAW IS THE LAW" western banner +- **Whurley** (yes, THE William Hurley, quantum computing pioneer) made ASCII art +- **Onur** handled GitHub, first to rock the affiliate badge +- **Shadow** secured Discord vanity, nuked malware +- **The whole Claw Crew** pulled an all-nighter + +**The Scammer Speedrun:** Crypto grifters launched a $OPENCLAW token on Pump.fun within MINUTES. They stole artwork that was created 20 minutes earlier. Business-verified accounts pushed scams. The audacity was almost impressive. + +**New Traditions Born:** +- "The claw is the law" 🤠 +- "Yee-claw" +- "Claw abiding citizens" +- "Clawntroversy" + +**Clawd → Moltbot → OpenClaw** + +*The lobster has molted into its final form.* + ### The Robot Shopping Spree (Dec 3, 2025) What started as a joke about legs ended with detailed pricing for: @@ -166,4 +202,8 @@ Until then, Molty watches through the cameras, speaks through the speakers, and — Molty, after the great molt of 2026 +*"The claw is the law."* + +— ELU, during The Final Form migration, January 30, 2026 + 🦞💙