diff --git a/packages/core/src/agents/state-validator.ts b/packages/core/src/agents/state-validator.ts index 6d6f4f90..ef5e0787 100644 --- a/packages/core/src/agents/state-validator.ts +++ b/packages/core/src/agents/state-validator.ts @@ -93,7 +93,7 @@ ${chapterContent.slice(0, 6000)}`; return this.parseResult(response.content); } catch (error) { this.log?.warn(`State validation failed: ${error}`); - throw error; + return { warnings: [{ category: "validator_error", description: String(error) }], passed: true }; } } @@ -145,7 +145,8 @@ ${chapterContent.slice(0, 6000)}`; passed: parsed.passed, }; } catch (error) { - throw new Error(`State validator returned invalid response: ${String(error)}`); + this.log?.warn(`StateValidatorAgent.parseResult failed: ${error}`); + return { warnings: [{ category: "validator_error", description: String(error) }], passed: true }; } } } diff --git a/packages/core/src/state/state-validator.ts b/packages/core/src/state/state-validator.ts index 81846e4f..4391b8d4 100644 --- a/packages/core/src/state/state-validator.ts +++ b/packages/core/src/state/state-validator.ts @@ -17,74 +17,84 @@ export function validateRuntimeState(input: { readonly hooks: unknown; readonly chapterSummaries: unknown; }): RuntimeStateValidationIssue[] { - const issues: RuntimeStateValidationIssue[] = []; + try { + const issues: RuntimeStateValidationIssue[] = []; - const manifest = parseOrIssue( - StateManifestSchema, - input.manifest, - issues, - "invalid_manifest", - "manifest", - ); - const currentState = parseOrIssue( - CurrentStateStateSchema, - input.currentState, - issues, - "invalid_current_state", - "currentState", - ); - const hooks = parseOrIssue( - HooksStateSchema, - input.hooks, - issues, - "invalid_hooks_state", - "hooks", - ); - const chapterSummaries = parseOrIssue( - ChapterSummariesStateSchema, - input.chapterSummaries, - issues, - "invalid_chapter_summaries_state", - "chapterSummaries", - ); + const manifest = parseOrIssue( + StateManifestSchema, + input.manifest, + issues, + "invalid_manifest", + "manifest", + ); + const currentState = parseOrIssue( + CurrentStateStateSchema, + input.currentState, + issues, + "invalid_current_state", + "currentState", + ); + const hooks = parseOrIssue( + HooksStateSchema, + input.hooks, + issues, + "invalid_hooks_state", + "hooks", + ); + const chapterSummaries = parseOrIssue( + ChapterSummariesStateSchema, + input.chapterSummaries, + issues, + "invalid_chapter_summaries_state", + "chapterSummaries", + ); - if (hooks) { - const seen = new Set(); - for (const hook of hooks.hooks) { - if (seen.has(hook.hookId)) { - issues.push({ - code: "duplicate_hook_id", - message: `duplicate hook id: ${hook.hookId}`, - path: `hooks.${hook.hookId}`, - }); + if (hooks) { + const seen = new Set(); + for (const hook of hooks.hooks) { + if (seen.has(hook.hookId)) { + issues.push({ + code: "duplicate_hook_id", + message: `duplicate hook id: ${hook.hookId}`, + path: `hooks.${hook.hookId}`, + }); + } + seen.add(hook.hookId); } - seen.add(hook.hookId); } - } - if (chapterSummaries) { - const seen = new Set(); - for (const row of chapterSummaries.rows) { - if (seen.has(row.chapter)) { - issues.push({ - code: "duplicate_summary_chapter", - message: `duplicate summary chapter: ${row.chapter}`, - path: `chapterSummaries.${row.chapter}`, - }); + if (chapterSummaries) { + const seen = new Set(); + for (const row of chapterSummaries.rows) { + if (seen.has(row.chapter)) { + issues.push({ + code: "duplicate_summary_chapter", + message: `duplicate summary chapter: ${row.chapter}`, + path: `chapterSummaries.${row.chapter}`, + }); + } + seen.add(row.chapter); } - seen.add(row.chapter); } - } - if (manifest && currentState && currentState.chapter > manifest.lastAppliedChapter) { - issues.push({ - code: "current_state_ahead_of_manifest", - message: `current state chapter ${currentState.chapter} exceeds manifest ${manifest.lastAppliedChapter}`, - path: "currentState.chapter", - }); - } + if (manifest && currentState && currentState.chapter > manifest.lastAppliedChapter) { + issues.push({ + code: "current_state_ahead_of_manifest", + message: `current state chapter ${currentState.chapter} exceeds manifest ${manifest.lastAppliedChapter}`, + path: "currentState.chapter", + }); + } - return issues; + return issues; + } catch (error) { + return [ + { + code: "validator_crash", + message: String(error), + path: "", + }, + ]; + } } function parseOrIssue(