feat(memory): add daily log continuity controls
This commit is contained in:
@@ -481,6 +481,56 @@ describe('AgentOrchestrator', () => {
|
||||
expect(dailyLog).toContain('Log this turn');
|
||||
expect(dailyLog).toContain('default response');
|
||||
expect(dailyLog).toContain('tool_calls: 0');
|
||||
expect(dailyLog).toContain('- session: unknown');
|
||||
expect(dailyLog).toContain('- channel: unknown');
|
||||
expect(dailyLog).toContain('- sender: unknown');
|
||||
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('honors daily log truncation and metadata toggles', async () => {
|
||||
const tempDir = mkdtempSync(join(tmpdir(), 'flynn-orchestrator-daily-log-config-'));
|
||||
const memoryStore = new MemoryStore({ dir: tempDir, maxContextTokens: 2000 });
|
||||
const session: Session = {
|
||||
id: 'ws:test-user',
|
||||
addMessage: vi.fn(),
|
||||
getHistory: vi.fn(() => []),
|
||||
clear: vi.fn(),
|
||||
replaceHistory: vi.fn(),
|
||||
getConfig: vi.fn(() => undefined),
|
||||
setConfig: vi.fn(),
|
||||
deleteConfig: vi.fn(),
|
||||
};
|
||||
|
||||
const orchestrator = new AgentOrchestrator({
|
||||
modelRouter: mockRouter,
|
||||
systemPrompt: 'You are a helpful agent.',
|
||||
primaryTier: 'default',
|
||||
delegation: {
|
||||
compaction: 'fast',
|
||||
memory_extraction: 'default',
|
||||
classification: 'complex',
|
||||
tool_summarisation: 'default',
|
||||
complex_reasoning: 'complex',
|
||||
},
|
||||
maxDelegationDepth: 10,
|
||||
session,
|
||||
memoryStore,
|
||||
memoryDailyLogEnabled: true,
|
||||
memoryDailyLogNamespacePrefix: 'daily',
|
||||
memoryDailyLogIncludeSessionMetadata: false,
|
||||
memoryDailyLogMaxUserChars: 120,
|
||||
memoryDailyLogMaxAssistantChars: 150,
|
||||
});
|
||||
|
||||
await orchestrator.process('x'.repeat(500));
|
||||
const date = new Date().toISOString().slice(0, 10);
|
||||
const dailyLog = memoryStore.read(`daily/${date}`);
|
||||
|
||||
expect(dailyLog).toContain('...[truncated]');
|
||||
expect(dailyLog).not.toContain('- session:');
|
||||
expect(dailyLog).not.toContain('- channel:');
|
||||
expect(dailyLog).not.toContain('- sender:');
|
||||
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
@@ -140,6 +140,12 @@ export interface OrchestratorConfig {
|
||||
memoryDailyLogEnabled?: boolean;
|
||||
/** Namespace prefix for daily logs (full namespace: <prefix>/YYYY-MM-DD). */
|
||||
memoryDailyLogNamespacePrefix?: string;
|
||||
/** Include session/channel/sender metadata in each daily log block. */
|
||||
memoryDailyLogIncludeSessionMetadata?: boolean;
|
||||
/** Max chars stored from the user message in daily logs. */
|
||||
memoryDailyLogMaxUserChars?: number;
|
||||
/** Max chars stored from the assistant response in daily logs. */
|
||||
memoryDailyLogMaxAssistantChars?: number;
|
||||
/** Automatically retry failed primary runs on a higher tier. */
|
||||
autoEscalate?: boolean;
|
||||
/** Tier to try for auto-escalation retries. Defaults to complex. */
|
||||
@@ -184,6 +190,9 @@ export class AgentOrchestrator {
|
||||
private _memoryProactiveExtractNamespace: string;
|
||||
private _memoryDailyLogEnabled: boolean;
|
||||
private _memoryDailyLogNamespacePrefix: string;
|
||||
private _memoryDailyLogIncludeSessionMetadata: boolean;
|
||||
private _memoryDailyLogMaxUserChars: number;
|
||||
private _memoryDailyLogMaxAssistantChars: number;
|
||||
private _autoEscalate: boolean;
|
||||
private _autoEscalateTier: ModelTier;
|
||||
private _systemPromptBase: string;
|
||||
@@ -213,6 +222,9 @@ export class AgentOrchestrator {
|
||||
this._memoryProactiveExtractNamespace = config.memoryProactiveExtractNamespace ?? 'global';
|
||||
this._memoryDailyLogEnabled = config.memoryDailyLogEnabled ?? false;
|
||||
this._memoryDailyLogNamespacePrefix = config.memoryDailyLogNamespacePrefix ?? 'daily';
|
||||
this._memoryDailyLogIncludeSessionMetadata = config.memoryDailyLogIncludeSessionMetadata ?? true;
|
||||
this._memoryDailyLogMaxUserChars = Math.max(100, config.memoryDailyLogMaxUserChars ?? 2000);
|
||||
this._memoryDailyLogMaxAssistantChars = Math.max(100, config.memoryDailyLogMaxAssistantChars ?? 4000);
|
||||
this._autoEscalate = config.autoEscalate ?? false;
|
||||
this._autoEscalateTier = config.autoEscalateTier ?? 'complex';
|
||||
this._systemPromptBase = config.systemPrompt;
|
||||
@@ -705,12 +717,20 @@ export class AgentOrchestrator {
|
||||
const date = new Date().toISOString().slice(0, 10);
|
||||
const timestamp = new Date().toISOString();
|
||||
const namespace = `${this._memoryDailyLogNamespacePrefix}/${date}`;
|
||||
const user = this._truncateForMemory(userMessage, 2000);
|
||||
const assistant = this._truncateForMemory(assistantText, 4000);
|
||||
const user = this._truncateForMemory(userMessage, this._memoryDailyLogMaxUserChars);
|
||||
const assistant = this._truncateForMemory(assistantText, this._memoryDailyLogMaxAssistantChars);
|
||||
const metadataLines = this._memoryDailyLogIncludeSessionMetadata
|
||||
? [
|
||||
`- session: ${this._session?.id ?? 'unknown'}`,
|
||||
`- channel: ${this._agent.getToolPolicyContext()?.channel ?? 'unknown'}`,
|
||||
`- sender: ${this._agent.getToolPolicyContext()?.sender ?? 'unknown'}`,
|
||||
]
|
||||
: [];
|
||||
const block = [
|
||||
`## ${timestamp}`,
|
||||
'',
|
||||
`- tool_calls: ${toolCallsInRun}`,
|
||||
...metadataLines,
|
||||
'',
|
||||
'### User',
|
||||
user,
|
||||
|
||||
Reference in New Issue
Block a user