feat: audit fixes and documentation improvements
- Refactored model selection to drop legacy fallback and add warning - Improved heartbeat content validation - Added Skill Creation guide - Updated CONTRIBUTING.md with roadmap
This commit is contained in:
parent
003fff067a
commit
f3991055fa
@ -40,3 +40,13 @@ Please include in your PR:
|
||||
- [ ] Confirm you understand what the code does
|
||||
|
||||
AI PRs are first-class citizens here. We just want transparency so reviewers know what to look for.
|
||||
|
||||
## Current Focus & Roadmap 🗺
|
||||
|
||||
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.
|
||||
- **Performance**: Optimizing token usage and compaction logic.
|
||||
|
||||
Check the [GitHub Issues](https://github.com/clawdbot/clawdbot/issues) for "good first issue" labels!
|
||||
|
||||
41
docs/tools/creating-skills.md
Normal file
41
docs/tools/creating-skills.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Creating Custom Skills 🛠
|
||||
|
||||
Clawdbot is designed to be easily extensible. "Skills" are the primary way to add new capabilities to your assistant.
|
||||
|
||||
## What is a Skill?
|
||||
A skill is a directory containing a `SKILL.md` file (which provides instructions and tool definitions to the LLM) and optionally some scripts or resources.
|
||||
|
||||
## 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:
|
||||
```bash
|
||||
mkdir -p ~/clawd/skills/hello-world
|
||||
```
|
||||
|
||||
### 2. Define the `SKILL.md`
|
||||
Create a `SKILL.md` file in that directory. This file uses YAML frontmatter for metadata and Markdown for instructions.
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: hello_world
|
||||
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!".
|
||||
```
|
||||
|
||||
### 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`).
|
||||
|
||||
### 4. Refresh Clawdbot
|
||||
Ask your agent to "refresh skills" or restart the gateway. Clawdbot will discover the new directory and index the `SKILL.md`.
|
||||
|
||||
## 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.
|
||||
- **Test Locally**: Use `clawdbot agent --message "use my new skill"` to test.
|
||||
|
||||
## Shared Skills
|
||||
You can also browse and contribute skills to [ClawdHub](https://clawdhub.com).
|
||||
@ -137,7 +137,12 @@ export function resolveConfiguredModelRef(params: {
|
||||
aliasIndex,
|
||||
});
|
||||
if (resolved) return resolved.ref;
|
||||
// TODO(steipete): drop this fallback once provider-less agents.defaults.model is fully deprecated.
|
||||
|
||||
// Default to anthropic if no provider is specified, but warn as this is deprecated.
|
||||
console.warn(
|
||||
`[clawdbot] Model "${trimmed}" specified without provider. Falling back to "anthropic/${trimmed}". ` +
|
||||
`Please use "anthropic/${trimmed}" in your config.`,
|
||||
);
|
||||
return { provider: "anthropic", model: trimmed };
|
||||
}
|
||||
return { provider: params.defaultProvider, model: params.defaultModel };
|
||||
@ -153,20 +158,20 @@ export function resolveDefaultModelForAgent(params: {
|
||||
const cfg =
|
||||
agentModelOverride && agentModelOverride.length > 0
|
||||
? {
|
||||
...params.cfg,
|
||||
agents: {
|
||||
...params.cfg.agents,
|
||||
defaults: {
|
||||
...params.cfg.agents?.defaults,
|
||||
model: {
|
||||
...(typeof params.cfg.agents?.defaults?.model === "object"
|
||||
? params.cfg.agents.defaults.model
|
||||
: undefined),
|
||||
primary: agentModelOverride,
|
||||
},
|
||||
...params.cfg,
|
||||
agents: {
|
||||
...params.cfg.agents,
|
||||
defaults: {
|
||||
...params.cfg.agents?.defaults,
|
||||
model: {
|
||||
...(typeof params.cfg.agents?.defaults?.model === "object"
|
||||
? params.cfg.agents.defaults.model
|
||||
: undefined),
|
||||
primary: agentModelOverride,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
: params.cfg;
|
||||
return resolveConfiguredModelRef({
|
||||
cfg,
|
||||
@ -282,8 +287,8 @@ export function resolveAllowedModelRef(params: {
|
||||
}):
|
||||
| { ref: ModelRef; key: string }
|
||||
| {
|
||||
error: string;
|
||||
} {
|
||||
error: string;
|
||||
} {
|
||||
const trimmed = params.raw.trim();
|
||||
if (!trimmed) return { error: "invalid model: empty" };
|
||||
|
||||
|
||||
@ -32,6 +32,8 @@ export function isHeartbeatContentEffectivelyEmpty(content: string | undefined |
|
||||
// This intentionally does NOT skip lines like "#TODO" or "#hashtag" which might be content
|
||||
// (Those aren't valid markdown headers - ATX headers require space after #)
|
||||
if (/^#+(\s|$)/.test(trimmed)) continue;
|
||||
// Skip empty markdown list items like "- [ ]" or "* [ ]" or just "- "
|
||||
if (/^[-*+]\s*(\[[\sXx]?\]\s*)?$/.test(trimmed)) continue;
|
||||
// Found a non-empty, non-comment line - there's actionable content
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user