@@ -11,6 +11,7 @@ const createSessionGoalMock = vi.fn();
1111const clearSessionGoalMock = vi . fn ( ) ;
1212const getSessionGoalMock = vi . fn ( ) ;
1313const updateSessionGoalStatusMock = vi . fn ( ) ;
14+ const ensureRuntimePluginsLoadedMock = vi . fn ( ) ;
1415const listSessionsFromStoreAsyncMock = vi . fn (
1516 async ( _options ?: unknown ) : Promise < { sessions : unknown [ ] } > => ( { sessions : [ ] } ) ,
1617) ;
@@ -87,13 +88,18 @@ vi.mock("../config/sessions.js", () => ({
8788} ) ) ;
8889
8990vi . mock ( "../agents/agent-scope.js" , ( ) => ( {
91+ resolveAgentWorkspaceDir : ( _cfg : unknown , agentId : string ) => `/tmp/openclaw-agent-${ agentId } ` ,
9092 resolveDefaultAgentId : ( cfg ?: {
9193 agents ?: { list ?: Array < { id ?: string ; default ?: boolean } > } ;
9294 } ) =>
9395 cfg ?. agents ?. list ?. find ( ( agent ) => agent . default ) ?. id ?? cfg ?. agents ?. list ?. [ 0 ] ?. id ?? "main" ,
9496 resolveSessionAgentId : ( ) => "main" ,
9597} ) ) ;
9698
99+ vi . mock ( "../agents/runtime-plugins.js" , ( ) => ( {
100+ ensureRuntimePluginsLoaded : ( ...args : unknown [ ] ) => ensureRuntimePluginsLoadedMock ( ...args ) ,
101+ } ) ) ;
102+
97103vi . mock ( "../agents/defaults.js" , ( ) => ( {
98104 DEFAULT_PROVIDER : "openai" ,
99105} ) ) ;
@@ -230,6 +236,7 @@ describe("EmbeddedTuiBackend", () => {
230236 status,
231237 tokensUsed : 0 ,
232238 } ) ) ;
239+ ensureRuntimePluginsLoadedMock . mockReset ( ) ;
233240 listSessionsFromStoreAsyncMock . mockReset ( ) ;
234241 listSessionsFromStoreAsyncMock . mockResolvedValue ( { sessions : [ ] } ) ;
235242 loadCombinedSessionStoreForGatewayMock . mockReset ( ) ;
@@ -604,6 +611,48 @@ describe("EmbeddedTuiBackend", () => {
604611 expect ( loadSessionEntryMock ) . toHaveBeenCalledWith ( "global" , { agentId : "work" } ) ;
605612 } ) ;
606613
614+ it ( "loads runtime plugins for the send-path workspace before returning embedded history" , async ( ) => {
615+ const cfg = { agents : { list : [ { id : "main" } ] } } ;
616+ loadSessionEntryMock . mockReturnValue ( {
617+ cfg,
618+ canonicalKey : "agent:main:main" ,
619+ storePath : "/tmp/openclaw-sessions.json" ,
620+ entry : { spawnedWorkspaceDir : "/tmp/openclaw-custom-workspace" } ,
621+ } ) ;
622+
623+ const { EmbeddedTuiBackend } = await import ( "./embedded-backend.js" ) ;
624+ const backend = new EmbeddedTuiBackend ( ) ;
625+
626+ await expect ( backend . loadHistory ( { sessionKey : "agent:main:main" } ) ) . resolves . toMatchObject ( {
627+ runtimePluginsPrewarm : { status : "warmed" } ,
628+ } ) ;
629+ expect ( ensureRuntimePluginsLoadedMock ) . toHaveBeenCalledWith ( {
630+ config : cfg ,
631+ workspaceDir : "/tmp/openclaw-agent-main" ,
632+ } ) ;
633+ } ) ;
634+
635+ it ( "returns embedded history when runtime plugin loading fails" , async ( ) => {
636+ ensureRuntimePluginsLoadedMock . mockImplementationOnce ( ( ) => {
637+ throw new Error ( "runtime unavailable" ) ;
638+ } ) ;
639+ loadSessionEntryMock . mockReturnValue ( {
640+ cfg : { } ,
641+ canonicalKey : "agent:main:main" ,
642+ storePath : "/tmp/openclaw-sessions.json" ,
643+ entry : { } ,
644+ } ) ;
645+
646+ const { EmbeddedTuiBackend } = await import ( "./embedded-backend.js" ) ;
647+ const backend = new EmbeddedTuiBackend ( ) ;
648+
649+ await expect ( backend . loadHistory ( { sessionKey : "agent:main:main" } ) ) . resolves . toMatchObject ( {
650+ sessionKey : "agent:main:main" ,
651+ messages : [ ] ,
652+ runtimePluginsPrewarm : { status : "failed" , error : "Error: runtime unavailable" } ,
653+ } ) ;
654+ } ) ;
655+
607656 it ( "passes selected-agent global scope into local chat turns" , async ( ) => {
608657 agentCommandFromIngressMock . mockResolvedValueOnce ( {
609658 payloads : [ { text : "done" } ] ,
0 commit comments