feat(agent): add profile system and improve tools
- Add Agent Profile module for managing agent identity, soul, tools, memory, and bootstrap configuration - Add profile CLI (pnpm agent:profile) for creating/listing/showing profiles - Default sessionId to UUIDv7 instead of "default" - Expose Agent.sessionId as public readonly property - Improve exec/process tools error handling (no more crashes on spawn errors) - Add 'output' action to process tool for reading stdout/stderr - Better tool descriptions to guide agent in choosing exec vs process Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
46a6cb3061
commit
200b2cefda
15 changed files with 740 additions and 58 deletions
155
src/agent/profile/index.ts
Normal file
155
src/agent/profile/index.ts
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* Agent Profile 模块
|
||||
*
|
||||
* 管理 agent 的身份、人格、记忆等配置
|
||||
*/
|
||||
|
||||
import type { AgentProfile, CreateProfileOptions, ProfileManagerOptions } from "./types.js";
|
||||
import { DEFAULT_TEMPLATES } from "./templates.js";
|
||||
import {
|
||||
ensureProfileDir,
|
||||
getProfileDir,
|
||||
loadProfile,
|
||||
profileExists,
|
||||
saveProfile,
|
||||
} from "./storage.js";
|
||||
|
||||
export { type AgentProfile, type CreateProfileOptions, type ProfileManagerOptions } from "./types.js";
|
||||
export { DEFAULT_TEMPLATES } from "./templates.js";
|
||||
export { getProfileDir, profileExists } from "./storage.js";
|
||||
|
||||
/**
|
||||
* 创建新的 Agent Profile
|
||||
*
|
||||
* @param profileId - Profile ID
|
||||
* @param options - 创建选项
|
||||
* @returns 创建的 AgentProfile
|
||||
*/
|
||||
export function createAgentProfile(
|
||||
profileId: string,
|
||||
options?: CreateProfileOptions,
|
||||
): AgentProfile {
|
||||
const { baseDir, useTemplates = true } = options ?? {};
|
||||
|
||||
// 确保目录存在
|
||||
ensureProfileDir(profileId, { baseDir });
|
||||
|
||||
// 创建 profile
|
||||
const profile: AgentProfile = {
|
||||
id: profileId,
|
||||
};
|
||||
|
||||
// 如果使用模板,填充默认内容
|
||||
if (useTemplates) {
|
||||
profile.soul = DEFAULT_TEMPLATES.soul;
|
||||
profile.identity = DEFAULT_TEMPLATES.identity;
|
||||
profile.tools = DEFAULT_TEMPLATES.tools;
|
||||
profile.memory = DEFAULT_TEMPLATES.memory;
|
||||
profile.bootstrap = DEFAULT_TEMPLATES.bootstrap;
|
||||
|
||||
// 保存到文件
|
||||
saveProfile(profile, { baseDir });
|
||||
}
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载 Agent Profile
|
||||
*
|
||||
* @param profileId - Profile ID
|
||||
* @param options - 加载选项
|
||||
* @returns AgentProfile,如果不存在返回 undefined
|
||||
*/
|
||||
export function loadAgentProfile(
|
||||
profileId: string,
|
||||
options?: { baseDir?: string | undefined },
|
||||
): AgentProfile | undefined {
|
||||
if (!profileExists(profileId, options)) {
|
||||
return undefined;
|
||||
}
|
||||
return loadProfile(profileId, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载或创建 Agent Profile
|
||||
*
|
||||
* @param profileId - Profile ID
|
||||
* @param options - 选项
|
||||
* @returns AgentProfile
|
||||
*/
|
||||
export function getOrCreateAgentProfile(
|
||||
profileId: string,
|
||||
options?: CreateProfileOptions,
|
||||
): AgentProfile {
|
||||
const existing = loadAgentProfile(profileId, options);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
return createAgentProfile(profileId, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile Manager - 用于管理单个 profile 的类
|
||||
*/
|
||||
export class ProfileManager {
|
||||
private readonly profileId: string;
|
||||
private readonly baseDir: string | undefined;
|
||||
private profile: AgentProfile | undefined;
|
||||
|
||||
constructor(options: ProfileManagerOptions) {
|
||||
this.profileId = options.profileId;
|
||||
this.baseDir = options.baseDir;
|
||||
}
|
||||
|
||||
/** 获取 profile,如果未加载则加载 */
|
||||
getProfile(): AgentProfile | undefined {
|
||||
if (!this.profile) {
|
||||
this.profile = loadAgentProfile(this.profileId, { baseDir: this.baseDir });
|
||||
}
|
||||
return this.profile;
|
||||
}
|
||||
|
||||
/** 获取或创建 profile */
|
||||
getOrCreateProfile(useTemplates = true): AgentProfile {
|
||||
if (!this.profile) {
|
||||
this.profile = getOrCreateAgentProfile(this.profileId, {
|
||||
baseDir: this.baseDir,
|
||||
useTemplates,
|
||||
});
|
||||
}
|
||||
return this.profile;
|
||||
}
|
||||
|
||||
/** 构建 system prompt */
|
||||
buildSystemPrompt(): string {
|
||||
const profile = this.getProfile();
|
||||
if (!profile) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const parts: string[] = [];
|
||||
|
||||
if (profile.identity) {
|
||||
parts.push(profile.identity);
|
||||
}
|
||||
|
||||
if (profile.soul) {
|
||||
parts.push(profile.soul);
|
||||
}
|
||||
|
||||
if (profile.tools) {
|
||||
parts.push(profile.tools);
|
||||
}
|
||||
|
||||
if (profile.memory) {
|
||||
parts.push(profile.memory);
|
||||
}
|
||||
|
||||
if (profile.bootstrap) {
|
||||
parts.push(profile.bootstrap);
|
||||
}
|
||||
|
||||
return parts.join("\n\n");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue