fix: persist Pascal agent scene after live updates

This commit is contained in:
134 2026-07-12 01:04:23 +08:00
parent 5260502507
commit 9efb9e8237
3 changed files with 30 additions and 12 deletions

View File

@ -95,12 +95,6 @@ function readSceneName(result: unknown, fallback: string): string {
: fallback
}
function readSceneVersion(result: unknown): number | null {
const version = (result as { structuredContent?: { version?: unknown } })?.structuredContent
?.version
return typeof version === 'number' && Number.isInteger(version) && version > 0 ? version : null
}
function assertToolSucceeded(result: unknown, operation: string): void {
if ((result as { isError?: unknown })?.isError === true) {
throw new Error(`Pascal MCP ${operation} failed.`)
@ -138,7 +132,6 @@ export async function createPascalAgentMcpSession(params: {
)
assertToolSucceeded(loadResult, 'load_scene')
const sceneName = readSceneName(loadResult, params.sceneId)
let currentVersion = readSceneVersion(loadResult)
const saveScene = withStepTimeout(requireTool(allTools, 'save_scene'), params.stepTimeoutMs)
const scopedSaveScene: RequiredTool = {
@ -148,7 +141,7 @@ export async function createPascalAgentMcpSession(params: {
const result = await saveScene.execute(
{
...candidate,
expectedVersion: currentVersion ?? undefined,
expectedVersion: undefined,
graph: undefined,
id: params.sceneId,
includeCurrentScene: true,
@ -157,8 +150,6 @@ export async function createPascalAgentMcpSession(params: {
},
options,
)
const savedVersion = readSceneVersion(result)
if (savedVersion) currentVersion = savedVersion
return result
},
}

View File

@ -167,4 +167,25 @@ describe('save_scene', () => {
})
expect(result.isError).toBe(true)
})
test('uses the active scene version when the caller omits expectedVersion', async () => {
const first = await client.callTool({
name: 'save_scene',
arguments: { id: 'active-scene', name: 'First' },
})
expect(first.isError).toBeFalsy()
const second = await client.callTool({
name: 'save_scene',
arguments: { id: 'active-scene', name: 'Second', expectedVersion: 1 },
})
expect(second.isError).toBeFalsy()
const final = await client.callTool({
name: 'save_scene',
arguments: { id: 'active-scene', name: 'Final' },
})
expect(final.isError).toBeFalsy()
expect(parseToolText(final.content as StoredTextContent[]).version).toBe(3)
})
})

View File

@ -118,6 +118,10 @@ export function registerSaveScene(server: McpServer, bridge: SceneOperations): v
sceneGraph = graph as unknown as SceneGraph
}
const activeScene = includeCurrentScene ? bridge.getActiveScene() : null
const resolvedExpectedVersion =
expectedVersion ?? (activeScene && activeScene.id === id ? activeScene.version : undefined)
try {
const meta = await bridge.saveScene({
...(id !== undefined ? { id } : {}),
@ -125,7 +129,9 @@ export function registerSaveScene(server: McpServer, bridge: SceneOperations): v
...(projectId !== undefined ? { projectId } : {}),
graph: sceneGraph,
...(thumbnail !== undefined ? { thumbnailUrl: thumbnail } : {}),
...(expectedVersion !== undefined ? { expectedVersion } : {}),
...(resolvedExpectedVersion !== undefined
? { expectedVersion: resolvedExpectedVersion }
: {}),
saveMode,
...(publish !== undefined ? { publish } : {}),
operation: 'save_scene',
@ -145,7 +151,7 @@ export function registerSaveScene(server: McpServer, bridge: SceneOperations): v
} catch (err) {
if (err instanceof SceneVersionConflictError) {
throwMcpError(ErrorCode.InvalidRequest, 'version_conflict', {
expectedVersion,
expectedVersion: resolvedExpectedVersion,
id,
})
}