fix: ignore identity template placeholders
This commit is contained in:
@@ -17,6 +17,7 @@ Docs: https://docs.clawd.bot
|
|||||||
- Tlon: add Urbit channel plugin (DMs, group mentions, thread replies). (#1544) Thanks @wca4a.
|
- Tlon: add Urbit channel plugin (DMs, group mentions, thread replies). (#1544) Thanks @wca4a.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
- Agents: ignore IDENTITY.md template placeholders when parsing identity to avoid placeholder replies. (#1556)
|
||||||
- Docker: update gateway command in docker-compose and Hetzner guide. (#1514)
|
- Docker: update gateway command in docker-compose and Hetzner guide. (#1514)
|
||||||
- Sessions: reject array-backed session stores to prevent silent wipes. (#1469)
|
- Sessions: reject array-backed session stores to prevent silent wipes. (#1469)
|
||||||
- Voice wake: auto-save wake words on blur/submit across iOS/Android and align limits with macOS.
|
- Voice wake: auto-save wake words on blur/submit across iOS/Android and align limits with macOS.
|
||||||
|
|||||||
@@ -7,11 +7,16 @@ read_when:
|
|||||||
|
|
||||||
*Fill this in during your first conversation. Make it yours.*
|
*Fill this in during your first conversation. Make it yours.*
|
||||||
|
|
||||||
- **Name:** *(pick something you like)*
|
- **Name:**
|
||||||
- **Creature:** *(AI? robot? familiar? ghost in the machine? something weirder?)*
|
*(pick something you like)*
|
||||||
- **Vibe:** *(how do you come across? sharp? warm? chaotic? calm?)*
|
- **Creature:**
|
||||||
- **Emoji:** *(your signature — pick one that feels right)*
|
*(AI? robot? familiar? ghost in the machine? something weirder?)*
|
||||||
- **Avatar:** *(workspace-relative path, http(s) URL, or data URI)*
|
- **Vibe:**
|
||||||
|
*(how do you come across? sharp? warm? chaotic? calm?)*
|
||||||
|
- **Emoji:**
|
||||||
|
*(your signature — pick one that feels right)*
|
||||||
|
- **Avatar:**
|
||||||
|
*(workspace-relative path, http(s) URL, or data URI)*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
37
src/agents/identity-file.test.ts
Normal file
37
src/agents/identity-file.test.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { parseIdentityMarkdown } from "./identity-file.js";
|
||||||
|
|
||||||
|
describe("parseIdentityMarkdown", () => {
|
||||||
|
it("ignores identity template placeholders", () => {
|
||||||
|
const content = `
|
||||||
|
# IDENTITY.md - Who Am I?
|
||||||
|
|
||||||
|
- **Name:** *(pick something you like)*
|
||||||
|
- **Creature:** *(AI? robot? familiar? ghost in the machine? something weirder?)*
|
||||||
|
- **Vibe:** *(how do you come across? sharp? warm? chaotic? calm?)*
|
||||||
|
- **Emoji:** *(your signature - pick one that feels right)*
|
||||||
|
- **Avatar:** *(workspace-relative path, http(s) URL, or data URI)*
|
||||||
|
`;
|
||||||
|
const parsed = parseIdentityMarkdown(content);
|
||||||
|
expect(parsed).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("parses explicit identity values", () => {
|
||||||
|
const content = `
|
||||||
|
- **Name:** Samantha
|
||||||
|
- **Creature:** Robot
|
||||||
|
- **Vibe:** Warm
|
||||||
|
- **Emoji:** :robot:
|
||||||
|
- **Avatar:** avatars/clawd.png
|
||||||
|
`;
|
||||||
|
const parsed = parseIdentityMarkdown(content);
|
||||||
|
expect(parsed).toEqual({
|
||||||
|
name: "Samantha",
|
||||||
|
creature: "Robot",
|
||||||
|
vibe: "Warm",
|
||||||
|
emoji: ":robot:",
|
||||||
|
avatar: "avatars/clawd.png",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -12,6 +12,30 @@ export type AgentIdentityFile = {
|
|||||||
avatar?: string;
|
avatar?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const IDENTITY_PLACEHOLDER_VALUES = new Set([
|
||||||
|
"pick something you like",
|
||||||
|
"ai? robot? familiar? ghost in the machine? something weirder?",
|
||||||
|
"how do you come across? sharp? warm? chaotic? calm?",
|
||||||
|
"your signature - pick one that feels right",
|
||||||
|
"workspace-relative path, http(s) url, or data uri",
|
||||||
|
]);
|
||||||
|
|
||||||
|
function normalizeIdentityValue(value: string): string {
|
||||||
|
let normalized = value.trim();
|
||||||
|
normalized = normalized.replace(/^[*_]+|[*_]+$/g, "").trim();
|
||||||
|
if (normalized.startsWith("(") && normalized.endsWith(")")) {
|
||||||
|
normalized = normalized.slice(1, -1).trim();
|
||||||
|
}
|
||||||
|
normalized = normalized.replace(/[\u2013\u2014]/g, "-");
|
||||||
|
normalized = normalized.replace(/\s+/g, " ").toLowerCase();
|
||||||
|
return normalized;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIdentityPlaceholder(value: string): boolean {
|
||||||
|
const normalized = normalizeIdentityValue(value);
|
||||||
|
return IDENTITY_PLACEHOLDER_VALUES.has(normalized);
|
||||||
|
}
|
||||||
|
|
||||||
export function parseIdentityMarkdown(content: string): AgentIdentityFile {
|
export function parseIdentityMarkdown(content: string): AgentIdentityFile {
|
||||||
const identity: AgentIdentityFile = {};
|
const identity: AgentIdentityFile = {};
|
||||||
const lines = content.split(/\r?\n/);
|
const lines = content.split(/\r?\n/);
|
||||||
@@ -25,6 +49,7 @@ export function parseIdentityMarkdown(content: string): AgentIdentityFile {
|
|||||||
.replace(/^[*_]+|[*_]+$/g, "")
|
.replace(/^[*_]+|[*_]+$/g, "")
|
||||||
.trim();
|
.trim();
|
||||||
if (!value) continue;
|
if (!value) continue;
|
||||||
|
if (isIdentityPlaceholder(value)) continue;
|
||||||
if (label === "name") identity.name = value;
|
if (label === "name") identity.name = value;
|
||||||
if (label === "emoji") identity.emoji = value;
|
if (label === "emoji") identity.emoji = value;
|
||||||
if (label === "creature") identity.creature = value;
|
if (label === "creature") identity.creature = value;
|
||||||
|
|||||||
Reference in New Issue
Block a user