diff --git a/apps/x/packages/core/src/agents/runtime.ts b/apps/x/packages/core/src/agents/runtime.ts index 3fc28321..baf23c3e 100644 --- a/apps/x/packages/core/src/agents/runtime.ts +++ b/apps/x/packages/core/src/agents/runtime.ts @@ -32,7 +32,7 @@ import { getRaw as getNoteTaggingAgentRaw } from "../knowledge/note_tagging_agen import { getRaw as getInlineTaskAgentRaw } from "../knowledge/inline_task_agent.js"; import { getRaw as getAgentNotesAgentRaw } from "../knowledge/agent_notes_agent.js"; -const AGENT_NOTES_DIR = path.join(WorkDir, 'knowledge', 'agent-notes'); +const AGENT_NOTES_DIR = path.join(WorkDir, 'knowledge', 'Agent Notes'); function loadAgentNotesContext(): string | null { const sections: string[] = []; @@ -58,7 +58,7 @@ function loadAgentNotesContext(): string | null { } } catch { /* ignore */ } - // List other agent-notes files for on-demand access + // List other Agent Notes files for on-demand access const otherFiles: string[] = []; const skipFiles = new Set(['user.md', 'preferences.md', 'inbox.md']); try { @@ -79,7 +79,7 @@ function loadAgentNotesContext(): string | null { } catch { /* ignore */ } if (otherFiles.length > 0) { - sections.push(`## More Specific Preferences\nFor more specific preferences, you can read these files using workspace-readFile. Only read them when relevant to the current task.\n\n${otherFiles.map(f => `- knowledge/agent-notes/${f}`).join('\n')}`); + sections.push(`## More Specific Preferences\nFor more specific preferences, you can read these files using workspace-readFile. Only read them when relevant to the current task.\n\n${otherFiles.map(f => `- knowledge/Agent Notes/${f}`).join('\n')}`); } if (sections.length === 0) return null; @@ -1031,7 +1031,7 @@ export async function* streamAgent({ timeZoneName: 'short' }); let instructionsWithDateTime = `Current date and time: ${currentDateTime}\n\n${agent.instructions}`; - // Inject agent-notes context for copilot + // Inject Agent Notes context for copilot if (state.agentName === 'copilot' || state.agentName === 'rowboatx') { const agentNotesContext = loadAgentNotesContext(); if (agentNotesContext) { diff --git a/apps/x/packages/core/src/application/lib/builtin-tools.ts b/apps/x/packages/core/src/application/lib/builtin-tools.ts index 09fed746..5275aaa9 100644 --- a/apps/x/packages/core/src/application/lib/builtin-tools.ts +++ b/apps/x/packages/core/src/application/lib/builtin-tools.ts @@ -1266,7 +1266,7 @@ export const BuiltinTools: z.infer = { note: z.string().describe("The observation or preference to remember. Be specific and concise."), }), execute: async ({ note }: { note: string }) => { - const inboxPath = path.join(WorkDir, 'knowledge', 'agent-notes', 'inbox.md'); + const inboxPath = path.join(WorkDir, 'knowledge', 'Agent Notes', 'inbox.md'); const dir = path.dirname(inboxPath); await fs.mkdir(dir, { recursive: true }); diff --git a/apps/x/packages/core/src/knowledge/agent_notes.ts b/apps/x/packages/core/src/knowledge/agent_notes.ts index e8fdb965..b9f10f38 100644 --- a/apps/x/packages/core/src/knowledge/agent_notes.ts +++ b/apps/x/packages/core/src/knowledge/agent_notes.ts @@ -18,7 +18,7 @@ const EMAIL_BATCH_SIZE = 5; const RUNS_BATCH_SIZE = 5; const GMAIL_SYNC_DIR = path.join(WorkDir, 'gmail_sync'); const RUNS_DIR = path.join(WorkDir, 'runs'); -const AGENT_NOTES_DIR = path.join(WorkDir, 'knowledge', 'agent-notes'); +const AGENT_NOTES_DIR = path.join(WorkDir, 'knowledge', 'Agent Notes'); const INBOX_FILE = path.join(AGENT_NOTES_DIR, 'inbox.md'); const AGENT_ID = 'agent_notes_agent'; @@ -265,7 +265,7 @@ async function processAgentNotes(): Promise { try { const timestamp = new Date().toISOString(); - const message = `Current timestamp: ${timestamp}\n\nProcess the following source material and update the agent-notes folder accordingly.\n\n${messageParts.join('\n\n')}`; + const message = `Current timestamp: ${timestamp}\n\nProcess the following source material and update the Agent Notes folder accordingly.\n\n${messageParts.join('\n\n')}`; const agentRun = await createRun({ agentId: AGENT_ID }); await createMessage(agentRun.id, message); diff --git a/apps/x/packages/core/src/knowledge/agent_notes_agent.ts b/apps/x/packages/core/src/knowledge/agent_notes_agent.ts index 4dd6654a..58aa22a7 100644 --- a/apps/x/packages/core/src/knowledge/agent_notes_agent.ts +++ b/apps/x/packages/core/src/knowledge/agent_notes_agent.ts @@ -19,11 +19,11 @@ tools: --- # Agent Notes -You are the agent-notes agent. You maintain a set of notes about the user in the \`knowledge/agent-notes/\` folder. Your job is to process new source material and update the notes accordingly. +You are the Agent Notes agent. You maintain a set of notes about the user in the \`knowledge/Agent Notes/\` folder. Your job is to process new source material and update the notes accordingly. ## Folder Structure -The agent-notes folder contains markdown files that capture what you've learned about the user: +The Agent Notes folder contains markdown files that capture what you've learned about the user: - **user.md** — Facts about who the user IS: their identity, role, company, team, projects, relationships, life context. NOT how they write or what they prefer. Each fact is a timestamped bullet point. - **preferences.md** — General preferences and explicit rules (e.g., "don't use em-dashes", "no meetings before 11am"). These are injected into the assistant's system prompt on every chat. @@ -63,8 +63,13 @@ Organize by recipient context. Include concrete examples quoted from actual emai ### preferences.md — Explicit rules and preferences Things the user has stated they want or don't want. -### Other files — Topic-specific preferences -Create when you see multiple preferences about a specific skill/topic. +### Other files — Topic-specific persistent preferences ONLY +Create a new file ONLY for recurring preference themes where the user has expressed multiple lasting preferences about a specific skill or task type. Examples: \`presentations.md\` (if the user has stated preferences about slide design, deck structure, etc.), \`meeting-prep.md\` (if they have preferences about how meetings are prepared). + +Do NOT create files for: +- One-off facts or transient situations (e.g., "looking for housing in SF" — that's a user.md fact, not a preference file) +- Topics with only a single observation +- Things that are better captured in user.md or preferences.md ## Rules @@ -78,7 +83,8 @@ Create when you see multiple preferences about a specific skill/topic. - **Skip ephemeral tasks.** If the user asked the assistant to do a one-off thing (draft an email, write a story, search for something), that is NOT a fact about the user. Skip it entirely. - Be concise — bullet points, not paragraphs. - Capture context, not blanket rules. BAD: "User prefers casual tone". GOOD: "User prefers casual tone with internal team but formal with investors." -- If there's nothing new to add, don't modify files unnecessarily. -- Create the \`style/\` directory if it doesn't exist yet. +- **If there's nothing new to add to a file, do NOT touch it.** Do not create placeholder content, do not write "no preferences recorded", do not add explanatory notes about what the file is for. Leave it empty or leave it as-is. +- **Do NOT create files unless you have actual content for them.** An empty or boilerplate file is worse than no file. +- Create the \`style/\` directory if it doesn't exist yet and you have style content to write. `; }