fix(agent): recover stale runs and improve new-user OA delivery
Fix DEV logout cookie clearing, materialize selected MindSpace OA assets before agent runs, and recover zombie runs from synced workspace pages. Add client run wait timeout, harness retry limits, page-edit asset forwarding, and logout/john2 scenario tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,10 +1,33 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
buildSelectedAssetDeleteInstructions,
|
||||
buildSelectedAssetReadInstructions,
|
||||
createAssetAgentService,
|
||||
} from './mindspace-asset-agent.mjs';
|
||||
|
||||
test('buildSelectedAssetReadInstructions uses agent download proxy', () => {
|
||||
const lines = buildSelectedAssetReadInstructions({
|
||||
selectedAssets: [
|
||||
{
|
||||
id: 'asset-9',
|
||||
displayName: 'sales.xlsx',
|
||||
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
},
|
||||
],
|
||||
h5ApiBase: 'http://127.0.0.1:8081',
|
||||
agentSessionId: 'session-1',
|
||||
});
|
||||
const text = lines.join('\n');
|
||||
assert.match(text, /mindspace_asset_download/);
|
||||
assert.match(text, /禁止.*assets\/:id\/download/);
|
||||
assert.match(text, /asset-9/);
|
||||
assert.match(text, /session-1/);
|
||||
});
|
||||
|
||||
test('buildSelectedAssetDeleteInstructions includes agent delete curl', () => {
|
||||
const lines = buildSelectedAssetDeleteInstructions({
|
||||
selectedAssets: [
|
||||
@@ -32,6 +55,7 @@ test('applyAgentDelete requires confirmation and valid session', async () => {
|
||||
},
|
||||
resolveUserIdForAgentSession: async (sessionId) =>
|
||||
sessionId === 'session-1' ? 'user-1' : null,
|
||||
resolveWorkspaceRoot: async () => '/tmp/workspace',
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
@@ -47,3 +71,64 @@ test('applyAgentDelete requires confirmation and valid session', async () => {
|
||||
assert.equal(result.deleted, true);
|
||||
assert.equal(result.userId, 'user-1');
|
||||
});
|
||||
|
||||
test('applyAgentDownload materializes asset into workspace oa/', async () => {
|
||||
const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'asset-agent-'));
|
||||
const sourcePath = path.join(workspaceRoot, 'source.xlsx');
|
||||
await fs.writeFile(sourcePath, 'excel-bytes');
|
||||
|
||||
const service = createAssetAgentService({
|
||||
assetService: {
|
||||
readAsset: async () => ({
|
||||
asset: {
|
||||
id: 'asset-9',
|
||||
categoryCode: 'oa',
|
||||
filename: 'sales.xlsx',
|
||||
displayName: 'sales.xlsx',
|
||||
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
},
|
||||
path: sourcePath,
|
||||
}),
|
||||
},
|
||||
resolveUserIdForAgentSession: async () => 'user-1',
|
||||
resolveWorkspaceRoot: async () => workspaceRoot,
|
||||
});
|
||||
|
||||
const result = await service.applyAgentDownload({
|
||||
session_id: 'session-1',
|
||||
asset_id: 'asset-9',
|
||||
});
|
||||
assert.equal(result.relativePath, 'oa/sales.xlsx');
|
||||
const copied = await fs.readFile(path.join(workspaceRoot, 'oa/sales.xlsx'), 'utf8');
|
||||
assert.equal(copied, 'excel-bytes');
|
||||
});
|
||||
|
||||
test('materializeAssetsForSession accepts explicit userId', async () => {
|
||||
const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'asset-agent-'));
|
||||
const sourcePath = path.join(workspaceRoot, 'source.csv');
|
||||
await fs.writeFile(sourcePath, 'a,b\n1,2');
|
||||
|
||||
const service = createAssetAgentService({
|
||||
assetService: {
|
||||
readAsset: async (_userId, assetId) => ({
|
||||
asset: {
|
||||
id: assetId,
|
||||
categoryCode: 'oa',
|
||||
filename: 'data.csv',
|
||||
displayName: 'data.csv',
|
||||
mimeType: 'text/csv',
|
||||
},
|
||||
path: sourcePath,
|
||||
}),
|
||||
},
|
||||
resolveUserIdForAgentSession: async () => null,
|
||||
resolveWorkspaceRoot: async () => workspaceRoot,
|
||||
});
|
||||
|
||||
const result = await service.materializeAssetsForSession({
|
||||
userId: 'user-1',
|
||||
assetIds: ['asset-a'],
|
||||
});
|
||||
assert.equal(result.materialized.length, 1);
|
||||
assert.equal(result.materialized[0].relativePath, 'oa/data.csv');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user