@@ -23,6 +23,7 @@ type AgentRuntimeModule = {
2323 lastConversation : Record < string , unknown > | null ;
2424 lastFoundationReadiness : Record < string , unknown > | null ;
2525 lastFailure : Record < string , unknown > | null ;
26+ memoryPolicySummary : Record < string , unknown > ;
2627 pathState : {
2728 visible : boolean ;
2829 fullscreen : boolean ;
@@ -2606,4 +2607,172 @@ describe('agent workspace runtime behavior', () => {
26062607 } )
26072608 ) ;
26082609 } ) ;
2610+
2611+ test ( 'records memory policy diagnostics summary with layer and operation visibility' , async ( ) => {
2612+ const fetchMock = jest
2613+ . fn ( )
2614+ . mockResolvedValueOnce ( {
2615+ ok : true ,
2616+ status : 200 ,
2617+ json : async ( ) => ( {
2618+ success : true ,
2619+ result : {
2620+ userId : 'agent_user_default' ,
2621+ message : 'Found 1 local knowledge point(s).' ,
2622+ knowledgePoints : [
2623+ {
2624+ atomId : 'atom-memory-diagnostics-1' ,
2625+ title : 'Memory Diagnostics Candidate' ,
2626+ snippet : 'Track readonly and mutating memory actions.' ,
2627+ score : 0.82 ,
2628+ capabilities : [
2629+ {
2630+ actionId : 'inspect_long_term_memory_read' ,
2631+ label : 'Long-Term Memory Read' ,
2632+ request : {
2633+ userId : 'agent_user_default' ,
2634+ atomId : 'atom-memory-diagnostics-1' ,
2635+ memoryLayer : 'long_term' ,
2636+ memoryOperation : 'read' ,
2637+ memoryLimit : 8 ,
2638+ memoryQuery : 'durable retrieval' ,
2639+ } ,
2640+ execution : {
2641+ kind : 'knowledge_operation' ,
2642+ operationId : 'apply_memory_policy' ,
2643+ resultPresentation : 'memory_policy_card' ,
2644+ } ,
2645+ } ,
2646+ {
2647+ actionId : 'write_memory_note' ,
2648+ label : 'Store Memory Note' ,
2649+ request : {
2650+ userId : 'agent_user_default' ,
2651+ atomId : 'atom-memory-diagnostics-1' ,
2652+ memoryLayer : 'session' ,
2653+ memoryOperation : 'write' ,
2654+ memoryKey : 'conversation_note:atom-memory-diagnostics-1' ,
2655+ memoryTags : [ 'agent_workspace' , 'conversation_note' ] ,
2656+ memoryReferences : [ 'atom-memory-diagnostics-1' ] ,
2657+ memoryPromptMessage : 'Store note for atom-memory-diagnostics-1' ,
2658+ } ,
2659+ execution : {
2660+ kind : 'knowledge_operation' ,
2661+ operationId : 'apply_memory_policy' ,
2662+ resultPresentation : 'memory_policy_card' ,
2663+ } ,
2664+ } ,
2665+ ] ,
2666+ } ,
2667+ ] ,
2668+ } ,
2669+ } ) ,
2670+ } )
2671+ . mockResolvedValueOnce ( {
2672+ ok : true ,
2673+ status : 200 ,
2674+ json : async ( ) => ( {
2675+ success : true ,
2676+ result : {
2677+ layer : 'long_term' ,
2678+ operation : 'read' ,
2679+ entries : [
2680+ { key : 'memory:lt:1' , value : 'durable retrieval note' } ,
2681+ ] ,
2682+ evictedCount : 0 ,
2683+ stats : {
2684+ session : 2 ,
2685+ unit : 1 ,
2686+ longTerm : 6 ,
2687+ } ,
2688+ } ,
2689+ } ) ,
2690+ } )
2691+ . mockResolvedValueOnce ( {
2692+ ok : true ,
2693+ status : 200 ,
2694+ json : async ( ) => ( {
2695+ success : true ,
2696+ result : {
2697+ layer : 'session' ,
2698+ operation : 'write' ,
2699+ entries : [
2700+ { key : 'conversation_note:atom-memory-diagnostics-1' , value : 'Persist this diagnostic note.' } ,
2701+ ] ,
2702+ evictedCount : 0 ,
2703+ mutatedCount : 1 ,
2704+ stats : {
2705+ session : 3 ,
2706+ unit : 1 ,
2707+ longTerm : 6 ,
2708+ } ,
2709+ } ,
2710+ } ) ,
2711+ } ) ;
2712+ ( global as unknown as Record < string , unknown > ) . fetch = fetchMock ;
2713+ const promptMock = jest . fn ( ) . mockReturnValue ( 'Persist this diagnostic note.' ) ;
2714+ ( global as unknown as Record < string , unknown > ) . prompt = promptMock ;
2715+ ( dom ! . window as unknown as Record < string , unknown > ) . prompt = promptMock ;
2716+
2717+ const runtime = runtimeModule . createAgentWorkspaceRuntime ( { defaultUserId : 'agent_user_default' } ) ;
2718+ runtime . init ( ) ;
2719+
2720+ const input = document . getElementById ( 'agent-workspace-input' ) as HTMLTextAreaElement ;
2721+ const form = document . getElementById ( 'agent-workspace-form' ) as HTMLFormElement ;
2722+ input . value = 'run memory diagnostics' ;
2723+ form . dispatchEvent ( new dom ! . window . Event ( 'submit' , { bubbles : true , cancelable : true } ) ) ;
2724+ await flushAsync ( ) ;
2725+
2726+ const actionButtons = Array . from (
2727+ document . querySelectorAll ( '.agent-workspace-action-button' )
2728+ ) as HTMLButtonElement [ ] ;
2729+ expect ( actionButtons ) . toHaveLength ( 2 ) ;
2730+
2731+ actionButtons [ 0 ] . click ( ) ;
2732+ await flushAsync ( ) ;
2733+ actionButtons [ 1 ] . click ( ) ;
2734+ await flushAsync ( ) ;
2735+
2736+ const snapshot = runtime . getDiagnosticsSnapshot ( ) ;
2737+ expect ( snapshot . memoryPolicySummary ) . toEqual (
2738+ expect . objectContaining ( {
2739+ executionCount : 2 ,
2740+ readonlyExecutions : 1 ,
2741+ mutatingExecutions : 1 ,
2742+ successCount : 2 ,
2743+ failureCount : 0 ,
2744+ byLayer : {
2745+ session : 1 ,
2746+ unit : 0 ,
2747+ long_term : 1 ,
2748+ } ,
2749+ byOperation : {
2750+ read : 1 ,
2751+ snapshot : 0 ,
2752+ retrain_plan : 0 ,
2753+ write : 1 ,
2754+ evict : 0 ,
2755+ } ,
2756+ lastEvent : expect . objectContaining ( {
2757+ memoryLayer : 'session' ,
2758+ memoryOperation : 'write' ,
2759+ status : 'success' ,
2760+ } ) ,
2761+ } )
2762+ ) ;
2763+ expect (
2764+ snapshot . capabilityEvents . some (
2765+ ( event ) => event . memoryLayer === 'long_term' && event . memoryOperation === 'read'
2766+ )
2767+ ) . toBe ( true ) ;
2768+
2769+ const exported = JSON . parse ( runtime . exportDiagnosticsReport ( { format : 'json' } ) as string ) ;
2770+ expect ( exported . snapshot . memoryPolicySummary ) . toEqual (
2771+ expect . objectContaining ( {
2772+ executionCount : 2 ,
2773+ readonlyExecutions : 1 ,
2774+ mutatingExecutions : 1 ,
2775+ } )
2776+ ) ;
2777+ } ) ;
26092778} ) ;
0 commit comments