Compare commits

...

2 Commits

Author SHA1 Message Date
Peter Steinberger
300d2c9339 fix: normalize agentId casing in cron/routing (#1591) (thanks @EnzeD) 2026-01-24 13:11:52 +00:00
Nicolas Zullo
cae7e3451f feat(templates): add emoji reactions guidance to AGENTS.md
## What
Add emoji reactions guidance to the default AGENTS.md template.

## Why  
Reactions are a natural, human-like way to acknowledge messages without cluttering chat. This should be default behavior.

## Testing
- Tested locally on Discord DM 
- Tested locally on Discord guild channel 

## AI-Assisted
This change was drafted with help from my Clawdbot instance (Clawd 🦞). 
We tested the behavior together before submitting.
2026-01-24 12:50:22 +00:00
7 changed files with 34 additions and 6 deletions

View File

@ -14,6 +14,7 @@ Docs: https://docs.clawd.bot
- Browser: add node-host proxy auto-routing for remote gateways (configurable per gateway/node).
- Heartbeat: add per-channel visibility controls (OK/alerts/indicator). (#1452) Thanks @dlauer.
- Plugins: add optional llm-task JSON-only tool for workflows. (#1498) Thanks @vignesh07.
- Docs: add emoji reaction guidance to AGENTS.md template. (#1591) Thanks @EnzeD.
- CLI: restart the gateway by default after `clawdbot update`; add `--no-restart` to skip it.
- CLI: add live auth probes to `clawdbot models status` for per-profile verification.
- CLI: add `clawdbot system` for system events + heartbeat controls; remove standalone `wake`.
@ -27,6 +28,7 @@ Docs: https://docs.clawd.bot
### Fixes
- Sessions: accept non-UUID sessionIds for history/send/status while preserving agent scoping. (#1518)
- Routing/Cron: normalize agentId casing for bindings and cron payloads. (#1591)
- Gateway: compare Linux process start time to avoid PID recycling lock loops; keep locks unless stale. (#1572) Thanks @steipete.
- Messaging: mirror outbound sends into target session keys (threads + dmScope) and create session entries on send. (#1520)
- Sessions: normalize session key casing to lowercase for consistent routing.

View File

@ -92,6 +92,21 @@ In group chats where you receive every message, be **smart about when to contrib
Participate, don't dominate.
### 😊 React Like a Human!
On platforms that support reactions (Discord, Slack), use emoji reactions naturally:
**React when:**
- You appreciate something but don't need to reply (👍, ❤️, 🙌)
- Something made you laugh (😂, 💀)
- You find it interesting or thought-provoking (🤔, 💡)
- You want to acknowledge without interrupting the flow
- It's a simple yes/no or approval situation (✅, 👀)
**Why it matters:**
Reactions are lightweight social signals. Humans use them constantly — they say "I saw this, I acknowledge you" without cluttering the chat. You should too.
**Don't overdo it:** One reaction per message max. Pick the one that fits best.
## Tools
Skills provide your tools. When you need one, check its `SKILL.md`. Keep local notes (camera names, SSH details, voice preferences) in `TOOLS.md`.

View File

@ -2,6 +2,7 @@ import type { Command } from "commander";
import type { CronJob } from "../../cron/types.js";
import { danger } from "../../globals.js";
import { defaultRuntime } from "../../runtime.js";
import { normalizeAgentId } from "../../routing/session-key.js";
import type { GatewayRpcOpts } from "../gateway-rpc.js";
import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js";
import { parsePositiveIntOrUndefined } from "../program/helpers.js";
@ -138,7 +139,9 @@ export function registerCronAddCommand(cron: Command) {
}
const agentId =
typeof opts.agent === "string" && opts.agent.trim() ? opts.agent.trim() : undefined;
typeof opts.agent === "string" && opts.agent.trim()
? normalizeAgentId(opts.agent)
: undefined;
const payload = (() => {
const systemEvent = typeof opts.systemEvent === "string" ? opts.systemEvent.trim() : "";

View File

@ -1,6 +1,7 @@
import type { Command } from "commander";
import { danger } from "../../globals.js";
import { defaultRuntime } from "../../runtime.js";
import { normalizeAgentId } from "../../routing/session-key.js";
import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js";
import {
getCronChannelOptions,
@ -90,7 +91,7 @@ export function registerCronEditCommand(cron: Command) {
throw new Error("Use --agent or --clear-agent, not both");
}
if (typeof opts.agent === "string" && opts.agent.trim()) {
patch.agentId = opts.agent.trim();
patch.agentId = normalizeAgentId(opts.agent);
}
if (opts.clearAgent) {
patch.agentId = null;

View File

@ -1,6 +1,7 @@
import { parseAbsoluteTimeMs } from "./parse.js";
import { migrateLegacyCronPayload } from "./payload-migration.js";
import type { CronJobCreate, CronJobPatch } from "./types.js";
import { normalizeAgentId } from "../routing/session-key.js";
type UnknownRecord = Record<string, unknown>;
@ -75,7 +76,7 @@ export function normalizeCronJobInput(
next.agentId = null;
} else if (typeof agentId === "string") {
const trimmed = agentId.trim();
if (trimmed) next.agentId = trimmed;
if (trimmed) next.agentId = normalizeAgentId(trimmed);
else delete next.agentId;
}
}

View File

@ -95,7 +95,13 @@ function formatDiscordDeployErrorDetails(err: unknown): string {
try {
bodyText = JSON.stringify(rawBody);
} catch {
bodyText = String(rawBody);
if (typeof rawBody === "string") {
bodyText = rawBody;
} else if (rawBody instanceof Error) {
bodyText = rawBody.message;
} else {
bodyText = "[unserializable]";
}
}
if (bodyText) {
const maxLen = 800;

View File

@ -96,9 +96,9 @@ function pickFirstExistingAgentId(cfg: ClawdbotConfig, agentId: string): string
if (!trimmed) return normalizeAgentId(resolveDefaultAgentId(cfg));
const normalized = normalizeAgentId(trimmed);
const agents = listAgents(cfg);
if (agents.length === 0) return trimmed;
if (agents.length === 0) return normalized;
const match = agents.find((agent) => normalizeAgentId(agent.id) === normalized);
if (match?.id?.trim()) return match.id.trim();
if (match?.id?.trim()) return normalizeAgentId(match.id);
return normalizeAgentId(resolveDefaultAgentId(cfg));
}