feat(agent): add soul.md support for agent identity
- Add getSoulContent/updateSoulContent to ProfileManager - Create soul.md with agent name when updating profile name - Add reloadSystemPrompt() method to Agent and AsyncAgent - Include soul.md content in system prompt build Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
82f0ccbe85
commit
fa03ae6e62
4 changed files with 93 additions and 4 deletions
|
|
@ -176,4 +176,12 @@ export class AsyncAgent {
|
|||
setUserContent(content: string): void {
|
||||
this.agent.setUserContent(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload profile from disk and rebuild system prompt.
|
||||
* Call this after updating profile files to apply changes immediately.
|
||||
*/
|
||||
reloadSystemPrompt(): void {
|
||||
this.agent.reloadSystemPrompt();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,12 @@ export class ProfileManager {
|
|||
return this.profile;
|
||||
}
|
||||
|
||||
/** 重新从磁盘加载 profile(清除缓存) */
|
||||
reloadProfile(): AgentProfile | undefined {
|
||||
this.profile = loadAgentProfile(this.profileId, { baseDir: this.baseDir });
|
||||
return this.profile;
|
||||
}
|
||||
|
||||
/** 获取或创建 profile */
|
||||
getOrCreateProfile(useTemplates = true): AgentProfile {
|
||||
if (!this.profile) {
|
||||
|
|
@ -132,6 +138,7 @@ export class ProfileManager {
|
|||
/** 构建 system prompt */
|
||||
buildSystemPrompt(): string {
|
||||
const profile = this.getProfile();
|
||||
console.log('[ProfileManager] buildSystemPrompt called, profile exists:', !!profile);
|
||||
if (!profile) {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -139,11 +146,15 @@ export class ProfileManager {
|
|||
const parts: string[] = [];
|
||||
|
||||
if (profile.soul) {
|
||||
console.log('[ProfileManager] Adding soul, length:', profile.soul.length);
|
||||
parts.push(profile.soul);
|
||||
}
|
||||
|
||||
if (profile.user) {
|
||||
console.log('[ProfileManager] Adding user, content:', profile.user.substring(0, 100));
|
||||
parts.push(profile.user);
|
||||
} else {
|
||||
console.log('[ProfileManager] No user content in profile');
|
||||
}
|
||||
|
||||
if (profile.workspace) {
|
||||
|
|
@ -236,6 +247,40 @@ export class ProfileManager {
|
|||
profile.config = newConfig;
|
||||
this.profile = profile;
|
||||
writeProfileConfig(this.profileId, newConfig, { baseDir: this.baseDir });
|
||||
|
||||
// Also update soul.md to include the agent name
|
||||
this.updateSoulWithName(name);
|
||||
}
|
||||
|
||||
/** 更新 soul.md,确保包含 Agent 名称 */
|
||||
private updateSoulWithName(name: string): void {
|
||||
const profile = this.getOrCreateProfile(true); // 确保有默认模板
|
||||
let soulContent = profile.soul ?? DEFAULT_TEMPLATES.soul;
|
||||
|
||||
// 替换 soul.md 中的 Name 字段
|
||||
// 匹配 "- **Name:** xxx" 格式
|
||||
const namePattern = /- \*\*Name:\*\* .*/;
|
||||
const newNameLine = `- **Name:** ${name}`;
|
||||
|
||||
if (namePattern.test(soulContent)) {
|
||||
soulContent = soulContent.replace(namePattern, newNameLine);
|
||||
} else {
|
||||
// 如果没有找到 Name 字段,在 Identity 部分后添加
|
||||
const identityPattern = /## Identity\n/;
|
||||
if (identityPattern.test(soulContent)) {
|
||||
soulContent = soulContent.replace(identityPattern, `## Identity\n\n${newNameLine}\n`);
|
||||
} else {
|
||||
// 如果没有 Identity 部分,在开头添加
|
||||
soulContent = `# Soul\n\n## Identity\n\n${newNameLine}\n\n${soulContent}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 保存更新后的 soul.md
|
||||
writeProfileFile(this.profileId, PROFILE_FILES.soul, soulContent, { baseDir: this.baseDir });
|
||||
// 更新缓存
|
||||
if (this.profile) {
|
||||
this.profile.soul = soulContent;
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取 user.md 内容 */
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
export const DEFAULT_TEMPLATES = {
|
||||
soul: `# Soul
|
||||
soul: `# Soul
|
||||
|
||||
_You're not a chatbot. You're becoming someone._
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ If you change this file, tell the user — it's your soul, and they should know.
|
|||
_This file is yours to evolve. As you learn who you are, update it._
|
||||
`,
|
||||
|
||||
user: `# User
|
||||
user: `# User
|
||||
|
||||
_Learn about the person you're helping. Update this as you go._
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ _(What do they care about? What projects are they working on? What annoys them?
|
|||
The more you know, the better you can help. But remember — you're learning about a person, not building a dossier. Respect the difference.
|
||||
`,
|
||||
|
||||
workspace: `# Workspace
|
||||
workspace: `# Workspace
|
||||
|
||||
This folder is home. Treat it that way.
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ Capture what matters. Decisions, context, things to remember.
|
|||
This is a starting point. Add your own conventions, style, and rules as you figure out what works.
|
||||
`,
|
||||
|
||||
memory: `# Memory
|
||||
memory: `# Memory
|
||||
|
||||
_(Persistent knowledge will be stored here. Update this as you learn.)_
|
||||
|
||||
|
|
|
|||
|
|
@ -446,12 +446,15 @@ export class Agent {
|
|||
reloadTools(): string[] {
|
||||
// Re-read profile tools config to get latest changes
|
||||
const profileToolsConfig = this.profile?.getToolsConfig();
|
||||
console.log(`[Agent] reloadTools: profileToolsConfig =`, JSON.stringify(profileToolsConfig));
|
||||
const mergedToolsConfig = mergeToolsConfig(profileToolsConfig, this.originalToolsConfig);
|
||||
console.log(`[Agent] reloadTools: mergedToolsConfig =`, JSON.stringify(mergedToolsConfig));
|
||||
this.toolsOptions = mergedToolsConfig
|
||||
? { ...this.toolsOptions, tools: mergedToolsConfig }
|
||||
: this.toolsOptions;
|
||||
|
||||
const tools = resolveTools(this.toolsOptions);
|
||||
console.log(`[Agent] reloadTools: resolved ${tools.length} tools: ${tools.map(t => t.name).join(", ") || "(none)"}`);
|
||||
this.agent.setTools(tools);
|
||||
if (this.debug) {
|
||||
console.error(`[debug] Reloaded ${tools.length} tools: ${tools.map(t => t.name).join(", ") || "(none)"}`);
|
||||
|
|
@ -560,4 +563,37 @@ export class Agent {
|
|||
setUserContent(content: string): void {
|
||||
this.profile?.updateUserContent(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload profile from disk and rebuild system prompt.
|
||||
* Call this after updating profile files to apply changes immediately.
|
||||
*/
|
||||
reloadSystemPrompt(): void {
|
||||
if (!this.profile) {
|
||||
console.log('[Agent] reloadSystemPrompt: no profile');
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload profile from disk
|
||||
console.log('[Agent] Reloading profile from disk...');
|
||||
this.profile.reloadProfile();
|
||||
|
||||
// Rebuild system prompt
|
||||
let systemPrompt = this.profile.buildSystemPrompt();
|
||||
console.log('[Agent] Built system prompt, length:', systemPrompt?.length);
|
||||
|
||||
// Re-add skills prompt if skills are enabled
|
||||
if (this.skillManager) {
|
||||
const skillsPrompt = this.skillManager.buildModelSkillsPrompt();
|
||||
if (skillsPrompt) {
|
||||
systemPrompt = systemPrompt ? `${systemPrompt}\n\n${skillsPrompt}` : skillsPrompt;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply new system prompt
|
||||
if (systemPrompt) {
|
||||
console.log('[Agent] Applying system prompt, first 200 chars:', systemPrompt.substring(0, 200));
|
||||
this.agent.setSystemPrompt(systemPrompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue