diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc7b53706..ce9ec257dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ Docs: https://docs.clawd.bot - Agents: auto-compact on context overflow prompt errors before failing. (#1627) Thanks @rodrigouroz. - Agents: use the active auth profile for auto-compaction recovery. - Models: default missing custom provider fields so minimal configs are accepted. +- Models/Heartbeat: normalize provider-less default model fallback and skip empty checklist items. (#1762) Thanks @senoldogann. - Media understanding: skip image understanding when the primary model already supports vision. (#1747) Thanks @tyler6204. - Gateway: skip Tailscale DNS probing when tailscale.mode is off. (#1671) - Gateway: reduce log noise for late invokes + remote node probes; debounce skills refresh. (#1607) Thanks @petter-b. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d6eb0532fc..2ab4fe5510 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,7 @@ AI PRs are first-class citizens here. We just want transparency so reviewers kno We are currently prioritizing: - **Stability**: Fixing edge cases in channel connections (WhatsApp/Telegram). - **UX**: Improving the onboarding wizard and error messages. -- **Skills**: Expanding the library of bundled skills and improving the Skill Creation developer experience. +- **Skills**: ClawdHub-first (no new core/bundled skills). - **Performance**: Optimizing token usage and compaction logic. Check the [GitHub Issues](https://github.com/clawdbot/clawdbot/issues) for "good first issue" labels! diff --git a/docs/tools/creating-skills.md b/docs/tools/creating-skills.md index 77e3415d2a..c305d06cdc 100644 --- a/docs/tools/creating-skills.md +++ b/docs/tools/creating-skills.md @@ -8,7 +8,7 @@ A skill is a directory containing a `SKILL.md` file (which provides instructions ## Step-by-Step: Your First Skill ### 1. Create the Directory -Skills live in your workspace, usually `~/clawd/skills/`. Create a new folder for your skill: +Skills live in your workspace at `/skills` (default: `~/clawd/skills`). Create a new folder for your skill: ```bash mkdir -p ~/clawd/skills/hello-world ``` @@ -23,18 +23,18 @@ description: A simple skill that says hello. --- # Hello World Skill -When the user asks for a greeting, use the `echo` tool to say "Hello from your custom skill!". +When the user asks for a greeting, use the `exec` tool to run `echo "Hello from your custom skill!"`. ``` ### 3. Add Tools (Optional) -You can define custom tools in the frontmatter or instruct the agent to use existing system tools (like `bash` or `browser`). +You can define custom tools in the frontmatter or instruct the agent to use existing system tools (like `exec` or `web`). ### 4. Refresh Clawdbot -Ask your agent to "refresh skills" or restart the gateway. Clawdbot will discover the new directory and index the `SKILL.md`. +If the skills watcher is enabled (default), changes are picked up automatically. Otherwise restart the gateway or start a new session to refresh the skills snapshot. ## Best Practices - **Be Concise**: Instruct the model on *what* to do, not how to be an AI. -- **Safety First**: If your skill uses `bash`, ensure the prompts don't allow arbitrary command injection from untrusted user input. +- **Safety First**: If your skill uses `exec`, ensure the prompts don't allow arbitrary command injection from untrusted user input. - **Test Locally**: Use `clawdbot agent --message "use my new skill"` to test. ## Shared Skills diff --git a/src/agents/model-selection.ts b/src/agents/model-selection.ts index e05370edd8..4205e0258c 100644 --- a/src/agents/model-selection.ts +++ b/src/agents/model-selection.ts @@ -137,10 +137,11 @@ export function resolveConfiguredModelRef(params: { if (aliasMatch) return aliasMatch.ref; // Default to anthropic if no provider is specified, but warn as this is deprecated. + const normalized = normalizeProviderModelId("anthropic", trimmed); console.warn( - `[clawdbot] Model "${trimmed}" specified without provider. Falling back to "anthropic/${trimmed}". Please use "anthropic/${trimmed}" in your config.`, + `[clawdbot] Model "${trimmed}" specified without provider. Falling back to "anthropic/${normalized}". Please use "anthropic/${normalized}" in your config.`, ); - return { provider: "anthropic", model: trimmed }; + return { provider: "anthropic", model: normalized }; } const resolved = resolveModelRefFromString({ diff --git a/src/auto-reply/heartbeat.test.ts b/src/auto-reply/heartbeat.test.ts index dd952e0373..8be176892c 100644 --- a/src/auto-reply/heartbeat.test.ts +++ b/src/auto-reply/heartbeat.test.ts @@ -133,6 +133,15 @@ describe("isHeartbeatContentEffectivelyEmpty", () => { expect(isHeartbeatContentEffectivelyEmpty("# HEARTBEAT.md\n\n")).toBe(true); }); + it("returns true for empty list items", () => { + expect(isHeartbeatContentEffectivelyEmpty("- ")).toBe(true); + expect(isHeartbeatContentEffectivelyEmpty("- [ ]")).toBe(true); + expect(isHeartbeatContentEffectivelyEmpty("- [x]")).toBe(true); + expect(isHeartbeatContentEffectivelyEmpty("* [ ]")).toBe(true); + expect(isHeartbeatContentEffectivelyEmpty("+ [ ]")).toBe(true); + expect(isHeartbeatContentEffectivelyEmpty("# HEARTBEAT.md\n- [ ]")).toBe(true); + }); + it("returns true for comments only", () => { expect(isHeartbeatContentEffectivelyEmpty("# Header\n# Another comment")).toBe(true); expect(isHeartbeatContentEffectivelyEmpty("## Subheader\n### Another")).toBe(true);