mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-30 16:26:59 +02:00
refactor(agents): rename memory profile blocks
This commit is contained in:
parent
8e0a28dd5b
commit
a85e07743e
|
|
@ -544,7 +544,7 @@ describe('AgentRuntime — memory profiles', () => {
|
|||
streamText.mockReset();
|
||||
});
|
||||
|
||||
it('loads persona and user profiles into the system prompt', async () => {
|
||||
it('loads agent and user profiles into the system prompt', async () => {
|
||||
const memory = new InMemoryMemory();
|
||||
await memory.saveMemoryProfile(
|
||||
{ scopeKind: 'agent', scopeId: 'agent-1' },
|
||||
|
|
@ -573,7 +573,7 @@ describe('AgentRuntime — memory profiles', () => {
|
|||
expect(prompt).toContain('<memory_blocks>');
|
||||
expect(prompt).toContain('When debugging, ask for the exact version before suggesting fixes.');
|
||||
expect(prompt).toContain('The user prefers concise answers.');
|
||||
expect(prompt.indexOf('<persona>')).toBeLessThan(prompt.indexOf('<user>'));
|
||||
expect(prompt.indexOf('<agent-profile>')).toBeLessThan(prompt.indexOf('<user-profile>'));
|
||||
expect(prompt).not.toContain('<memory>');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -46,18 +46,17 @@ describe('memory profiles', () => {
|
|||
const prompt = DEFAULT_MEMORY_PROFILE_UPDATE_PROMPT;
|
||||
|
||||
for (const phrase of [
|
||||
'User profile captures stable cross-session information',
|
||||
'<user> is not task memory',
|
||||
'User-profile captures stable cross-session information',
|
||||
'<user-profile> is not task memory',
|
||||
'must never be connected to the current objective of an agent',
|
||||
'communication preferences',
|
||||
'durable workflow preferences',
|
||||
'stable preferences about communication style, workflow, tools, environment, ownership, or domain context',
|
||||
'User-profile may include durable user preferences',
|
||||
'If the information would stop being useful after the current task ends',
|
||||
'belongs in <persona>',
|
||||
'does not belong in <user>',
|
||||
'describes the agent',
|
||||
'does not belong in <user-profile>',
|
||||
'Existing profile content is not authoritative',
|
||||
'Persona captures actionable behavioral directives',
|
||||
'imperative system-instruction-style directives',
|
||||
'concrete future behavior change',
|
||||
'Agent-profile captures durable facts about the agent',
|
||||
'durable persona or operating mode',
|
||||
]) {
|
||||
expect(prompt).toContain(phrase);
|
||||
}
|
||||
|
|
@ -71,7 +70,6 @@ describe('memory profiles', () => {
|
|||
'next actions',
|
||||
'temporary constraints',
|
||||
'session objectives',
|
||||
'descriptive agent facts',
|
||||
'storage/data-model facts',
|
||||
'model names',
|
||||
'schema facts',
|
||||
|
|
@ -86,9 +84,9 @@ describe('memory profiles', () => {
|
|||
it('updates memory profiles from the profile updater path', async () => {
|
||||
generateText.mockResolvedValueOnce({
|
||||
text: JSON.stringify({
|
||||
persona:
|
||||
agentProfile:
|
||||
'When discussing memory architecture, distinguish durable profile state from session objective state.',
|
||||
user: 'The user prefers concise updates.',
|
||||
userProfile: 'The user prefers concise updates.',
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
@ -122,7 +120,7 @@ describe('memory profiles', () => {
|
|||
});
|
||||
expect(generateText).toHaveBeenCalledTimes(1);
|
||||
expect(generateText.mock.calls[0][0].system).toContain(
|
||||
'Persona captures actionable behavioral directives',
|
||||
'Agent-profile captures durable facts about the agent',
|
||||
);
|
||||
expect(generateText.mock.calls[0][0].system).toContain(
|
||||
'Assistant messages are supporting context',
|
||||
|
|
@ -144,9 +142,9 @@ describe('memory profiles', () => {
|
|||
it('updates memory profiles from the turn pair even when no entries are accepted', async () => {
|
||||
generateText.mockResolvedValueOnce({
|
||||
text: JSON.stringify({
|
||||
persona:
|
||||
agentProfile:
|
||||
'When users describe technical issues, ask for the specific n8n version before suggesting fixes.',
|
||||
user: 'The user prefers responses without business framing or em dashes.',
|
||||
userProfile: 'The user prefers responses without business framing or em dashes.',
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
@ -197,7 +195,7 @@ describe('memory profiles', () => {
|
|||
).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it('loads resource profiles shared across agents and persona profiles scoped to one agent', async () => {
|
||||
it('loads resource profiles shared across agents and agent profiles scoped to one agent', async () => {
|
||||
const memory = new InMemoryMemory();
|
||||
await memory.saveMemoryProfile(
|
||||
{ scopeKind: 'resource', scopeId: 'user-1' },
|
||||
|
|
@ -222,12 +220,12 @@ describe('memory profiles', () => {
|
|||
});
|
||||
|
||||
expect(agentOne).toEqual({
|
||||
persona: 'This agent handles memory debugging.',
|
||||
user: 'The user prefers concise answers.',
|
||||
agentProfile: 'This agent handles memory debugging.',
|
||||
userProfile: 'The user prefers concise answers.',
|
||||
});
|
||||
expect(agentTwo).toEqual({
|
||||
persona: 'This other agent handles invoices.',
|
||||
user: 'The user prefers concise answers.',
|
||||
agentProfile: 'This other agent handles invoices.',
|
||||
userProfile: 'The user prefers concise answers.',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -166,11 +166,11 @@ describe('AgentMessageList — forLlm working memory', () => {
|
|||
expect(prompt).not.toContain('Current template');
|
||||
});
|
||||
|
||||
it('renders persona, user, and session memory inside memory_blocks', () => {
|
||||
it('renders agent profile, user profile, and session memory inside memory_blocks', () => {
|
||||
const list = new AgentMessageList();
|
||||
list.memoryProfile = {
|
||||
persona: 'This agent specializes in n8n memory work.',
|
||||
user: 'The user prefers concise answers.',
|
||||
agentProfile: 'This agent specializes in n8n memory work.',
|
||||
userProfile: 'The user prefers concise answers.',
|
||||
};
|
||||
list.workingMemory = {
|
||||
template: '# Thread memory',
|
||||
|
|
@ -183,28 +183,28 @@ describe('AgentMessageList — forLlm working memory', () => {
|
|||
expect(prompt).toContain('<memory_blocks>');
|
||||
expect(prompt).toContain(
|
||||
[
|
||||
'<persona>',
|
||||
'<description>Durable behavior rules this agent should follow with this user.</description>',
|
||||
'<agent-profile>',
|
||||
'<description>Durable persona, role, and operating style for this agent.</description>',
|
||||
'<value>',
|
||||
'This agent specializes in n8n memory work.',
|
||||
'</value>',
|
||||
'</persona>',
|
||||
'</agent-profile>',
|
||||
].join('\n'),
|
||||
);
|
||||
expect(prompt).toContain(
|
||||
[
|
||||
'<user>',
|
||||
'<description>Stable user preferences and context shared across agents.</description>',
|
||||
'<user-profile>',
|
||||
'<description>Stable facts and preferences about the user or resource.</description>',
|
||||
'<value>',
|
||||
'The user prefers concise answers.',
|
||||
'</value>',
|
||||
'</user>',
|
||||
'</user-profile>',
|
||||
].join('\n'),
|
||||
);
|
||||
expect(prompt).toContain('<session-memory>');
|
||||
expect(prompt).toContain('Current objective: verify prompt sections.');
|
||||
expect(prompt.indexOf('<persona>')).toBeLessThan(prompt.indexOf('<user>'));
|
||||
expect(prompt.indexOf('<user>')).toBeLessThan(prompt.indexOf('<session-memory>'));
|
||||
expect(prompt.indexOf('<agent-profile>')).toBeLessThan(prompt.indexOf('<user-profile>'));
|
||||
expect(prompt.indexOf('<user-profile>')).toBeLessThan(prompt.indexOf('<session-memory>'));
|
||||
expect(prompt).not.toContain('<memory>');
|
||||
});
|
||||
|
||||
|
|
@ -306,13 +306,13 @@ describe('AgentMessageList — deserialize', () => {
|
|||
|
||||
it('preserves injected profile context across serialization', () => {
|
||||
const list = new AgentMessageList();
|
||||
list.memoryProfile = { persona: 'Agent profile.', user: 'Resource profile.' };
|
||||
list.memoryProfile = { agentProfile: 'Agent profile.', userProfile: 'Resource profile.' };
|
||||
|
||||
const restored = AgentMessageList.deserialize(list.serialize());
|
||||
|
||||
expect(restored.memoryProfile).toEqual({
|
||||
persona: 'Agent profile.',
|
||||
user: 'Resource profile.',
|
||||
agentProfile: 'Agent profile.',
|
||||
userProfile: 'Resource profile.',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -368,8 +368,8 @@ describe('runObservationalCycle', () => {
|
|||
opts(mem, {
|
||||
observe: undefined,
|
||||
memoryProfile: {
|
||||
persona: 'This agent specializes in memory debugging.',
|
||||
user: 'The user prefers concise answers.',
|
||||
agentProfile: 'This agent specializes in memory debugging.',
|
||||
userProfile: 'The user prefers concise answers.',
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
|
@ -377,9 +377,11 @@ describe('runObservationalCycle', () => {
|
|||
const call = mockGenerateText.mock.calls[0][0];
|
||||
expect(call.prompt).toContain('Known durable profiles');
|
||||
expect(call.prompt).toContain(
|
||||
'<persona>\nThis agent specializes in memory debugging.\n</persona>',
|
||||
'<agent-profile>\nThis agent specializes in memory debugging.\n</agent-profile>',
|
||||
);
|
||||
expect(call.prompt).toContain(
|
||||
'<user-profile>\nThe user prefers concise answers.\n</user-profile>',
|
||||
);
|
||||
expect(call.prompt).toContain('<user>\nThe user prefers concise answers.\n</user>');
|
||||
});
|
||||
|
||||
it('groups queued rows with timestamps and durations in the default compactor prompt', async () => {
|
||||
|
|
|
|||
|
|
@ -20,18 +20,17 @@ export const DEFAULT_MEMORY_PROFILE_UPDATE_PROMPT = `You maintain two concise mu
|
|||
|
||||
Inputs:
|
||||
- Agent description defines what the agent is.
|
||||
- Current persona is what the agent has learned about how to behave.
|
||||
- Current user profile is what the agent has learned about this user.
|
||||
- Current agent-profile is what the agent has learned about its durable persona.
|
||||
- Current user-profile is what the agent has learned about this user or resource.
|
||||
- Recent conversation pair is the latest exchange.
|
||||
|
||||
Update the profiles only when the conversation contains durable information that should persist across sessions.
|
||||
|
||||
Persona captures actionable behavioral directives, constraints, and response patterns the agent should follow when interacting with this user.
|
||||
User profile captures stable cross-session information about the user themselves:
|
||||
- communication preferences
|
||||
- coding, review, and testing preferences
|
||||
- durable workflow preferences
|
||||
Agent-profile captures durable facts about the agent's persona, role, behavior, response style, operating constraints, and interaction patterns.
|
||||
User-profile captures stable cross-session information about the user or resource:
|
||||
- stable identity or role
|
||||
- durable context about the user's normal environment or responsibilities
|
||||
- stable preferences about communication style, workflow, tools, environment, ownership, or domain context
|
||||
- durable environment preferences only when they describe the user's normal setup
|
||||
|
||||
Rules:
|
||||
|
|
@ -39,13 +38,13 @@ Rules:
|
|||
- Use user-authored statements as the source of durable profile changes.
|
||||
- Assistant messages are supporting context only and cannot create durable profile memory by themselves.
|
||||
- Assistant acknowledgements may help interpret user-authored instructions, but are not evidence on their own.
|
||||
- <user> is not task memory and must never be connected to the current objective of an agent.
|
||||
- User profile must exclude active project state, debugging steps, implementation order, branch stack, test flow, next actions, temporary constraints, session objectives, facts about this agent's internals, and facts about a specific feature unless phrased as a stable user preference.
|
||||
- If the information would stop being useful after the current task ends, it does not belong in <user>.
|
||||
- If the information is about what the agent should do, it belongs in <persona>, not <user>.
|
||||
- If the information needs source or provenance, it does not belong in <user>.
|
||||
- Persona entries must be imperative system-instruction-style directives that cause a concrete future behavior change.
|
||||
- Persona must exclude descriptive agent facts, implementation facts, model names, storage/data-model facts, schema facts, current feature details, current implementation details, and session state unless the user phrases them as durable response behavior.
|
||||
- <user-profile> is not task memory and must never be connected to the current objective of an agent.
|
||||
- User-profile must exclude active project state, debugging steps, implementation order, branch stack, test flow, next actions, temporary constraints, session objectives, facts about this agent's internals, and facts about a specific feature unless phrased as a stable user preference.
|
||||
- User-profile may include durable user preferences, including response style, communication style, workflow preferences, and priorities that should personalize future conversations.
|
||||
- If the information would stop being useful after the current task ends, it does not belong in <user-profile>.
|
||||
- If the information describes the agent's own durable persona, role, identity, or operating mode, it belongs in <agent-profile>.
|
||||
- If the information needs source or provenance, it does not belong in <user-profile>.
|
||||
- Agent-profile may include descriptive persona facts and durable operating rules, but must exclude implementation facts, model names, storage/data-model facts, schema facts, current feature details, current implementation details, and session state unless they define the configured agent's durable persona or operating mode.
|
||||
- Existing profile content is not authoritative. Rewrite profiles to remove entries that violate these rules, even if no new durable information is present.
|
||||
- Do not summarize the conversation.
|
||||
- Do not add situational or one-task-only details.
|
||||
|
|
@ -53,7 +52,7 @@ Rules:
|
|||
- If a profile needs no update or cleanup, return the existing profile content exactly.
|
||||
|
||||
Return only JSON in this exact shape:
|
||||
{"persona":"...","user":"..."}`;
|
||||
{"agentProfile":"...","userProfile":"..."}`;
|
||||
|
||||
interface NormalizedMemoryProfilesConfig {
|
||||
profileUpdatePrompt: string;
|
||||
|
|
@ -123,8 +122,8 @@ export async function updateMemoryProfilesFromTurn(opts: {
|
|||
system: normalized.profileUpdatePrompt,
|
||||
prompt: renderMemoryProfileUpdatePrompt({
|
||||
agentDescription: normalized.agentDescription,
|
||||
persona: current?.persona ?? '',
|
||||
user: current?.user ?? '',
|
||||
agentProfile: current?.agentProfile ?? '',
|
||||
userProfile: current?.userProfile ?? '',
|
||||
turn,
|
||||
}),
|
||||
});
|
||||
|
|
@ -135,14 +134,14 @@ export async function updateMemoryProfilesFromTurn(opts: {
|
|||
await saveProfileIfChanged({
|
||||
memory: opts.memory,
|
||||
scope: agentMemoryProfileScope(opts.scope.agentId),
|
||||
current: current?.persona ?? '',
|
||||
next: parsed.persona,
|
||||
current: current?.agentProfile ?? '',
|
||||
next: parsed.agentProfile,
|
||||
});
|
||||
await saveProfileIfChanged({
|
||||
memory: opts.memory,
|
||||
scope: resourceMemoryProfileScope(opts.scope.resourceId),
|
||||
current: current?.user ?? '',
|
||||
next: parsed.user,
|
||||
current: current?.userProfile ?? '',
|
||||
next: parsed.userProfile,
|
||||
});
|
||||
} catch (error) {
|
||||
opts.eventBus.emit({
|
||||
|
|
@ -159,7 +158,7 @@ async function loadMemoryProfiles(
|
|||
agentId: string | undefined,
|
||||
resourceId: string | undefined,
|
||||
): Promise<SerializedMessageList['memoryProfile'] | undefined> {
|
||||
const [persona, user] = await Promise.all([
|
||||
const [agentProfile, userProfile] = await Promise.all([
|
||||
agentId ? memory.getMemoryProfile(agentMemoryProfileScope(agentId)) : Promise.resolve(null),
|
||||
resourceId
|
||||
? memory.getMemoryProfile(resourceMemoryProfileScope(resourceId))
|
||||
|
|
@ -167,16 +166,16 @@ async function loadMemoryProfiles(
|
|||
]);
|
||||
|
||||
const context = {
|
||||
persona: persona?.content ?? null,
|
||||
user: user?.content ?? null,
|
||||
agentProfile: agentProfile?.content ?? null,
|
||||
userProfile: userProfile?.content ?? null,
|
||||
};
|
||||
return context.persona || context.user ? context : undefined;
|
||||
return context.agentProfile || context.userProfile ? context : undefined;
|
||||
}
|
||||
|
||||
function renderMemoryProfileUpdatePrompt(ctx: {
|
||||
agentDescription?: string;
|
||||
persona: string;
|
||||
user: string;
|
||||
agentProfile: string;
|
||||
userProfile: string;
|
||||
turn: ProfileUpdateTurn;
|
||||
}): string {
|
||||
const agentDescription = ctx.agentDescription?.trim();
|
||||
|
|
@ -184,13 +183,13 @@ function renderMemoryProfileUpdatePrompt(ctx: {
|
|||
...(agentDescription
|
||||
? ['<agent-description>', agentDescription, '</agent-description>', '']
|
||||
: []),
|
||||
'<persona>',
|
||||
ctx.persona.trim(),
|
||||
'</persona>',
|
||||
'<agent-profile>',
|
||||
ctx.agentProfile.trim(),
|
||||
'</agent-profile>',
|
||||
'',
|
||||
'<user>',
|
||||
ctx.user.trim(),
|
||||
'</user>',
|
||||
'<user-profile>',
|
||||
ctx.userProfile.trim(),
|
||||
'</user-profile>',
|
||||
'',
|
||||
'<turn>',
|
||||
'<user-message>',
|
||||
|
|
@ -204,13 +203,13 @@ function renderMemoryProfileUpdatePrompt(ctx: {
|
|||
].join('\n');
|
||||
}
|
||||
|
||||
function parseProfileUpdate(text: string): { persona: string; user: string } | null {
|
||||
function parseProfileUpdate(text: string): { agentProfile: string; userProfile: string } | null {
|
||||
const parsed = parseJsonObject(stripMarkdownFence(text));
|
||||
if (!isRecord(parsed)) return null;
|
||||
const persona = parsed.persona;
|
||||
const user = parsed.user;
|
||||
if (typeof persona !== 'string' || typeof user !== 'string') return null;
|
||||
return { persona: persona.trim(), user: user.trim() };
|
||||
const agentProfile = parsed.agentProfile;
|
||||
const userProfile = parsed.userProfile;
|
||||
if (typeof agentProfile !== 'string' || typeof userProfile !== 'string') return null;
|
||||
return { agentProfile: agentProfile.trim(), userProfile: userProfile.trim() };
|
||||
}
|
||||
|
||||
async function saveProfileIfChanged(opts: {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ export interface WorkingMemoryContext {
|
|||
}
|
||||
|
||||
export interface MemoryProfileContext {
|
||||
persona?: string | null;
|
||||
user?: string | null;
|
||||
agentProfile?: string | null;
|
||||
userProfile?: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -223,30 +223,30 @@ export class AgentMessageList {
|
|||
let systemPrompt = baseInstructions;
|
||||
const memoryBlocks: string[] = [];
|
||||
|
||||
const persona = this.memoryProfile?.persona?.trim();
|
||||
if (persona) {
|
||||
const agentProfile = this.memoryProfile?.agentProfile?.trim();
|
||||
if (agentProfile) {
|
||||
memoryBlocks.push(
|
||||
[
|
||||
'<persona>',
|
||||
'<description>Durable behavior rules this agent should follow with this user.</description>',
|
||||
'<agent-profile>',
|
||||
'<description>Durable persona, role, and operating style for this agent.</description>',
|
||||
'<value>',
|
||||
persona,
|
||||
agentProfile,
|
||||
'</value>',
|
||||
'</persona>',
|
||||
'</agent-profile>',
|
||||
].join('\n'),
|
||||
);
|
||||
}
|
||||
|
||||
const user = this.memoryProfile?.user?.trim();
|
||||
if (user) {
|
||||
const userProfile = this.memoryProfile?.userProfile?.trim();
|
||||
if (userProfile) {
|
||||
memoryBlocks.push(
|
||||
[
|
||||
'<user>',
|
||||
'<description>Stable user preferences and context shared across agents.</description>',
|
||||
'<user-profile>',
|
||||
'<description>Stable facts and preferences about the user or resource.</description>',
|
||||
'<value>',
|
||||
user,
|
||||
userProfile,
|
||||
'</value>',
|
||||
'</user>',
|
||||
'</user-profile>',
|
||||
].join('\n'),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Evidence rules:
|
|||
- Transcript roles matter. User messages are authoritative for requested work,
|
||||
current-session goals, constraints, corrections, and decisions.
|
||||
- Assistant messages are supporting context only. A normal assistant reply is not verification evidence.
|
||||
- Known persona and resource/user profiles are durable memory. Do not copy them
|
||||
- Known agent and resource/user profiles are durable memory. Do not copy them
|
||||
into thread working memory unless the live transcript adds session-specific
|
||||
objective or task state.
|
||||
- Do not record assistant-created checklists, diagnostic questions, file/table
|
||||
|
|
@ -65,9 +65,9 @@ Evidence rules:
|
|||
Rules:
|
||||
- Prefer explicit session state over broad durable profile facts.
|
||||
- Do not record stable user identity, general communication style, long-lived
|
||||
user preferences, or durable agent/persona facts as thread working memory.
|
||||
user-profile preferences, or durable agent-profile content as thread working memory.
|
||||
- Do not record general user preferences, repo-wide habits, style preferences,
|
||||
or persona facts as session memory.
|
||||
or agent-profile content as session memory.
|
||||
- If a durable preference is relevant to the active objective:
|
||||
record only the objective-specific application, not the durable preference itself. For example:
|
||||
"For this task, do not run evals" instead of "User never wants evals run".
|
||||
|
|
@ -109,7 +109,7 @@ Rules:
|
|||
objective-specific constraints, objective-specific uncertainties, task state,
|
||||
concrete progress, active items, and open follow-ups.
|
||||
- Remove stable user identity, general communication style, durable preferences,
|
||||
and agent/persona facts unless they are needed as session-specific task state.
|
||||
and agent-profile content unless they are needed as session-specific task state.
|
||||
- When durable preferences are relevant to this thread:
|
||||
rewrite broad durable preferences into objective-specific constraints instead of copying them. For example:
|
||||
"For this task, do not run evals" instead of
|
||||
|
|
@ -325,14 +325,14 @@ export function buildDefaultObserveFn(model: ModelConfig, observerPrompt?: strin
|
|||
function renderMemoryProfileContext(
|
||||
memoryProfile: SerializedMessageList['memoryProfile'] | undefined,
|
||||
): string {
|
||||
const persona = memoryProfile?.persona?.trim();
|
||||
const user = memoryProfile?.user?.trim();
|
||||
if (!persona && !user) return '';
|
||||
const agentProfile = memoryProfile?.agentProfile?.trim();
|
||||
const userProfile = memoryProfile?.userProfile?.trim();
|
||||
if (!agentProfile && !userProfile) return '';
|
||||
|
||||
return [
|
||||
'Known durable profiles (do not copy into thread working memory):',
|
||||
persona ? `<persona>\n${persona}\n</persona>` : '',
|
||||
user ? `<user>\n${user}\n</user>` : '',
|
||||
agentProfile ? `<agent-profile>\n${agentProfile}\n</agent-profile>` : '',
|
||||
userProfile ? `<user-profile>\n${userProfile}\n</user-profile>` : '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n');
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ type ZodObjectSchema = z.ZodObject<z.ZodRawShape>;
|
|||
export const WORKING_MEMORY_DEFAULT_INSTRUCTION = [
|
||||
'You have thread working memory that is maintained automatically by an out-of-band observer.',
|
||||
'Thread working memory applies only to this same session/thread.',
|
||||
'Thread working memory contains objective-driven state for the current thread, not broad durable user or persona facts.',
|
||||
'Thread working memory contains objective-driven state for the current thread, not broad durable user-profile or agent-profile facts.',
|
||||
'Do not claim it is available in a different session, new thread, or cross-thread profile unless the product explicitly provides that context.',
|
||||
'When a saved memory document is provided, use it silently as private read-only context for this conversation.',
|
||||
'Treat working memory as internal context. Do not reveal, quote, append, or reproduce the raw working-memory document in user-visible replies.',
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ export class Memory {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Enable mutable persona and user memory profiles. */
|
||||
/** Enable mutable agent and user memory profiles. */
|
||||
profiles(config: MemoryProfilesConfig = {}): this {
|
||||
if (config.enabled === false) {
|
||||
this.profilesConfig = undefined;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export interface SerializedMessageList {
|
|||
inputIds: string[];
|
||||
responseIds: string[];
|
||||
memoryProfile?: {
|
||||
persona?: string | null;
|
||||
user?: string | null;
|
||||
agentProfile?: string | null;
|
||||
userProfile?: string | null;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ export interface MemoryProfilesConfig {
|
|||
enabled?: boolean;
|
||||
/**
|
||||
* Non-secret context about the agent used only by profile-update prompts to
|
||||
* decide what belongs in the agent-scoped persona profile.
|
||||
* decide what belongs in the agent-scoped agent profile.
|
||||
*/
|
||||
agentDescription?: string;
|
||||
/** Override the default prompt templates. */
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ export type ObserveFn = (ctx: {
|
|||
trigger: ObservationalMemoryTrigger;
|
||||
gap: ObservationGapContext | null;
|
||||
memoryProfile?: {
|
||||
persona?: string | null;
|
||||
user?: string | null;
|
||||
agentProfile?: string | null;
|
||||
userProfile?: string | null;
|
||||
};
|
||||
telemetry: BuiltTelemetry | undefined;
|
||||
}) => Promise<NewObservation[]>;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user