fix: persist agent scene mutations reliably

This commit is contained in:
134 2026-07-11 16:50:20 +08:00
parent 67ff51d194
commit 54b0020af7
2 changed files with 37 additions and 13 deletions

View File

@ -95,6 +95,18 @@ 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.`)
}
}
export async function createPascalAgentMcpSession(params: {
abortSignal?: AbortSignal
env?: NodeJS.ProcessEnv
@ -124,16 +136,19 @@ export async function createPascalAgentMcpSession(params: {
{ id: params.sceneId },
toolExecutionOptions(params.abortSignal),
)
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 = {
...saveScene,
execute: async (input, options) => {
const candidate = input && typeof input === 'object' ? input : {}
return saveScene.execute(
const result = await saveScene.execute(
{
...candidate,
expectedVersion: currentVersion ?? undefined,
graph: undefined,
id: params.sceneId,
includeCurrentScene: true,
@ -142,6 +157,9 @@ export async function createPascalAgentMcpSession(params: {
},
options,
)
const savedVersion = readSceneVersion(result)
if (savedVersion) currentVersion = savedVersion
return result
},
}
@ -168,7 +186,7 @@ export async function createPascalAgentMcpSession(params: {
sceneName,
tools,
saveDraft: async (abortSignal) => {
await scopedSaveScene.execute(
const result = await scopedSaveScene.execute(
{
id: params.sceneId,
includeCurrentScene: true,
@ -177,6 +195,7 @@ export async function createPascalAgentMcpSession(params: {
},
toolExecutionOptions(abortSignal),
)
assertToolSucceeded(result, 'save_scene')
},
}
} catch (error) {

View File

@ -272,19 +272,23 @@ class SceneOperationsFacade implements SceneOperations {
}
async saveScene(options: SceneSaveOptions): Promise<SceneMeta> {
return this.requireStore().save(options)
const store = this.requireStore()
return store.save(options)
}
async loadStoredScene(id: string): Promise<SceneWithGraph | null> {
return this.requireStore().load(id)
const store = this.requireStore()
return store.load(id)
}
async listScenes(options?: SceneListOptions): Promise<SceneMeta[]> {
return this.requireStore().list(options)
const store = this.requireStore()
return store.list(options)
}
async deleteStoredScene(id: string, options?: SceneMutateOptions): Promise<boolean> {
return this.requireStore().delete(id, options)
const store = this.requireStore()
return store.delete(id, options)
}
async renameStoredScene(
@ -292,21 +296,22 @@ class SceneOperationsFacade implements SceneOperations {
newName: string,
options?: SceneMutateOptions,
): Promise<SceneMeta> {
return this.requireStore().rename(id, newName, options)
const store = this.requireStore()
return store.rename(id, newName, options)
}
async appendSceneEvent(options: SceneEventAppendOptions): Promise<SceneEvent | null> {
const append = this.requireStore().appendSceneEvent
if (!append) return null
return append(options)
const store = this.requireStore()
if (!store.appendSceneEvent) return null
return store.appendSceneEvent(options)
}
async listSceneEvents(id: string, options?: SceneEventListOptions): Promise<SceneEvent[]> {
const list = this.requireStore().listSceneEvents
if (!list) {
const store = this.requireStore()
if (!store.listSceneEvents) {
throw new Error('scene_events_unavailable')
}
return list(id, options)
return store.listSceneEvents(id, options)
}
private requireBridge(): SceneBridge {