From 58e556d43ff9252378f9fd814ccd273be4e826ec Mon Sep 17 00:00:00 2001 From: Zhongxuan Wang Date: Thu, 13 Aug 2026 16:13:21 -0700 Subject: [PATCH 1/2] fix: allow null errors in successful adapter results Signed-off-by: Zhongxuan Wang --- crates/fabric-core/src/agent_execution.rs | 2 +- crates/fabric-core/src/schema.rs | 5 +++++ schemas/adapter-contract/agent-run-result.schema.json | 8 ++++---- .../adapter-contract/schemas/agent-run-result.schema.json | 8 ++++---- typescript/adapter-contract/scripts/generate.mjs | 4 ++-- typescript/adapter-contract/scripts/projection-guards.mjs | 2 +- .../adapter-contract/src/generated/agent-run-result.ts | 4 ++-- typescript/adapter-contract/test/execution.test.ts | 1 + 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/crates/fabric-core/src/agent_execution.rs b/crates/fabric-core/src/agent_execution.rs index 7f9780f4c..5f8111c2c 100644 --- a/crates/fabric-core/src/agent_execution.rs +++ b/crates/fabric-core/src/agent_execution.rs @@ -239,7 +239,7 @@ fn agent_run_result_schema(schema: &mut Schema) { "properties": {"status": {"const": "succeeded"}}, "required": ["status"] }, - "then": {"not": {"required": ["error"]}} + "then": {"properties": {"error": {"type": "null"}}} } ]), ); diff --git a/crates/fabric-core/src/schema.rs b/crates/fabric-core/src/schema.rs index 39812e50f..d77232853 100644 --- a/crates/fabric-core/src/schema.rs +++ b/crates/fabric-core/src/schema.rs @@ -447,6 +447,11 @@ mod tests { "output": null, "error": {"code": "target_error", "message": "target failed"} }))); + assert!(validator.is_valid(&serde_json::json!({ + "status": "succeeded", + "output": null, + "error": null + }))); for path in [ " \t", "nested/../output", diff --git a/schemas/adapter-contract/agent-run-result.schema.json b/schemas/adapter-contract/agent-run-result.schema.json index c6ac4081e..94704b106 100644 --- a/schemas/adapter-contract/agent-run-result.schema.json +++ b/schemas/adapter-contract/agent-run-result.schema.json @@ -199,10 +199,10 @@ ] }, "then": { - "not": { - "required": [ - "error" - ] + "properties": { + "error": { + "type": "null" + } } } } diff --git a/typescript/adapter-contract/schemas/agent-run-result.schema.json b/typescript/adapter-contract/schemas/agent-run-result.schema.json index c6ac4081e..94704b106 100644 --- a/typescript/adapter-contract/schemas/agent-run-result.schema.json +++ b/typescript/adapter-contract/schemas/agent-run-result.schema.json @@ -199,10 +199,10 @@ ] }, "then": { - "not": { - "required": [ - "error" - ] + "properties": { + "error": { + "type": "null" + } } } } diff --git a/typescript/adapter-contract/scripts/generate.mjs b/typescript/adapter-contract/scripts/generate.mjs index a0a117dac..ef796c27e 100644 --- a/typescript/adapter-contract/scripts/generate.mjs +++ b/typescript/adapter-contract/scripts/generate.mjs @@ -282,10 +282,10 @@ export type AgentRunResult = | AgentRunFailed | AgentRunCancelled; -/** Successful terminal result. Successful results cannot carry an error. */ +/** Successful terminal result. Successful results can carry only a null error. */ export interface AgentRunSucceeded extends AgentRunResultCommon { status: "succeeded"; - error?: never; + error?: null; } /** Failed terminal result. Failed results must carry a non-null error. */ diff --git a/typescript/adapter-contract/scripts/projection-guards.mjs b/typescript/adapter-contract/scripts/projection-guards.mjs index b6dd7de99..b009e6541 100644 --- a/typescript/adapter-contract/scripts/projection-guards.mjs +++ b/typescript/adapter-contract/scripts/projection-guards.mjs @@ -19,7 +19,7 @@ const supportedRunResultConditionals = [ properties: { status: { const: "succeeded" } }, required: ["status"], }, - then: { not: { required: ["error"] } }, + then: { properties: { error: { type: "null" } } }, }, ]; diff --git a/typescript/adapter-contract/src/generated/agent-run-result.ts b/typescript/adapter-contract/src/generated/agent-run-result.ts index 43a604ebb..db771c8f7 100644 --- a/typescript/adapter-contract/src/generated/agent-run-result.ts +++ b/typescript/adapter-contract/src/generated/agent-run-result.ts @@ -12,10 +12,10 @@ export type AgentRunResult = | AgentRunFailed | AgentRunCancelled; -/** Successful terminal result. Successful results cannot carry an error. */ +/** Successful terminal result. Successful results can carry only a null error. */ export interface AgentRunSucceeded extends AgentRunResultCommon { status: "succeeded"; - error?: never; + error?: null; } /** Failed terminal result. Failed results must carry a non-null error. */ diff --git a/typescript/adapter-contract/test/execution.test.ts b/typescript/adapter-contract/test/execution.test.ts index 0cb4fdfab..e658dd874 100644 --- a/typescript/adapter-contract/test/execution.test.ts +++ b/typescript/adapter-contract/test/execution.test.ts @@ -19,6 +19,7 @@ const requests: AgentRunRequest[] = [ const results: AgentRunResult[] = [ { output: null, status: "succeeded" }, + { error: null, output: null, status: "succeeded" }, { error: { code: "target_error", message: "target failed" }, output: { partial: true }, From 0452293780039a3161c4f6c58d56d03a6bb5a423 Mon Sep 17 00:00:00 2001 From: Zhongxuan Wang Date: Thu, 13 Aug 2026 16:55:46 -0700 Subject: [PATCH 2/2] test: cover optional successful result errors Signed-off-by: Zhongxuan Wang --- crates/fabric-core/src/schema.rs | 4 ++++ docs/adapter-contract/results.md | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/fabric-core/src/schema.rs b/crates/fabric-core/src/schema.rs index d77232853..83a399336 100644 --- a/crates/fabric-core/src/schema.rs +++ b/crates/fabric-core/src/schema.rs @@ -447,6 +447,10 @@ mod tests { "output": null, "error": {"code": "target_error", "message": "target failed"} }))); + assert!(validator.is_valid(&serde_json::json!({ + "status": "succeeded", + "output": null + }))); assert!(validator.is_valid(&serde_json::json!({ "status": "succeeded", "output": null, diff --git a/docs/adapter-contract/results.md b/docs/adapter-contract/results.md index 145245ce0..cde614ff2 100644 --- a/docs/adapter-contract/results.md +++ b/docs/adapter-contract/results.md @@ -31,10 +31,10 @@ Use the generated [`AgentRunResult` JSON Schema](https://github.com/NVIDIA/NeMo-Fabric/blob/main/schemas/adapter-contract/agent-run-result.schema.json) for exact fields and constraints. -A failed result must contain `error`. A succeeded result must not contain -`error`. Do not infer status from arbitrary fields in `output`. Exactly one -terminal result is produced for an invocation, and its status is immutable -once returned. +A failed result must contain `error`. A succeeded result can omit `error` or +set it to `null`; it must not contain a non-null error. Do not infer status +from arbitrary fields in `output`. Exactly one terminal result is produced for +an invocation, and its status is immutable once returned. ## Failure Classes