From 2f2f14562db56d6ce02f92c544d8bf1175fd74fd Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Sat, 18 Apr 2026 01:11:19 -0400 Subject: [PATCH] fix(api): convert OpenAPI spec to valid 3.1 syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The spec declared openapi 3.1.0 but used nullable: true (3.0 idiom) in 78 places, which Mintlify's parser rejected, breaking doc deploys. Convert to proper 3.1 patterns (type arrays and oneOf with type: null), switch the server conformance test from openapiv3 (3.0-only) to a YAML-level walk so it accepts 3.1 input, and regenerate the typescript client — it now correctly emits `| null` on nullable fields. Co-Authored-By: Claude Opus 4.7 (1M context) --- Cargo.lock | 1 - docs/api-reference/fabro-api.yaml | 238 ++++++------------ lib/crates/fabro-server/Cargo.toml | 1 - .../tests/it/openapi_conformance.rs | 52 ++-- .../src/models/aggregate-billing-totals.ts | 2 +- .../src/models/api-question.ts | 4 +- .../src/models/artifact-batch-upload-entry.ts | 6 +- .../src/models/billed-token-counts.ts | 2 +- .../src/models/diagnostics-check.ts | 2 +- .../src/models/disk-usage-response.ts | 2 +- .../src/models/disk-usage-summary-row.ts | 4 +- .../src/models/manifest-config.ts | 4 +- .../src/models/manifest-file-ref.ts | 2 +- .../src/models/manifest-goal.ts | 2 +- .../src/models/model-costs.ts | 6 +- .../src/models/model-limits.ts | 2 +- .../src/models/model-test-result.ts | 2 +- .../fabro-api-client/src/models/model.ts | 4 +- .../fabro-api-client/src/models/node-state.ts | 10 +- .../src/models/node-status-record.ts | 4 +- .../src/models/preflight-check-result.ts | 2 +- .../src/models/preflight-workflow-summary.ts | 2 +- .../src/models/prune-runs-response.ts | 2 +- .../src/models/repo-check-response.ts | 6 +- .../src/models/run-billing-totals.ts | 2 +- .../fabro-api-client/src/models/run-event.ts | 18 +- .../src/models/run-manifest.ts | 2 +- .../src/models/run-projection.ts | 20 +- .../src/models/run-status-response.ts | 4 +- .../src/models/store-run-summary.ts | 20 +- .../src/models/system-info-response.ts | 4 +- .../src/models/workflow-diagnostic.ts | 6 +- 32 files changed, 181 insertions(+), 257 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5536a3cf5..7451606fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1955,7 +1955,6 @@ dependencies = [ "mime_guess", "multer", "object_store", - "openapiv3", "rand 0.9.2", "regex", "rustls", diff --git a/docs/api-reference/fabro-api.yaml b/docs/api-reference/fabro-api.yaml index 3228cbefd..da5f2cac8 100644 --- a/docs/api-reference/fabro-api.yaml +++ b/docs/api-reference/fabro-api.yaml @@ -1735,9 +1735,8 @@ components: description: Maximum context window size in tokens. example: 1000000 max_output: - type: integer + type: ["integer", "null"] format: int64 - nullable: true description: Maximum output tokens, if known. example: 128000 @@ -1764,21 +1763,18 @@ components: type: object properties: input_cost_per_mtok: - type: number + type: ["number", "null"] format: double - nullable: true description: Cost per million input tokens in USD. example: 15.0 output_cost_per_mtok: - type: number + type: ["number", "null"] format: double - nullable: true description: Cost per million output tokens in USD. example: 75.0 cache_input_cost_per_mtok: - type: number + type: ["number", "null"] format: double - nullable: true description: Cost per million cached input tokens in USD. example: 1.50 @@ -1815,8 +1811,7 @@ components: limits: $ref: "#/components/schemas/ModelLimits" training: - type: string - nullable: true + type: ["string", "null"] description: Training data cutoff date (YYYY-MM-DD). example: "2025-08-01" features: @@ -1824,9 +1819,8 @@ components: costs: $ref: "#/components/schemas/ModelCosts" estimated_output_tps: - type: number + type: ["number", "null"] format: double - nullable: true description: Estimated output tokens per second. aliases: type: array @@ -1857,8 +1851,7 @@ components: - skip description: Whether the model responded successfully, failed, or was skipped because its provider is not configured. error_message: - type: string - nullable: true + type: ["string", "null"] description: Error details when status is "error". ModelTestMode: @@ -2108,8 +2101,7 @@ components: description: Manifest schema version. example: 1 run_id: - type: string - nullable: true + type: ["string", "null"] description: Optional pre-generated run ID to use instead of allocating a new ULID. example: "01HV6D7S5YF4Z4B2M7K4N0Q6T9" cwd: @@ -2175,8 +2167,7 @@ components: type: string description: Resolved goal content. path: - type: string - nullable: true + type: ["string", "null"] description: Original goal file path when the goal came from a file. ManifestArgs: @@ -2230,11 +2221,9 @@ components: - project - user path: - type: string - nullable: true + type: ["string", "null"] source: - type: string - nullable: true + type: ["string", "null"] ManifestWorkflowConfig: type: object @@ -2274,8 +2263,7 @@ components: original: type: string from: - type: string - nullable: true + type: ["string", "null"] ManifestWorkflow: type: object @@ -2341,8 +2329,7 @@ components: name: type: string graph_path: - type: string - nullable: true + type: ["string", "null"] nodes: type: integer edges: @@ -2372,18 +2359,15 @@ components: message: type: string node_id: - type: string - nullable: true + type: ["string", "null"] edge: - type: array - nullable: true + type: ["array", "null"] minItems: 2 maxItems: 2 items: type: string fix: - type: string - nullable: true + type: ["string", "null"] PreflightCheckReport: type: object @@ -2434,8 +2418,7 @@ components: items: $ref: "#/components/schemas/PreflightCheckDetail" remediation: - type: string - nullable: true + type: ["string", "null"] PreflightCheckDetail: type: object @@ -2478,13 +2461,13 @@ components: description: Position in the queue (1-based). Only present when status is `queued`. example: 3 status_reason: - allOf: + oneOf: - $ref: "#/components/schemas/StatusReason" - nullable: true + - type: "null" pending_control: - allOf: + oneOf: - $ref: "#/components/schemas/RunControlAction" - nullable: true + - type: "null" created_at: type: string format: date-time @@ -2542,14 +2525,12 @@ components: description: Whether the user may provide freeform text in addition to selecting options. example: true timeout_seconds: - type: number + type: ["number", "null"] format: double - nullable: true description: Timeout for the question when configured by the workflow. example: 30 context_display: - type: string - nullable: true + type: ["string", "null"] description: Optional contextual text shown alongside the question. example: Latest draft @@ -2662,44 +2643,36 @@ components: run_id: type: string node_id: - type: string - nullable: true + type: ["string", "null"] node_label: - type: string - nullable: true + type: ["string", "null"] stage_id: - type: string - nullable: true + type: ["string", "null"] description: Stage execution identity, formatted as "{node_id}@{visit}". parallel_group_id: - type: string - nullable: true + type: ["string", "null"] description: > Durable identity of one execution of a parallel node, formatted as "{node_id}@{visit}". parallel_branch_id: - type: string - nullable: true + type: ["string", "null"] description: > Durable identity of one branch within a parallel execution, formatted as "{parallel_group_id}:{index}". session_id: - type: string - nullable: true + type: ["string", "null"] parent_session_id: - type: string - nullable: true + type: ["string", "null"] tool_call_id: - type: string - nullable: true + type: ["string", "null"] description: > Stable identifier for a tool call, present on agent.tool.* events and other durable events that directly describe the same tool call. actor: - allOf: + oneOf: - $ref: "#/components/schemas/ActorRef" - nullable: true + - type: "null" event: type: string description: Event type discriminator. @@ -2803,20 +2776,17 @@ components: description: Relative artifact path to store. example: src/lib.rs sha256: - type: string - nullable: true + type: ["string", "null"] description: Optional lowercase hex SHA-256 checksum for the file contents. example: 3f785df4c5b7d3f1f4c1f0ecb0f55f1d9f6f6a3d9f0a8a98f7a74f29d1f81a2c expected_bytes: - type: integer + type: ["integer", "null"] format: int64 - nullable: true minimum: 0 description: Optional exact byte length expected for the file part. example: 1234 content_type: - type: string - nullable: true + type: ["string", "null"] description: Optional client-supplied content type for the file part. example: text/plain @@ -2945,11 +2915,9 @@ components: status: $ref: "#/components/schemas/InternalStageStatus" notes: - type: string - nullable: true + type: ["string", "null"] failure_reason: - type: string - nullable: true + type: ["string", "null"] timestamp: type: string format: date-time @@ -2959,32 +2927,23 @@ components: type: object properties: prompt: - type: string - nullable: true + type: ["string", "null"] response: - type: string - nullable: true + type: ["string", "null"] status: oneOf: - $ref: "#/components/schemas/NodeStatusRecord" - type: "null" - provider_used: - nullable: true + provider_used: {} diff: - type: string - nullable: true - script_invocation: - nullable: true - script_timing: - nullable: true - parallel_results: - nullable: true + type: ["string", "null"] + script_invocation: {} + script_timing: {} + parallel_results: {} stdout: - type: string - nullable: true + type: ["string", "null"] stderr: - type: string - nullable: true + type: ["string", "null"] RunProjection: description: Raw internal run projection derived from the event log. @@ -2993,16 +2952,13 @@ components: - nodes properties: run: - type: object + type: ["object", "null"] additionalProperties: true - nullable: true graph_source: - type: string - nullable: true + type: ["string", "null"] start: - type: object + type: ["object", "null"] additionalProperties: true - nullable: true status: oneOf: - $ref: "#/components/schemas/RunStatusRecord" @@ -3023,30 +2979,23 @@ components: - type: integer - $ref: "#/components/schemas/RunCheckpoint" conclusion: - type: object + type: ["object", "null"] additionalProperties: true - nullable: true retro: - type: object + type: ["object", "null"] additionalProperties: true - nullable: true retro_prompt: - type: string - nullable: true + type: ["string", "null"] retro_response: - type: string - nullable: true + type: ["string", "null"] sandbox: - type: object + type: ["object", "null"] additionalProperties: true - nullable: true final_patch: - type: string - nullable: true + type: ["string", "null"] pull_request: - type: object + type: ["object", "null"] additionalProperties: true - nullable: true nodes: type: object description: Map from StageId (`node_id@visit`) to NodeState. @@ -3063,44 +3012,35 @@ components: run_id: type: string workflow_name: - type: string - nullable: true + type: ["string", "null"] workflow_slug: - type: string - nullable: true + type: ["string", "null"] goal: - type: string - nullable: true + type: ["string", "null"] labels: type: object additionalProperties: type: string host_repo_path: - type: string - nullable: true + type: ["string", "null"] start_time: - type: string + type: ["string", "null"] format: date-time - nullable: true status: - type: string - nullable: true + type: ["string", "null"] status_reason: - type: string - nullable: true + type: ["string", "null"] pending_control: - allOf: + oneOf: - $ref: "#/components/schemas/RunControlAction" - nullable: true + - type: "null" duration_ms: - type: integer + type: ["integer", "null"] format: int64 minimum: 0 - nullable: true total_usd_micros: - type: integer + type: ["integer", "null"] format: int64 - nullable: true # ── Run Board Schemas ──────────────────────────────────────────────── @@ -3225,9 +3165,8 @@ components: description: Number of cache write tokens. example: 1500 total_usd_micros: - type: integer + type: ["integer", "null"] format: int64 - nullable: true description: Billed USD amount in micros. example: 720000 @@ -3379,9 +3318,8 @@ components: description: Total cache write tokens. example: 9200 total_usd_micros: - type: integer + type: ["integer", "null"] format: int64 - nullable: true description: Total billed USD amount in micros. example: 20340000 runtime_secs: @@ -3768,9 +3706,8 @@ components: description: Total cache write tokens. example: 4500 total_usd_micros: - type: integer + type: ["integer", "null"] format: int64 - nullable: true description: Total billed USD amount in micros. example: 2260000 @@ -4086,12 +4023,10 @@ components: type: string description: Server version string. git_sha: - type: string - nullable: true + type: ["string", "null"] description: Build git SHA when available. build_date: - type: string - nullable: true + type: ["string", "null"] description: Build date when available. os: type: string @@ -4158,8 +4093,7 @@ components: format: int64 description: Total bytes reclaimable by deleting inactive runs and logs. runs: - type: array - nullable: true + type: ["array", "null"] description: Per-run usage rows when verbose output is requested. items: $ref: "#/components/schemas/DiskUsageRunRow" @@ -4176,18 +4110,16 @@ components: format: int64 description: Number of items in the category. active: - type: integer + type: ["integer", "null"] format: int64 - nullable: true description: Number of active items when applicable. size_bytes: type: integer format: int64 description: Total bytes used by the category. reclaimable_bytes: - type: integer + type: ["integer", "null"] format: int64 - nullable: true description: Bytes reclaimable by pruning the category. DiskUsageRunRow: @@ -4249,8 +4181,7 @@ components: type: boolean description: Whether this response is a dry-run preview. runs: - type: array - nullable: true + type: ["array", "null"] description: Matched runs when dry-run is enabled. items: $ref: "#/components/schemas/PruneRunEntry" @@ -4428,17 +4359,14 @@ components: type: boolean description: Whether the server has read-write access to this repository. default_branch: - type: string - nullable: true + type: ["string", "null"] description: Default branch name, if accessible. example: main private: - type: boolean - nullable: true + type: ["boolean", "null"] description: Whether the repository is private, if accessible. permissions: - type: object - nullable: true + type: ["object", "null"] description: Detected permission levels. properties: pull: @@ -4448,8 +4376,7 @@ components: admin: type: boolean install_url: - type: string - nullable: true + type: ["string", "null"] description: GitHub App installation URL when the repo is not yet accessible. DiagnosticsReport: @@ -4502,8 +4429,7 @@ components: items: $ref: "#/components/schemas/DiagnosticsDetail" remediation: - type: string - nullable: true + type: ["string", "null"] DiagnosticsDetail: type: object diff --git a/lib/crates/fabro-server/Cargo.toml b/lib/crates/fabro-server/Cargo.toml index 7d2267a7c..698818086 100644 --- a/lib/crates/fabro-server/Cargo.toml +++ b/lib/crates/fabro-server/Cargo.toml @@ -87,6 +87,5 @@ tokio = { workspace = true, features = ["test-util", "macros"] } tower = "0.5" http-body-util = "0.1" httpmock = "0.8" -openapiv3 = "2" serde_yaml = "0.9" fabro-sandbox = { path = "../fabro-sandbox" } diff --git a/lib/crates/fabro-server/tests/it/openapi_conformance.rs b/lib/crates/fabro-server/tests/it/openapi_conformance.rs index dfe118a11..c4e47b9f7 100644 --- a/lib/crates/fabro-server/tests/it/openapi_conformance.rs +++ b/lib/crates/fabro-server/tests/it/openapi_conformance.rs @@ -11,11 +11,12 @@ use axum::body::Body; use axum::http::{Method, Request, StatusCode}; use fabro_server::jwt_auth::AuthMode; use fabro_server::server::build_router; +use serde_yaml::Value; use tower::ServiceExt; use super::helpers::test_app_state; -fn load_spec() -> openapiv3::OpenAPI { +fn load_spec() -> Value { let spec_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) .parent() .unwrap() @@ -36,24 +37,22 @@ fn resolve_path(path: &str) -> String { .replace("{slug}", "test-slug") } -fn methods_for_path_item(item: &openapiv3::PathItem) -> Vec { - let mut methods = Vec::new(); - if item.get.is_some() { - methods.push(Method::GET); - } - if item.post.is_some() { - methods.push(Method::POST); - } - if item.put.is_some() { - methods.push(Method::PUT); - } - if item.delete.is_some() { - methods.push(Method::DELETE); - } - if item.patch.is_some() { - methods.push(Method::PATCH); - } - methods +fn methods_for_path_item(item: &Value) -> Vec { + const HTTP_METHODS: &[(&str, Method)] = &[ + ("get", Method::GET), + ("post", Method::POST), + ("put", Method::PUT), + ("delete", Method::DELETE), + ("patch", Method::PATCH), + ]; + let Some(map) = item.as_mapping() else { + return Vec::new(); + }; + HTTP_METHODS + .iter() + .filter(|(key, _)| map.contains_key(Value::String((*key).to_string()))) + .map(|(_, method)| method.clone()) + .collect() } #[tokio::test] @@ -62,15 +61,16 @@ async fn all_spec_routes_are_routable() { let state = test_app_state(); let app = build_router(state, AuthMode::Disabled); - let mut checked = 0; - for (path, item) in &spec.paths.paths { - let path_item = match item { - openapiv3::ReferenceOr::Item(item) => item, - openapiv3::ReferenceOr::Reference { .. } => continue, - }; + let paths = spec + .get("paths") + .and_then(Value::as_mapping) + .expect("spec is missing `paths`"); + let mut checked = 0; + for (path_key, item) in paths { + let path = path_key.as_str().expect("path key must be a string"); let uri = resolve_path(path); - for method in methods_for_path_item(path_item) { + for method in methods_for_path_item(item) { let mut builder = Request::builder().method(&method).uri(&uri); let body = if method == Method::POST { diff --git a/lib/packages/fabro-api-client/src/models/aggregate-billing-totals.ts b/lib/packages/fabro-api-client/src/models/aggregate-billing-totals.ts index 92558f151..92d44ae11 100644 --- a/lib/packages/fabro-api-client/src/models/aggregate-billing-totals.ts +++ b/lib/packages/fabro-api-client/src/models/aggregate-billing-totals.ts @@ -49,7 +49,7 @@ export interface AggregateBillingTotals { /** * Total billed USD amount in micros. */ - 'total_usd_micros'?: number; + 'total_usd_micros'?: number | null; /** * Total runtime in seconds. */ diff --git a/lib/packages/fabro-api-client/src/models/api-question.ts b/lib/packages/fabro-api-client/src/models/api-question.ts index 78ea79cd3..efdd1416a 100644 --- a/lib/packages/fabro-api-client/src/models/api-question.ts +++ b/lib/packages/fabro-api-client/src/models/api-question.ts @@ -48,11 +48,11 @@ export interface ApiQuestion { /** * Timeout for the question when configured by the workflow. */ - 'timeout_seconds'?: number; + 'timeout_seconds'?: number | null; /** * Optional contextual text shown alongside the question. */ - 'context_display'?: string; + 'context_display'?: string | null; } diff --git a/lib/packages/fabro-api-client/src/models/artifact-batch-upload-entry.ts b/lib/packages/fabro-api-client/src/models/artifact-batch-upload-entry.ts index 3a4545f4e..d54d061af 100644 --- a/lib/packages/fabro-api-client/src/models/artifact-batch-upload-entry.ts +++ b/lib/packages/fabro-api-client/src/models/artifact-batch-upload-entry.ts @@ -29,14 +29,14 @@ export interface ArtifactBatchUploadEntry { /** * Optional lowercase hex SHA-256 checksum for the file contents. */ - 'sha256'?: string; + 'sha256'?: string | null; /** * Optional exact byte length expected for the file part. */ - 'expected_bytes'?: number; + 'expected_bytes'?: number | null; /** * Optional client-supplied content type for the file part. */ - 'content_type'?: string; + 'content_type'?: string | null; } diff --git a/lib/packages/fabro-api-client/src/models/billed-token-counts.ts b/lib/packages/fabro-api-client/src/models/billed-token-counts.ts index 5cc3922a4..a9d0bf9c7 100644 --- a/lib/packages/fabro-api-client/src/models/billed-token-counts.ts +++ b/lib/packages/fabro-api-client/src/models/billed-token-counts.ts @@ -45,6 +45,6 @@ export interface BilledTokenCounts { /** * Billed USD amount in micros. */ - 'total_usd_micros'?: number; + 'total_usd_micros'?: number | null; } diff --git a/lib/packages/fabro-api-client/src/models/diagnostics-check.ts b/lib/packages/fabro-api-client/src/models/diagnostics-check.ts index a2f2990e2..4e44f6b2b 100644 --- a/lib/packages/fabro-api-client/src/models/diagnostics-check.ts +++ b/lib/packages/fabro-api-client/src/models/diagnostics-check.ts @@ -22,7 +22,7 @@ export interface DiagnosticsCheck { 'status': DiagnosticsCheckStatusEnum; 'summary': string; 'details'?: Array; - 'remediation'?: string; + 'remediation'?: string | null; } export const DiagnosticsCheckStatusEnum = { diff --git a/lib/packages/fabro-api-client/src/models/disk-usage-response.ts b/lib/packages/fabro-api-client/src/models/disk-usage-response.ts index 3d0c0a8bb..186558cf8 100644 --- a/lib/packages/fabro-api-client/src/models/disk-usage-response.ts +++ b/lib/packages/fabro-api-client/src/models/disk-usage-response.ts @@ -36,6 +36,6 @@ export interface DiskUsageResponse { /** * Per-run usage rows when verbose output is requested. */ - 'runs'?: Array; + 'runs'?: Array | null; } diff --git a/lib/packages/fabro-api-client/src/models/disk-usage-summary-row.ts b/lib/packages/fabro-api-client/src/models/disk-usage-summary-row.ts index bd41f1f43..2672730a3 100644 --- a/lib/packages/fabro-api-client/src/models/disk-usage-summary-row.ts +++ b/lib/packages/fabro-api-client/src/models/disk-usage-summary-row.ts @@ -29,7 +29,7 @@ export interface DiskUsageSummaryRow { /** * Number of active items when applicable. */ - 'active'?: number; + 'active'?: number | null; /** * Total bytes used by the category. */ @@ -37,6 +37,6 @@ export interface DiskUsageSummaryRow { /** * Bytes reclaimable by pruning the category. */ - 'reclaimable_bytes'?: number; + 'reclaimable_bytes'?: number | null; } diff --git a/lib/packages/fabro-api-client/src/models/manifest-config.ts b/lib/packages/fabro-api-client/src/models/manifest-config.ts index 91585688c..19e1e36c7 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-config.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-config.ts @@ -16,8 +16,8 @@ export interface ManifestConfig { 'type': ManifestConfigTypeEnum; - 'path'?: string; - 'source'?: string; + 'path'?: string | null; + 'source'?: string | null; } export const ManifestConfigTypeEnum = { diff --git a/lib/packages/fabro-api-client/src/models/manifest-file-ref.ts b/lib/packages/fabro-api-client/src/models/manifest-file-ref.ts index 9ff779047..cf84bf0d7 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-file-ref.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-file-ref.ts @@ -17,7 +17,7 @@ export interface ManifestFileRef { 'type': ManifestFileRefTypeEnum; 'original': string; - 'from'?: string; + 'from'?: string | null; } export const ManifestFileRefTypeEnum = { diff --git a/lib/packages/fabro-api-client/src/models/manifest-goal.ts b/lib/packages/fabro-api-client/src/models/manifest-goal.ts index 397ef8317..2c766649d 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-goal.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-goal.ts @@ -26,7 +26,7 @@ export interface ManifestGoal { /** * Original goal file path when the goal came from a file. */ - 'path'?: string; + 'path'?: string | null; } export const ManifestGoalTypeEnum = { diff --git a/lib/packages/fabro-api-client/src/models/model-costs.ts b/lib/packages/fabro-api-client/src/models/model-costs.ts index 4c91891f9..ac7205f35 100644 --- a/lib/packages/fabro-api-client/src/models/model-costs.ts +++ b/lib/packages/fabro-api-client/src/models/model-costs.ts @@ -21,14 +21,14 @@ export interface ModelCosts { /** * Cost per million input tokens in USD. */ - 'input_cost_per_mtok'?: number; + 'input_cost_per_mtok'?: number | null; /** * Cost per million output tokens in USD. */ - 'output_cost_per_mtok'?: number; + 'output_cost_per_mtok'?: number | null; /** * Cost per million cached input tokens in USD. */ - 'cache_input_cost_per_mtok'?: number; + 'cache_input_cost_per_mtok'?: number | null; } diff --git a/lib/packages/fabro-api-client/src/models/model-limits.ts b/lib/packages/fabro-api-client/src/models/model-limits.ts index 795a32b8e..0150717d2 100644 --- a/lib/packages/fabro-api-client/src/models/model-limits.ts +++ b/lib/packages/fabro-api-client/src/models/model-limits.ts @@ -25,6 +25,6 @@ export interface ModelLimits { /** * Maximum output tokens, if known. */ - 'max_output'?: number; + 'max_output'?: number | null; } diff --git a/lib/packages/fabro-api-client/src/models/model-test-result.ts b/lib/packages/fabro-api-client/src/models/model-test-result.ts index f21c5fbda..ba3abc7c9 100644 --- a/lib/packages/fabro-api-client/src/models/model-test-result.ts +++ b/lib/packages/fabro-api-client/src/models/model-test-result.ts @@ -29,7 +29,7 @@ export interface ModelTestResult { /** * Error details when status is \"error\". */ - 'error_message'?: string; + 'error_message'?: string | null; } export const ModelTestResultStatusEnum = { diff --git a/lib/packages/fabro-api-client/src/models/model.ts b/lib/packages/fabro-api-client/src/models/model.ts index 45fb04f44..0c82c2f6c 100644 --- a/lib/packages/fabro-api-client/src/models/model.ts +++ b/lib/packages/fabro-api-client/src/models/model.ts @@ -47,13 +47,13 @@ export interface Model { /** * Training data cutoff date (YYYY-MM-DD). */ - 'training'?: string; + 'training'?: string | null; 'features': ModelFeatures; 'costs': ModelCosts; /** * Estimated output tokens per second. */ - 'estimated_output_tps'?: number; + 'estimated_output_tps'?: number | null; /** * Alternative names that resolve to this model. */ diff --git a/lib/packages/fabro-api-client/src/models/node-state.ts b/lib/packages/fabro-api-client/src/models/node-state.ts index f25ce1f8d..9f7f823f2 100644 --- a/lib/packages/fabro-api-client/src/models/node-state.ts +++ b/lib/packages/fabro-api-client/src/models/node-state.ts @@ -21,15 +21,15 @@ import type { NodeStatusRecord } from './node-status-record'; * Internal node projection state. */ export interface NodeState { - 'prompt'?: string; - 'response'?: string; + 'prompt'?: string | null; + 'response'?: string | null; 'status'?: NodeStatusRecord | null; 'provider_used'?: any; - 'diff'?: string; + 'diff'?: string | null; 'script_invocation'?: any; 'script_timing'?: any; 'parallel_results'?: any; - 'stdout'?: string; - 'stderr'?: string; + 'stdout'?: string | null; + 'stderr'?: string | null; } diff --git a/lib/packages/fabro-api-client/src/models/node-status-record.ts b/lib/packages/fabro-api-client/src/models/node-status-record.ts index a899a5116..6df95ddd8 100644 --- a/lib/packages/fabro-api-client/src/models/node-status-record.ts +++ b/lib/packages/fabro-api-client/src/models/node-status-record.ts @@ -22,8 +22,8 @@ import type { InternalStageStatus } from './internal-stage-status'; */ export interface NodeStatusRecord { 'status': InternalStageStatus; - 'notes'?: string; - 'failure_reason'?: string; + 'notes'?: string | null; + 'failure_reason'?: string | null; 'timestamp': string; } diff --git a/lib/packages/fabro-api-client/src/models/preflight-check-result.ts b/lib/packages/fabro-api-client/src/models/preflight-check-result.ts index 2faf5771e..947447955 100644 --- a/lib/packages/fabro-api-client/src/models/preflight-check-result.ts +++ b/lib/packages/fabro-api-client/src/models/preflight-check-result.ts @@ -22,7 +22,7 @@ export interface PreflightCheckResult { 'status': PreflightCheckResultStatusEnum; 'summary': string; 'details': Array; - 'remediation'?: string; + 'remediation'?: string | null; } export const PreflightCheckResultStatusEnum = { diff --git a/lib/packages/fabro-api-client/src/models/preflight-workflow-summary.ts b/lib/packages/fabro-api-client/src/models/preflight-workflow-summary.ts index e5ecdba75..075594408 100644 --- a/lib/packages/fabro-api-client/src/models/preflight-workflow-summary.ts +++ b/lib/packages/fabro-api-client/src/models/preflight-workflow-summary.ts @@ -19,7 +19,7 @@ import type { WorkflowDiagnostic } from './workflow-diagnostic'; export interface PreflightWorkflowSummary { 'name': string; - 'graph_path'?: string; + 'graph_path'?: string | null; 'nodes': number; 'edges': number; 'goal': string; diff --git a/lib/packages/fabro-api-client/src/models/prune-runs-response.ts b/lib/packages/fabro-api-client/src/models/prune-runs-response.ts index 4382b5afe..5e985b061 100644 --- a/lib/packages/fabro-api-client/src/models/prune-runs-response.ts +++ b/lib/packages/fabro-api-client/src/models/prune-runs-response.ts @@ -28,7 +28,7 @@ export interface PruneRunsResponse { /** * Matched runs when dry-run is enabled. */ - 'runs'?: Array; + 'runs'?: Array | null; /** * Count of runs matching the prune filters. */ diff --git a/lib/packages/fabro-api-client/src/models/repo-check-response.ts b/lib/packages/fabro-api-client/src/models/repo-check-response.ts index 1e6d61a3c..453423c71 100644 --- a/lib/packages/fabro-api-client/src/models/repo-check-response.ts +++ b/lib/packages/fabro-api-client/src/models/repo-check-response.ts @@ -36,15 +36,15 @@ export interface RepoCheckResponse { /** * Default branch name, if accessible. */ - 'default_branch'?: string; + 'default_branch'?: string | null; /** * Whether the repository is private, if accessible. */ - 'private'?: boolean; + 'private'?: boolean | null; 'permissions'?: RepoCheckResponsePermissions; /** * GitHub App installation URL when the repo is not yet accessible. */ - 'install_url'?: string; + 'install_url'?: string | null; } diff --git a/lib/packages/fabro-api-client/src/models/run-billing-totals.ts b/lib/packages/fabro-api-client/src/models/run-billing-totals.ts index 51e9980a5..2cbf731bc 100644 --- a/lib/packages/fabro-api-client/src/models/run-billing-totals.ts +++ b/lib/packages/fabro-api-client/src/models/run-billing-totals.ts @@ -49,6 +49,6 @@ export interface RunBillingTotals { /** * Total billed USD amount in micros. */ - 'total_usd_micros'?: number; + 'total_usd_micros'?: number | null; } diff --git a/lib/packages/fabro-api-client/src/models/run-event.ts b/lib/packages/fabro-api-client/src/models/run-event.ts index f7319b815..5f47658cf 100644 --- a/lib/packages/fabro-api-client/src/models/run-event.ts +++ b/lib/packages/fabro-api-client/src/models/run-event.ts @@ -26,27 +26,27 @@ export interface RunEvent { 'id': string; 'ts': string; 'run_id': string; - 'node_id'?: string; - 'node_label'?: string; + 'node_id'?: string | null; + 'node_label'?: string | null; /** * Stage execution identity, formatted as \"{node_id}@{visit}\". */ - 'stage_id'?: string; + 'stage_id'?: string | null; /** * Durable identity of one execution of a parallel node, formatted as \"{node_id}@{visit}\". */ - 'parallel_group_id'?: string; + 'parallel_group_id'?: string | null; /** * Durable identity of one branch within a parallel execution, formatted as \"{parallel_group_id}:{index}\". */ - 'parallel_branch_id'?: string; - 'session_id'?: string; - 'parent_session_id'?: string; + 'parallel_branch_id'?: string | null; + 'session_id'?: string | null; + 'parent_session_id'?: string | null; /** * Stable identifier for a tool call, present on agent.tool.* events and other durable events that directly describe the same tool call. */ - 'tool_call_id'?: string; - 'actor'?: ActorRef; + 'tool_call_id'?: string | null; + 'actor'?: ActorRef | null; /** * Event type discriminator. */ diff --git a/lib/packages/fabro-api-client/src/models/run-manifest.ts b/lib/packages/fabro-api-client/src/models/run-manifest.ts index cfac73005..06d015900 100644 --- a/lib/packages/fabro-api-client/src/models/run-manifest.ts +++ b/lib/packages/fabro-api-client/src/models/run-manifest.ts @@ -43,7 +43,7 @@ export interface RunManifest { /** * Optional pre-generated run ID to use instead of allocating a new ULID. */ - 'run_id'?: string; + 'run_id'?: string | null; /** * CLI working directory at invocation time. */ diff --git a/lib/packages/fabro-api-client/src/models/run-projection.ts b/lib/packages/fabro-api-client/src/models/run-projection.ts index 5ea6b401b..4ae2f47a0 100644 --- a/lib/packages/fabro-api-client/src/models/run-projection.ts +++ b/lib/packages/fabro-api-client/src/models/run-projection.ts @@ -30,22 +30,22 @@ import type { RunStatusRecord } from './run-status-record'; * Raw internal run projection derived from the event log. */ export interface RunProjection { - 'run'?: { [key: string]: any; }; - 'graph_source'?: string; - 'start'?: { [key: string]: any; }; + 'run'?: { [key: string]: any; } | null; + 'graph_source'?: string | null; + 'start'?: { [key: string]: any; } | null; 'status'?: RunStatusRecord | null; 'checkpoint'?: RunCheckpoint | null; /** * Sequence-tagged checkpoint history entries as `[seq, checkpoint]`. */ 'checkpoints'?: Array>; - 'conclusion'?: { [key: string]: any; }; - 'retro'?: { [key: string]: any; }; - 'retro_prompt'?: string; - 'retro_response'?: string; - 'sandbox'?: { [key: string]: any; }; - 'final_patch'?: string; - 'pull_request'?: { [key: string]: any; }; + 'conclusion'?: { [key: string]: any; } | null; + 'retro'?: { [key: string]: any; } | null; + 'retro_prompt'?: string | null; + 'retro_response'?: string | null; + 'sandbox'?: { [key: string]: any; } | null; + 'final_patch'?: string | null; + 'pull_request'?: { [key: string]: any; } | null; /** * Map from StageId (`node_id@visit`) to NodeState. */ diff --git a/lib/packages/fabro-api-client/src/models/run-status-response.ts b/lib/packages/fabro-api-client/src/models/run-status-response.ts index 2c7c0a17c..c3e3359b2 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-response.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-response.ts @@ -40,8 +40,8 @@ export interface RunStatusResponse { * Position in the queue (1-based). Only present when status is `queued`. */ 'queue_position'?: number; - 'status_reason'?: StatusReason; - 'pending_control'?: RunControlAction; + 'status_reason'?: StatusReason | null; + 'pending_control'?: RunControlAction | null; /** * Timestamp when the run was created. */ diff --git a/lib/packages/fabro-api-client/src/models/store-run-summary.ts b/lib/packages/fabro-api-client/src/models/store-run-summary.ts index e5d68c84a..5c520dfa7 100644 --- a/lib/packages/fabro-api-client/src/models/store-run-summary.ts +++ b/lib/packages/fabro-api-client/src/models/store-run-summary.ts @@ -22,17 +22,17 @@ import type { RunControlAction } from './run-control-action'; */ export interface StoreRunSummary { 'run_id': string; - 'workflow_name'?: string; - 'workflow_slug'?: string; - 'goal'?: string; + 'workflow_name'?: string | null; + 'workflow_slug'?: string | null; + 'goal'?: string | null; 'labels': { [key: string]: string; }; - 'host_repo_path'?: string; - 'start_time'?: string; - 'status'?: string; - 'status_reason'?: string; - 'pending_control'?: RunControlAction; - 'duration_ms'?: number; - 'total_usd_micros'?: number; + 'host_repo_path'?: string | null; + 'start_time'?: string | null; + 'status'?: string | null; + 'status_reason'?: string | null; + 'pending_control'?: RunControlAction | null; + 'duration_ms'?: number | null; + 'total_usd_micros'?: number | null; } diff --git a/lib/packages/fabro-api-client/src/models/system-info-response.ts b/lib/packages/fabro-api-client/src/models/system-info-response.ts index beebc85b5..ad2e8c855 100644 --- a/lib/packages/fabro-api-client/src/models/system-info-response.ts +++ b/lib/packages/fabro-api-client/src/models/system-info-response.ts @@ -31,11 +31,11 @@ export interface SystemInfoResponse { /** * Build git SHA when available. */ - 'git_sha'?: string; + 'git_sha'?: string | null; /** * Build date when available. */ - 'build_date'?: string; + 'build_date'?: string | null; /** * Target operating system. */ diff --git a/lib/packages/fabro-api-client/src/models/workflow-diagnostic.ts b/lib/packages/fabro-api-client/src/models/workflow-diagnostic.ts index cb15e046f..e38743e24 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-diagnostic.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-diagnostic.ts @@ -18,9 +18,9 @@ export interface WorkflowDiagnostic { 'rule': string; 'severity': WorkflowDiagnosticSeverityEnum; 'message': string; - 'node_id'?: string; - 'edge'?: Array; - 'fix'?: string; + 'node_id'?: string | null; + 'edge'?: Array | null; + 'fix'?: string | null; } export const WorkflowDiagnosticSeverityEnum = {