feat(FN-3321): add agent self-improvement service and heartbeat evaluation

This merge delivers agent self-improvement (FN-3321) — adding evaluation identity tools, wiring evaluation into the heartbeat loop, implementing a self-improvement service, and providing test coverage. It also expands the dashboard guide view with regression tests, adds org chart full-view mode with

Fusion-Task-Id: FN-3321
This commit is contained in:
Fusion
2026-05-05 03:44:01 -07:00
committed by gsxdsm
parent 02a0c48bad
commit 499417bc8e
14 changed files with 667 additions and 16 deletions

View File

@@ -0,0 +1,98 @@
import type { AgentHeartbeatConfig, AgentStore, ReflectionStore } from "@fusion/core";
import { createLogger } from "./logger.js";
const selfImproveLog = createLogger("agent-self-improve");
const DEFAULT_SELF_IMPROVE_INTERVAL_MS = 14_400_000;
const MIN_SELF_IMPROVE_INTERVAL_MS = 3_600_000;
export interface AgentSelfImproveServiceOptions {
agentStore: AgentStore;
reflectionStore: ReflectionStore;
rootDir: string;
}
export class AgentSelfImproveService {
private readonly agentStore: AgentStore;
private readonly reflectionStore: ReflectionStore;
private readonly rootDir: string;
constructor(options: AgentSelfImproveServiceOptions) {
this.agentStore = options.agentStore;
this.reflectionStore = options.reflectionStore;
this.rootDir = options.rootDir;
}
async shouldRunSelfImprove(agentId: string): Promise<boolean> {
void this.reflectionStore;
void this.rootDir;
const agent = await this.agentStore.getAgent(agentId);
if (!agent) {
return false;
}
const runtimeConfig = (agent.runtimeConfig ?? {}) as AgentHeartbeatConfig;
if (runtimeConfig.selfImproveEnabled === false) {
return false;
}
const intervalMs = typeof runtimeConfig.selfImproveIntervalMs === "number" && Number.isFinite(runtimeConfig.selfImproveIntervalMs)
? Math.max(MIN_SELF_IMPROVE_INTERVAL_MS, runtimeConfig.selfImproveIntervalMs)
: DEFAULT_SELF_IMPROVE_INTERVAL_MS;
const lastSelfImproveAt = runtimeConfig.lastSelfImproveAt;
if (!lastSelfImproveAt) {
const summary = await this.agentStore.getRatingSummary(agentId);
return summary.totalRatings > 0;
}
const lastMs = Date.parse(lastSelfImproveAt);
if (!Number.isFinite(lastMs)) {
return true;
}
return Date.now() - lastMs > intervalMs;
}
async getSelfImprovePrompt(agentId: string): Promise<string> {
const agent = await this.agentStore.getAgent(agentId);
const runtimeConfig = (agent?.runtimeConfig ?? {}) as AgentHeartbeatConfig;
const lastSelfImproveAt = runtimeConfig.lastSelfImproveAt ?? "never";
return `## Self-Improvement Phase
It is time for your periodic self-improvement review. Your last self-improvement was at ${lastSelfImproveAt}.
Follow this process:
1. Call fn_read_evaluations to review your ratings, reflections, and feedback.
2. Analyze the data for actionable patterns:
- Declining scores or negative trends
- Recurring error categories
- Repeated negative feedback themes
- Suggestions from reflections you haven't addressed
3. Based on your analysis, call fn_update_identity to update your instructions, soul, or memory:
- Update instructionsText to incorporate new operating procedures or avoid repeated mistakes
- Update soul to refine your personality/behavior based on feedback
- Update memory to record self-improvement observations and commitments
4. Be conservative: only make changes you're confident will improve performance based on concrete evidence.
5. Document your self-improvement decisions concisely.`;
}
async recordSelfImprove(agentId: string): Promise<void> {
const agent = await this.agentStore.getAgent(agentId);
if (!agent) {
return;
}
const existingRuntime = (agent.runtimeConfig ?? {}) as Record<string, unknown>;
await this.agentStore.updateAgent(agentId, {
runtimeConfig: {
...existingRuntime,
lastSelfImproveAt: new Date().toISOString(),
},
});
selfImproveLog.log(`Recorded self-improve checkpoint for ${agentId}`);
}
}