Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/core/src/agents/state-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}
}

Expand Down Expand Up @@ -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 };
}
}
}
Expand Down
128 changes: 69 additions & 59 deletions packages/core/src/state/state-validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>();
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<string>();
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<number>();
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<number>();
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<T>(
Expand Down