diff --git a/Cargo.lock b/Cargo.lock index 9fba2f78c..5d47c63c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2255,7 +2255,7 @@ dependencies = [ [[package]] name = "fabro-acp" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "agent-client-protocol", "agent-client-protocol-tokio", @@ -2274,7 +2274,7 @@ dependencies = [ [[package]] name = "fabro-agent" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -2320,7 +2320,7 @@ dependencies = [ [[package]] name = "fabro-api" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "chrono", "fabro-automation", @@ -2343,7 +2343,7 @@ dependencies = [ [[package]] name = "fabro-auth" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -2368,7 +2368,7 @@ dependencies = [ [[package]] name = "fabro-automation" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -2388,11 +2388,11 @@ dependencies = [ [[package]] name = "fabro-build-support" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" [[package]] name = "fabro-checkpoint" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "chrono", "fabro-config", @@ -2408,7 +2408,7 @@ dependencies = [ [[package]] name = "fabro-cli" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "assert_cmd", @@ -2510,7 +2510,7 @@ dependencies = [ [[package]] name = "fabro-client" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "bytes", @@ -2539,7 +2539,7 @@ dependencies = [ [[package]] name = "fabro-config" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -2569,7 +2569,7 @@ dependencies = [ [[package]] name = "fabro-core" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "async-trait", "fabro-types", @@ -2584,7 +2584,7 @@ dependencies = [ [[package]] name = "fabro-db" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -2596,7 +2596,7 @@ dependencies = [ [[package]] name = "fabro-dev" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "assert_cmd", @@ -2615,7 +2615,7 @@ dependencies = [ [[package]] name = "fabro-dump" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "bytes", @@ -2629,7 +2629,7 @@ dependencies = [ [[package]] name = "fabro-environment" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -2651,7 +2651,7 @@ dependencies = [ [[package]] name = "fabro-github" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "base64", @@ -2673,7 +2673,7 @@ dependencies = [ [[package]] name = "fabro-graphviz" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "fabro-types", @@ -2688,7 +2688,7 @@ dependencies = [ [[package]] name = "fabro-hooks" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "async-trait", "fabro-agent", @@ -2711,7 +2711,7 @@ dependencies = [ [[package]] name = "fabro-http" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "fabro-static", "http 1.4.0", @@ -2721,7 +2721,7 @@ dependencies = [ [[package]] name = "fabro-install" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "base64", @@ -2740,7 +2740,7 @@ dependencies = [ [[package]] name = "fabro-interview" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "async-trait", "dialoguer", @@ -2755,7 +2755,7 @@ dependencies = [ [[package]] name = "fabro-llm" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -2797,7 +2797,7 @@ dependencies = [ [[package]] name = "fabro-macros" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "clap", "fabro-options-metadata", @@ -2808,7 +2808,7 @@ dependencies = [ [[package]] name = "fabro-manifest" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "fabro-api", @@ -2816,9 +2816,11 @@ dependencies = [ "fabro-github", "fabro-graphviz", "fabro-template", + "fabro-test", "fabro-types", "fabro-workflow", "git2", + "insta", "serde_json", "temp-env", "tempfile", @@ -2827,7 +2829,7 @@ dependencies = [ [[package]] name = "fabro-mcp" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "axum", @@ -2847,7 +2849,7 @@ dependencies = [ [[package]] name = "fabro-mcp-server" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -2875,7 +2877,7 @@ dependencies = [ [[package]] name = "fabro-mcp-store" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "chrono", "fabro-db", @@ -2893,7 +2895,7 @@ dependencies = [ [[package]] name = "fabro-model" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "fabro-static", "http 1.4.0", @@ -2909,7 +2911,7 @@ dependencies = [ [[package]] name = "fabro-oauth" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "axum", @@ -2931,7 +2933,7 @@ dependencies = [ [[package]] name = "fabro-options-metadata" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "serde", "serde_json", @@ -2939,7 +2941,7 @@ dependencies = [ [[package]] name = "fabro-proc" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "cc", "libc", @@ -2948,7 +2950,7 @@ dependencies = [ [[package]] name = "fabro-redact" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "aho-corasick", "ref-cast", @@ -2964,7 +2966,7 @@ dependencies = [ [[package]] name = "fabro-sandbox" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -3008,7 +3010,7 @@ dependencies = [ [[package]] name = "fabro-server" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -3058,6 +3060,7 @@ dependencies = [ "fabro-variable", "fabro-vault", "fabro-workflow", + "fabro-workflow-version", "futures-util", "globset", "hex", @@ -3102,7 +3105,7 @@ dependencies = [ [[package]] name = "fabro-slack" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "fabro-http", "fabro-interview", @@ -3124,18 +3127,18 @@ dependencies = [ [[package]] name = "fabro-spa" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "rust-embed", ] [[package]] name = "fabro-static" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" [[package]] name = "fabro-store" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "async-trait", "bytes", @@ -3165,7 +3168,7 @@ dependencies = [ [[package]] name = "fabro-telemetry" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "base64", @@ -3191,7 +3194,7 @@ dependencies = [ [[package]] name = "fabro-template" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "fabro-types", @@ -3205,7 +3208,7 @@ dependencies = [ [[package]] name = "fabro-test" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "assert_cmd", @@ -3230,7 +3233,7 @@ dependencies = [ [[package]] name = "fabro-tool" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -3251,7 +3254,7 @@ dependencies = [ [[package]] name = "fabro-tracker" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-trait", @@ -3265,7 +3268,7 @@ dependencies = [ [[package]] name = "fabro-types" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "chrono", "clap", @@ -3288,7 +3291,7 @@ dependencies = [ [[package]] name = "fabro-util" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "console 0.15.11", @@ -3311,7 +3314,7 @@ dependencies = [ [[package]] name = "fabro-validate" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "fabro-acp", "fabro-graphviz", @@ -3324,7 +3327,7 @@ dependencies = [ [[package]] name = "fabro-variable" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -3341,7 +3344,7 @@ dependencies = [ [[package]] name = "fabro-vault" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "chrono", @@ -3360,7 +3363,7 @@ dependencies = [ [[package]] name = "fabro-workflow" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "assert_cmd", @@ -3428,6 +3431,22 @@ dependencies = [ "walkdir", ] +[[package]] +name = "fabro-workflow-version" +version = "0.331.0-nightly.0" +dependencies = [ + "fabro-config", + "fabro-graphviz", + "fabro-store", + "fabro-template", + "fabro-types", + "object_store", + "serde", + "serde_json", + "thiserror 2.0.18", + "tokio", +] + [[package]] name = "fail-parallel" version = "0.5.1" @@ -8525,7 +8544,7 @@ dependencies = [ [[package]] name = "twin-github" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "axum", "base64", @@ -8544,7 +8563,7 @@ dependencies = [ [[package]] name = "twin-openai" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" dependencies = [ "anyhow", "async-stream", diff --git a/Cargo.toml b/Cargo.toml index fd260535c..bb339e93f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ resolver = "2" [workspace.package] edition = "2021" -version = "0.316.0-nightly.0" +version = "0.331.0-nightly.0" license = "MIT" [workspace.dependencies] diff --git a/docs/internal/events.md b/docs/internal/events.md index 2920159e0..dfc7403b4 100644 --- a/docs/internal/events.md +++ b/docs/internal/events.md @@ -77,7 +77,7 @@ Emitted when the run record is created. | `source_directory` | string? | Submitter-side source directory | | `workflow_slug` | string? | Workflow slug | | `provenance` | object | Actor and request provenance | -| `manifest_blob` | string? | Blob id for the submitted manifest | +| `manifest_blob` | string? | Blob hash for the submitted manifest | | `git` | object? | Git provenance observed before the run: normalized `origin_url`, `branch`, optional `sha`, and `dirty` status | | `fork_source_ref` | object? | Source run/checkpoint reference when this run was forked | | `in_place` | boolean | Whether the run was created with `--in-place` (no git checkpoints) | diff --git a/docs/internal/server-secrets-strategy.md b/docs/internal/server-secrets-strategy.md index 76f12087d..839f2bcec 100644 --- a/docs/internal/server-secrets-strategy.md +++ b/docs/internal/server-secrets-strategy.md @@ -13,7 +13,7 @@ when does it resolve** — see [Which process resolves what](#which-process-reso - Resolution is snapshot-based: env and file are read once at construction, then treated as immutable for the life of the process. - `process env` wins over `server.env` on conflicts. - Optional integration secrets are vault-only in the **server process**. Do not add optional server integrations to `ServerSecrets`, and do not add bespoke env fallback paths to it. -- Not every credential is a `ServerSecrets` or vault lookup. A third mechanism exists: **settings-declared credentials** in `InterpString` fields, resolved at consumption time from `{{ env.NAME }}` or `{{ secrets.NAME }}`. See [Settings-declared credentials](#settings-declared-credentials). +- Not every credential is a `ServerSecrets` or vault lookup. A third mechanism exists: **settings-declared credentials** in `InterpString` fields, resolved at consumption time from `{{ secrets.NAME }}`. See [Settings-declared credentials](#settings-declared-credentials). - `fabro server start` never generates secrets. Missing required secrets are a startup error. - `std::env::set_var` and `std::env::remove_var` are banned workspace-wide. Tests are not exempt. Enforced by clippy via `disallowed_methods` in `clippy.toml`; intentional exceptions must be annotated with a scoped `#[expect(clippy::disallowed_methods, reason = "...")]` at the call site. @@ -70,7 +70,6 @@ than saying "server runtime", which is ambiguous. | Bootstrap server secret | Server process, via `ServerSecrets` | Once at construction, then immutable | | Optional integration secret | Server process or worker, via the vault | At use | | `{{ vars.NAME }}` | Server process | When the run is created, from that run's variable snapshot | -| `{{ env.NAME }}` | The process that owns the value (usually the worker) | At consumption time | | `{{ secrets.NAME }}` | The process that owns the value, against the server vault | At consumption time | `docs/public/agents/mcp.mdx` documents the same split for MCP server configuration and is a good @@ -80,18 +79,17 @@ worked example of the shape. Some credentials are declared in settings rather than looked up by name. Those fields are `InterpString` (`lib/foundation/fabro-types/src/settings/interp.rs`), which supports narrow -`{{ namespace.NAME }}` tokens with no template logic. Three namespaces resolve: `env` (process -environment, consumption time), `secrets` (vault, consumption time), and `vars` (non-sensitive run -variables, substituted early at run creation). A token whose namespace is unavailable in the -resolution context fails loudly. +`{{ namespace.NAME }}` tokens with no template logic. Two namespaces resolve: `secrets` (vault, +consumption time) and `vars` (non-sensitive run variables, substituted early at run creation). +`{{ env.NAME }}` tokens still parse but never resolve; they fail loudly with a migration message. A +token whose namespace is unavailable in the resolution context also fails loudly. -The reference implementation is LLM provider `extra_headers`, resolved against env plus vault at +The reference implementation is LLM provider `extra_headers`, resolved against the vault at `lib/foundation/fabro-auth/src/resolve.rs:376-378`: ```toml [llm.providers.example.extra_headers] authorization = "Bearer {{ secrets.EXAMPLE_TOKEN }}" -x-tenant = "{{ env.EXAMPLE_TENANT }}" ``` Use this mechanism when the credential belongs to an operator-configured integration declared in @@ -149,7 +147,7 @@ First pick the mechanism. These are the only three: |---|---|---| | Bootstrap server secret | Platform env or install-written `server.env` | `state.server_secret(...)` | | Optional integration secret | Vault (`fabro secret set`, `fabro install`) | `state.vault_secret(...)` | -| Settings-declared credential | `{{ secrets.* }}` or `{{ env.* }}` in an `InterpString` settings field | Resolved at consumption time by the owning process | +| Settings-declared credential | `{{ secrets.* }}` in an `InterpString` settings field | Resolved at consumption time by the owning process | Then: diff --git a/docs/public/agents/outputs.mdx b/docs/public/agents/outputs.mdx index b36259b25..004c4f0e8 100644 --- a/docs/public/agents/outputs.mdx +++ b/docs/public/agents/outputs.mdx @@ -219,10 +219,10 @@ When Fabro builds a [preamble](/execution/context#preamble-construction) for a d - **plan**: success - Model: claude-sonnet-4-5, 12.4k tokens in / 3.2k out - Files: src/main.rs, tests/api_test.rs - - Response: See: /path/to/runtime/blobs/.json + - Response: See: /path/to/runtime/blobs/.json - **test**: success - Script: `cargo test 2>&1 || true` - - Stdout: See: /path/to/runtime/blobs/.json + - Stdout: See: /path/to/runtime/blobs/.json ``` This keeps preambles concise while still giving agents a path to read the full output if needed. @@ -237,7 +237,7 @@ Captured stage artifacts such as screenshots, videos, reports, and traces still For remote sandboxes (Docker, Daytona), execution-time file access happens inside the sandbox filesystem. -- Blob refs are materialized into `{working_directory}/.fabro/blobs/{blob_id}.json` +- Blob refs are materialized into `{working_directory}/.fabro/blobs/{blob_hash}.json` - Explicit non-blob `file://` refs keep the existing copy-on-demand behavior and are copied into `{working_directory}/.fabro/artifacts/{filename}` when needed In both cases, downstream handlers and agents continue to consume ordinary `file://` pointers during execution. diff --git a/docs/public/api-reference/fabro-api.yaml b/docs/public/api-reference/fabro-api.yaml index 261badbbb..8d1c8fa14 100644 --- a/docs/public/api-reference/fabro-api.yaml +++ b/docs/public/api-reference/fabro-api.yaml @@ -1,7 +1,7 @@ openapi: "3.1.0" info: title: Fabro Run API - version: "0.1.0" + version: "0.2.0" description: HTTP API for managing Fabro workflow run executions. tags: @@ -33,6 +33,8 @@ tags: description: Internal run details (stages, turns, context, configuration) - name: Workflows description: Workflow definitions and execution + - name: Workflow Versions + description: Immutable, content-addressed workflow packages - name: Billing description: Token counts and billed totals - name: Insights @@ -1065,6 +1067,69 @@ paths: schema: $ref: "#/components/schemas/ErrorResponse" + # ── Workflow Versions ───────────────────────────────────────────────── + + /api/v1/workflow-versions: + post: + operationId: createWorkflowVersion + tags: [Workflow Versions] + summary: Create Workflow Version + description: >- + Validates and stores an immutable workflow package in content-addressed + storage. Repeating the same canonical content returns the same identifier. + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/WorkflowVersion" + responses: + "201": + description: Workflow version stored or already present + content: + application/json: + schema: + $ref: "#/components/schemas/CreateWorkflowVersionResponse" + "400": + description: Malformed JSON (`invalid_json`) + headers: + x-request-id: + $ref: "#/components/headers/XRequestId" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "413": + description: Request body exceeds 2 MiB (`workflow_version_too_large`) + headers: + x-request-id: + $ref: "#/components/headers/XRequestId" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "422": + description: >- + Invalid workflow content (`workflow_version_invalid`) or an absent, + invalid, or non-canonical dependency + (`workflow_version_dependency_not_found`) + headers: + x-request-id: + $ref: "#/components/headers/XRequestId" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + "500": + description: Workflow version storage failed + headers: + x-request-id: + $ref: "#/components/headers/XRequestId" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + # ── Runs ────────────────────────────────────────────────────────────── /api/v1/runs: @@ -3027,7 +3092,7 @@ paths: operationId: writeRunBlob tags: [Run Internals] summary: Write Run Blob - description: Writes an opaque binary blob and returns its content-addressed blob identifier. + description: Writes an opaque binary blob and returns its content-addressed blob hash. parameters: - $ref: "#/components/parameters/RunId" requestBody: @@ -3072,15 +3137,15 @@ paths: schema: $ref: "#/components/schemas/ErrorResponse" - /api/v1/runs/{id}/blobs/{blobId}: + /api/v1/runs/{id}/blobs/{blobHash}: get: operationId: readRunBlob tags: [Run Internals] summary: Read Run Blob - description: Reads a previously stored blob by identifier. + description: Reads a previously stored blob by hash. parameters: - $ref: "#/components/parameters/RunId" - - $ref: "#/components/parameters/BlobId" + - $ref: "#/components/parameters/BlobHash" responses: "200": description: Blob contents @@ -5909,14 +5974,13 @@ components: default: 65536 example: 65536 - BlobId: - name: blobId + BlobHash: + name: blobHash in: path required: true - description: Content-addressed blob identifier. + description: Content-addressed blob hash. schema: - type: string - pattern: '^[0-9a-f]{64}$' + $ref: "#/components/schemas/BlobHash" example: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 ArtifactFilename: @@ -9074,6 +9138,73 @@ components: detail: $ref: "#/components/schemas/FailureDetail" + WorkflowPath: + description: >- + Canonical portable path inside one workflow version. Paths are UTF-8, + relative, at most 240 bytes and 16 components, and cannot contain empty, + dot, parent, backslash, control, tilde-root, or drive-letter segments. + Map keys receive stricter byte and structural validation in the domain + model than OpenAPI can express. + type: string + minLength: 1 + maxLength: 240 + example: graphs/main.fabro + + WorkflowVersionId: + description: >- + SHA-256 identity of validated canonical workflow-version bytes. Hex input is + case-insensitive; Fabro emits the canonical lowercase form. + type: string + pattern: "^[0-9A-Fa-f]{64}$" + example: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + + WorkflowVersion: + description: >- + Complete immutable package for one rooted workflow. It contains at most + 512 files and 512 workflow dependencies, each file is at most 512 KiB + of UTF-8 content, and its compact canonical JSON representation is at + most 2 MiB. + type: object + additionalProperties: false + required: + - entrypoint + - files + - workflow_dependencies + properties: + entrypoint: + $ref: "#/components/schemas/WorkflowPath" + files: + type: object + description: >- + Workflow-local text files keyed by canonical path. Keys receive + stricter domain validation than OpenAPI can express; each value is + limited to 512 KiB of UTF-8 bytes. + maxProperties: 512 + propertyNames: + $ref: "#/components/schemas/WorkflowPath" + additionalProperties: + type: string + workflow_dependencies: + type: object + description: >- + Exact stored workflow-version IDs keyed by resolved child-workflow + path. Keys receive stricter domain validation than OpenAPI can express. + maxProperties: 512 + propertyNames: + $ref: "#/components/schemas/WorkflowPath" + additionalProperties: + $ref: "#/components/schemas/WorkflowVersionId" + + CreateWorkflowVersionResponse: + description: Identity of the stored immutable workflow version. + type: object + additionalProperties: false + required: + - workflow_version_id + properties: + workflow_version_id: + $ref: "#/components/schemas/WorkflowVersionId" + RunManifest: description: Self-contained workflow run manifest. type: object @@ -10153,16 +10284,22 @@ components: description: Assigned event sequence number. example: 42 + BlobHash: + description: >- + Content-addressed SHA-256 hash of a stored blob. Hex input is case-insensitive; + Fabro emits the canonical lowercase form. + type: string + pattern: "^[0-9A-Fa-f]{64}$" + example: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 + WriteBlobResponse: - description: Content-addressed identifier for a stored blob. + description: Content-addressed hash of a stored blob. type: object required: - - id + - hash properties: - id: - type: string - description: Blob identifier. - example: 550e8400-e29b-41d4-a716-446655440000 + hash: + $ref: "#/components/schemas/BlobHash" CommandTermination: description: Terminal state for a command execution. @@ -10271,7 +10408,7 @@ components: example: src/lib.rs sha256: type: ["string", "null"] - description: Optional lowercase hex SHA-256 checksum for the file contents. + description: Optional SHA-256 checksum for the file contents; hex input is case-insensitive. example: 3f785df4c5b7d3f1f4c1f0ecb0f55f1d9f6f6a3d9f0a8a98f7a74f29d1f81a2c expected_bytes: type: ["integer", "null"] diff --git a/docs/public/execution/context.mdx b/docs/public/execution/context.mdx index 2ef5b0bbb..19f9c1d2c 100644 --- a/docs/public/execution/context.mdx +++ b/docs/public/execution/context.mdx @@ -243,8 +243,8 @@ Checkpoints and checkpoint-completed events persist these `blob://` refs, not ho Before Fabro builds a preamble or starts the next stage, it resolves any blob refs into execution-local files so handlers and agents still see normal `file://` references: -- Local execution materializes blobs under `{run_dir}/runtime/blobs/{blob_id}.json` -- Remote sandboxes materialize blobs under `{working_directory}/.fabro/blobs/{blob_id}.json` +- Local execution materializes blobs under `{run_dir}/runtime/blobs/{blob_hash}.json` +- Remote sandboxes materialize blobs under `{working_directory}/.fabro/blobs/{blob_hash}.json` These materialized `file://` paths are runtime-only. They are not written back into durable context snapshots. diff --git a/docs/public/execution/run-configuration.mdx b/docs/public/execution/run-configuration.mdx index a8f1bc927..d2ce9bd5e 100644 --- a/docs/public/execution/run-configuration.mdx +++ b/docs/public/execution/run-configuration.mdx @@ -321,7 +321,7 @@ memory = "8GB" | `network.allow` | CIDRs for `cidr_allow_list`; entries are validated as CIDRs. | | `lifecycle.preserve` | Keep the created sandbox after the run finishes. | | `lifecycle.stop_on_terminal` | Stop the sandbox when the run reaches a terminal state. | -| `lifecycle.auto_stop` | Daytona auto-stop duration, such as `"30m"`. | +| `lifecycle.auto_stop` | Daytona auto-stop duration, such as `"30m"`. Defaults to `"120m"`; `"0s"` disables auto-stop. | | `labels` | Provider labels. Merge by key across layers. | | `env` | Environment variables passed to command and agent execution. Merge by key across layers. | diff --git a/docs/public/integrations/daytona.mdx b/docs/public/integrations/daytona.mdx index 6ad19b9b3..1a2f25790 100644 --- a/docs/public/integrations/daytona.mdx +++ b/docs/public/integrations/daytona.mdx @@ -198,6 +198,10 @@ The `lifecycle.auto_stop` setting tells Daytona to stop the sandbox after a peri auto_stop = "30m" ``` +When `auto_stop` is unset, Fabro applies a default of 120 minutes so a sandbox leaked by an interrupted run is still reclaimed. Set `auto_stop = "0s"` to disable auto-stop and let the sandbox run indefinitely. + +Daytona counts inactivity from the last sandbox interaction (a command, file operation, or other API call). Time an agent spends on LLM inference does not touch the sandbox, so intervals shorter than your longest inference call risk stopping the sandbox mid-run. + ## Server defaults When running via `fabro server start`, the server config at `~/.fabro/settings.toml` can set default Daytona settings for all runs. Run config TOML values override server defaults. Labels are **merged** — run config labels win on key collisions. The `network` setting uses simple override (run config replaces the server default entirely). diff --git a/lib/apps/fabro-cli/src/commands/dump.rs b/lib/apps/fabro-cli/src/commands/dump.rs index b3938e12a..9c0454da8 100644 --- a/lib/apps/fabro-cli/src/commands/dump.rs +++ b/lib/apps/fabro-cli/src/commands/dump.rs @@ -86,8 +86,8 @@ async fn write_run_dump( dump.add_file_bytes("run.log", log); } - dump.hydrate_referenced_blobs_with_reader(|blob_id| { - Box::pin(async move { client.read_run_blob(run_id, &blob_id).await }) + dump.hydrate_referenced_blobs_with_reader(|blob_hash| { + Box::pin(async move { client.read_run_blob(run_id, &blob_hash).await }) }) .await?; diff --git a/lib/apps/fabro-cli/src/commands/run/output.rs b/lib/apps/fabro-cli/src/commands/run/output.rs index 136d2b506..9de4a3158 100644 --- a/lib/apps/fabro-cli/src/commands/run/output.rs +++ b/lib/apps/fabro-cli/src/commands/run/output.rs @@ -5,7 +5,7 @@ use anyhow::{Context as _, Result}; use cli_table::format::{Border, Justify, Separator}; use cli_table::{Cell, CellStruct, Style, Table}; use fabro_api::types; -use fabro_types::{PullRequestLink, RunBlobId, RunId, StageId, parse_blob_ref}; +use fabro_types::{PullRequestLink, RunId, StageId, parse_blob_ref}; use fabro_util::check_report::{CheckDetail, CheckReport, CheckResult, CheckSection, CheckStatus}; use fabro_util::error::render_with_causes; use fabro_util::printer::Printer; @@ -325,11 +325,11 @@ async fn resolve_response_string( run_id: &RunId, response: &str, ) -> Result> { - let Some(blob_id) = blob_id_from_response(response) else { + let Some(blob_hash) = parse_blob_ref(response) else { return Ok(Some(response.to_string())); }; - let Some(bytes) = client.read_run_blob(run_id, &blob_id).await? else { + let Some(bytes) = client.read_run_blob(run_id, &blob_hash).await? else { return Ok(None); }; let value: serde_json::Value = @@ -341,10 +341,6 @@ async fn resolve_response_string( })) } -fn blob_id_from_response(response: &str) -> Option { - parse_blob_ref(response) -} - async fn list_artifact_display_entries_with_client( client: &server_client::Client, run_id: &RunId, diff --git a/lib/apps/fabro-cli/src/commands/run/runner.rs b/lib/apps/fabro-cli/src/commands/run/runner.rs index 1d825d3c8..713838555 100644 --- a/lib/apps/fabro-cli/src/commands/run/runner.rs +++ b/lib/apps/fabro-cli/src/commands/run/runner.rs @@ -21,7 +21,7 @@ use fabro_store::{EventEnvelope, RunProjection, RunProjectionReducer}; use fabro_tool::fabro_client::ClientBackend; use fabro_types::settings::run::{RunMode, RunNamespace}; use fabro_types::{ - ArtifactUpload, EventBody, FailureReason, Principal, RunBlobId, RunEvent, RunId, + ArtifactUpload, BlobHash, EventBody, FailureReason, Principal, RunEvent, RunId, WorkflowSettings, }; use fabro_vault::{SecretStore, Vault}; @@ -1008,7 +1008,7 @@ impl RunStoreBackend for HttpRunStore { self.apply_acknowledged_event(seq, event).await } - async fn write_blob(&self, data: &[u8]) -> Result { + async fn write_blob(&self, data: &[u8]) -> Result { self.with_retries("write run blob", || { let client = self.client.clone_for_reuse(); let run_id = self.run_id; @@ -1018,12 +1018,12 @@ impl RunStoreBackend for HttpRunStore { .await } - async fn read_blob(&self, id: &RunBlobId) -> Result> { + async fn read_blob(&self, blob_hash: &BlobHash) -> Result> { self.with_retries("read run blob", || { let client = self.client.clone_for_reuse(); let run_id = self.run_id; - let blob_id = *id; - async move { client.read_run_blob(&run_id, &blob_id).await } + let blob_hash = *blob_hash; + async move { client.read_run_blob(&run_id, &blob_hash).await } }) .await } diff --git a/lib/apps/fabro-cli/tests/it/cmd/attach.rs b/lib/apps/fabro-cli/tests/it/cmd/attach.rs index 813bf7424..15709012d 100644 --- a/lib/apps/fabro-cli/tests/it/cmd/attach.rs +++ b/lib/apps/fabro-cli/tests/it/cmd/attach.rs @@ -66,20 +66,8 @@ fn format_output_snapshot(output: &Output, filters: &[(String, String)]) -> Stri } fn normalize_attach_json_progress_event(mut event: Value) -> Value { - if let Some(properties) = event.get_mut("properties").and_then(Value::as_object_mut) { - if properties.contains_key("manifest_blob") { - properties.insert( - "manifest_blob".to_string(), - Value::String("[BLOB_ID]".to_string()), - ); - } - if properties.contains_key("definition_blob") { - properties.insert( - "definition_blob".to_string(), - Value::String("[BLOB_ID]".to_string()), - ); - } - } + // manifest_blob/definition_blob hashes are already rewritten to + // [BLOB_HASH] by the shared json_snapshot_filters regexes. // Strip v2-shape server/version fields that the bridge emits, // since the test fixture's socket path is randomised per run. if let Some(settings) = event @@ -896,7 +884,7 @@ fn attach_json_errors_without_prompting_for_human_input() { } } }, - "manifest_blob": "[BLOB_ID]", + "manifest_blob": "[BLOB_HASH]", "provenance": { "client": { "name": "fabro-cli", @@ -1036,7 +1024,7 @@ fn attach_json_errors_without_prompting_for_human_input() { "event": "run.submitted", "id": "[EVENT_ID]", "properties": { - "definition_blob": "[BLOB_ID]" + "definition_blob": "[BLOB_HASH]" }, "run_id": "[ULID]", "ts": "[TIMESTAMP]" diff --git a/lib/apps/fabro-cli/tests/it/cmd/validate.rs b/lib/apps/fabro-cli/tests/it/cmd/validate.rs index f82f5dc9e..dd469c4a5 100644 --- a/lib/apps/fabro-cli/tests/it/cmd/validate.rs +++ b/lib/apps/fabro-cli/tests/it/cmd/validate.rs @@ -314,7 +314,8 @@ fn validate_reports_missing_template_dependency() { exit_code: 1 ----- stdout ----- ----- stderr ----- - × failed to discover template dependencies: missing template dependency `missing.tpl.md` from `[FIXTURES]/templates/missing_dependency/workflow.fabro` + × failed to discover template dependencies + ╰─▶ missing template dependency `missing.tpl.md` from `[FIXTURES]/templates/missing_dependency/workflow.fabro` "); } diff --git a/lib/apps/fabro-server/Cargo.toml b/lib/apps/fabro-server/Cargo.toml index 8aea2bade..5ad20cfbb 100644 --- a/lib/apps/fabro-server/Cargo.toml +++ b/lib/apps/fabro-server/Cargo.toml @@ -32,6 +32,7 @@ fabro-hooks = { path = "../../components/fabro-hooks" } fabro-interview = { path = "../../components/fabro-interview" } fabro-slack = { path = "../../components/fabro-slack" } fabro-workflow = { path = "../../components/fabro-workflow" } +fabro-workflow-version = { path = "../../components/fabro-workflow-version" } fabro-validate = { path = "../../components/fabro-validate" } fabro-sandbox = { path = "../../components/fabro-sandbox", features = ["daytona", "docker"] } fabro-github = { path = "../../components/fabro-github" } diff --git a/lib/apps/fabro-server/src/principal_middleware.rs b/lib/apps/fabro-server/src/principal_middleware.rs index 2559b07bf..3d9bb0542 100644 --- a/lib/apps/fabro-server/src/principal_middleware.rs +++ b/lib/apps/fabro-server/src/principal_middleware.rs @@ -7,14 +7,14 @@ use axum::http::StatusCode; use axum::http::request::Parts; use axum::middleware::Next; use axum::response::{IntoResponse, Response}; -use fabro_types::{AuthMethod, IdpIdentity, Principal, RunBlobId, RunId, StageId, UserPrincipal}; +use fabro_types::{AuthMethod, BlobHash, IdpIdentity, Principal, RunId, StageId, UserPrincipal}; use jsonwebtoken::decode_header; use strum::IntoStaticStr; use crate::auth::{AuthErrorCode, JwtError, REFRESH_TOKEN_PREFIX}; use crate::error::ApiError; use crate::jwt_auth::{self, AuthMode, ConfiguredAuth}; -use crate::server::{AppState, parse_blob_id_path, parse_run_id_path, parse_stage_id_path}; +use crate::server::{AppState, parse_blob_hash_path, parse_run_id_path, parse_stage_id_path}; use crate::worker_token::{self, WORKER_TOKEN_KID, WorkerScopeSet}; #[derive(Clone, Debug)] @@ -61,7 +61,7 @@ pub(crate) struct RequiredRunToolActor(pub(crate) Principal); pub(crate) struct RequireRunScoped(pub(crate) RunId); pub(crate) struct RequireWorkerRunScoped(pub(crate) RunId); pub(crate) struct RequireRunManagementTarget(pub(crate) RunId, pub(crate) Principal); -pub(crate) struct RequireRunBlob(pub(crate) RunId, pub(crate) RunBlobId); +pub(crate) struct RequireRunBlob(pub(crate) RunId, pub(crate) BlobHash); pub(crate) struct RequireRunStageScoped(pub(crate) RunId, pub(crate) String); pub(crate) struct RequireStageArtifact(pub(crate) RunId, pub(crate) StageId); pub(crate) struct RequireCommandLog(pub(crate) RunId, pub(crate) StageId); @@ -295,14 +295,14 @@ impl FromRequestParts> for RequireRunBlob { parts: &mut Parts, state: &Arc, ) -> Result { - let Path((id, blob_id)): Path<(String, String)> = Path::from_request_parts(parts, state) + let Path((id, blob_hash)): Path<(String, String)> = Path::from_request_parts(parts, state) .await .map_err(IntoResponse::into_response)?; let run_id = parse_run_id_path(&id)?; - let blob_id = parse_blob_id_path(&blob_id)?; + let blob_hash = parse_blob_hash_path(&blob_hash)?; require_worker_or_user_for_run(&auth_slot_from_parts(parts), &run_id) .map_err(IntoResponse::into_response)?; - Ok(Self(run_id, blob_id)) + Ok(Self(run_id, blob_hash)) } } diff --git a/lib/apps/fabro-server/src/run_compiler.rs b/lib/apps/fabro-server/src/run_compiler.rs index 437df572b..a018f46d0 100644 --- a/lib/apps/fabro-server/src/run_compiler.rs +++ b/lib/apps/fabro-server/src/run_compiler.rs @@ -586,17 +586,7 @@ fn resolve_dockerfiles( config_path: &ManifestPath, files: &HashMap, ) -> Result<()> { - for environment in layer.environments.values_mut() { - if let Some(image) = environment.image.as_mut() { - resolve_dockerfile(image, config_path, files)?; - } - } - if let Some(image) = layer - .run - .as_mut() - .and_then(|run| run.environment.as_mut()) - .and_then(|environment| environment.image.as_mut()) - { + for image in layer.environment_images_mut() { resolve_dockerfile(image, config_path, files)?; } Ok(()) diff --git a/lib/apps/fabro-server/src/server.rs b/lib/apps/fabro-server/src/server.rs index 5445ad619..67ae1f32f 100644 --- a/lib/apps/fabro-server/src/server.rs +++ b/lib/apps/fabro-server/src/server.rs @@ -96,10 +96,10 @@ use fabro_types::settings::server::{ GithubIntegrationSettings, GithubIntegrationStrategy, LogDestination, }; use fabro_types::{ - AgentBackend, AskFabro, AskFabroUnavailableReason, EventBody, InterviewQuestionRecord, PairId, - PairMessageId, PairTarget, PendingReason, Principal, PullRequestLink, QuestionType, RunBlobId, - RunControlAction, RunEvent, RunId, RunRunnableSource, SandboxProviderKind, ServerSettings, - SessionCapability, + AgentBackend, AskFabro, AskFabroUnavailableReason, BlobHash, EventBody, + InterviewQuestionRecord, PairId, PairMessageId, PairTarget, PendingReason, Principal, + PullRequestLink, QuestionType, RunControlAction, RunEvent, RunId, RunRunnableSource, + SandboxProviderKind, ServerSettings, SessionCapability, }; use fabro_util::error::{ SharedError, collect_causes, render_compact_with_causes, render_with_causes, @@ -2889,11 +2889,11 @@ pub(crate) fn parse_stage_id_path(stage_id: &str) -> Result { #[allow( clippy::result_large_err, - reason = "Blob ID parsing returns HTTP 400 responses directly." + reason = "Blob hash parsing returns HTTP 400 responses directly." )] -pub(crate) fn parse_blob_id_path(blob_id: &str) -> Result { - RunBlobId::from_str(blob_id) - .map_err(|_| ApiError::bad_request("Invalid blob ID.").into_response()) +pub(crate) fn parse_blob_hash_path(blob_hash: &str) -> Result { + BlobHash::from_str(blob_hash) + .map_err(|_| ApiError::bad_request("Invalid blob hash.").into_response()) } #[allow( diff --git a/lib/apps/fabro-server/src/server/handler/artifacts.rs b/lib/apps/fabro-server/src/server/handler/artifacts.rs index f426a0007..f0f2b6064 100644 --- a/lib/apps/fabro-server/src/server/handler/artifacts.rs +++ b/lib/apps/fabro-server/src/server/handler/artifacts.rs @@ -32,7 +32,7 @@ pub(super) fn routes() -> Router> { Router::new() .route("/runs/{id}/checkpoint", get(get_checkpoint)) .route("/runs/{id}/blobs", post(write_run_blob)) - .route("/runs/{id}/blobs/{blobId}", get(read_run_blob)) + .route("/runs/{id}/blobs/{blobHash}", get(read_run_blob)) .route("/runs/{id}/artifacts", get(list_run_artifacts)) .route("/runs/{id}/artifacts/download", get(download_run_artifacts)) .route( @@ -105,10 +105,7 @@ async fn write_run_blob( } match state.stores.runs.open_run(&id).await { Ok(run_store) => match run_store.write_blob(&body).await { - Ok(blob_id) => Json(WriteBlobResponse { - id: blob_id.to_string(), - }) - .into_response(), + Ok(blob_hash) => Json(WriteBlobResponse { hash: blob_hash }).into_response(), Err(err) => { ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response() } @@ -118,11 +115,11 @@ async fn write_run_blob( } async fn read_run_blob( - RequireRunBlob(id, blob_id): RequireRunBlob, + RequireRunBlob(id, blob_hash): RequireRunBlob, State(state): State>, ) -> Response { match state.stores.runs.open_run_reader(&id).await { - Ok(run_store) => match run_store.read_blob(&blob_id).await { + Ok(run_store) => match run_store.read_blob(&blob_hash).await { Ok(Some(bytes)) => octet_stream_response(bytes), Ok(None) => ApiError::not_found("Blob not found.").into_response(), Err(err) => { diff --git a/lib/apps/fabro-server/src/server/handler/mod.rs b/lib/apps/fabro-server/src/server/handler/mod.rs index c186464d7..d42999c74 100644 --- a/lib/apps/fabro-server/src/server/handler/mod.rs +++ b/lib/apps/fabro-server/src/server/handler/mod.rs @@ -30,6 +30,7 @@ mod steer; pub(in crate::server) mod system; mod variables; mod worker_control; +mod workflow_versions; pub(super) use system::{health, openapi_spec}; @@ -100,7 +101,7 @@ pub(super) fn demo_routes() -> Router> { ) .route("/runs/{id}/attach", get(demo::run_events_stub)) .route("/runs/{id}/blobs", post(not_implemented)) - .route("/runs/{id}/blobs/{blobId}", get(not_implemented)) + .route("/runs/{id}/blobs/{blobHash}", get(not_implemented)) .route( "/runs/{id}/stages/{stageId}/logs/output", get(not_implemented), @@ -226,6 +227,7 @@ pub(super) fn real_routes() -> Router> { .merge(secrets::routes()) .merge(variables::routes()) .merge(worker_control::routes()) + .merge(workflow_versions::routes()) .merge(sessions::routes()) .merge(system::routes()) .merge(completions::routes()) diff --git a/lib/apps/fabro-server/src/server/handler/workflow_versions.rs b/lib/apps/fabro-server/src/server/handler/workflow_versions.rs new file mode 100644 index 000000000..1ded22adf --- /dev/null +++ b/lib/apps/fabro-server/src/server/handler/workflow_versions.rs @@ -0,0 +1,392 @@ +use std::sync::Arc; + +use axum::extract::DefaultBodyLimit; +use axum::extract::rejection::JsonRejection; +use fabro_api::types::{CreateWorkflowVersionResponse, WorkflowVersion}; +use fabro_types::MAX_WORKFLOW_VERSION_BYTES; +use fabro_util::error; +use fabro_workflow_version::{ + ValidatedWorkflowVersion, WorkflowVersionStore, WorkflowVersionStoreError, +}; + +use super::super::{ + ApiError, AppState, IntoResponse, Json, RequiredUser, Response, Router, State, StatusCode, post, +}; + +const INVALID_JSON_CODE: &str = "invalid_json"; +const INVALID_VERSION_CODE: &str = "workflow_version_invalid"; +const DEPENDENCY_NOT_FOUND_CODE: &str = "workflow_version_dependency_not_found"; +const VERSION_TOO_LARGE_CODE: &str = "workflow_version_too_large"; + +pub(super) fn routes() -> Router> { + Router::new().route( + "/workflow-versions", + post(create_workflow_version).layer(DefaultBodyLimit::max(MAX_WORKFLOW_VERSION_BYTES)), + ) +} + +async fn create_workflow_version( + _auth: RequiredUser, + State(state): State>, + payload: Result, JsonRejection>, +) -> Result { + let Json(version) = payload.map_err(json_rejection)?; + let version = ValidatedWorkflowVersion::new(version).map_err(|err| { + ApiError::with_code( + StatusCode::UNPROCESSABLE_ENTITY, + err.to_string(), + INVALID_VERSION_CODE, + ) + })?; + let blobs = state.store_ref().blobs().await.map_err(|err| { + tracing::error!( + error = %err, + error_chain = ?error::collect_chain(&err), + "Failed to open workflow version storage" + ); + internal_store_error() + })?; + let store = WorkflowVersionStore::new(blobs); + let workflow_version_id = store.put(&version).await.map_err(store_error)?; + + Ok(( + StatusCode::CREATED, + Json(CreateWorkflowVersionResponse { + workflow_version_id, + }), + ) + .into_response()) +} + +fn json_rejection(rejection: JsonRejection) -> ApiError { + if rejection.status() == StatusCode::PAYLOAD_TOO_LARGE { + return ApiError::with_code( + StatusCode::PAYLOAD_TOO_LARGE, + "workflow version request exceeds 2 MiB", + VERSION_TOO_LARGE_CODE, + ); + } + + match rejection { + JsonRejection::JsonDataError(err) => ApiError::with_code( + StatusCode::UNPROCESSABLE_ENTITY, + err.body_text(), + INVALID_VERSION_CODE, + ), + other => ApiError::with_code( + StatusCode::BAD_REQUEST, + other.body_text(), + INVALID_JSON_CODE, + ), + } +} + +fn store_error(err: WorkflowVersionStoreError) -> ApiError { + match err { + // The top-level message names the offending dependency without its + // internal source chain, so it is safe to surface to the caller. + err @ (WorkflowVersionStoreError::DependencyNotFound { .. } + | WorkflowVersionStoreError::DependencyInvalid { .. }) => ApiError::with_code( + StatusCode::UNPROCESSABLE_ENTITY, + err.to_string(), + DEPENDENCY_NOT_FOUND_CODE, + ), + err => { + tracing::error!( + error = %err, + error_chain = ?error::collect_chain(&err), + "Workflow version store operation failed" + ); + internal_store_error() + } + } +} + +fn internal_store_error() -> ApiError { + ApiError::new( + StatusCode::INTERNAL_SERVER_ERROR, + "workflow version store operation failed", + ) +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use axum::body::{Body, to_bytes}; + use axum::http::{Method, Request, StatusCode, header}; + use axum::response::IntoResponse; + use fabro_types::{BlobHash, WorkflowVersion, WorkflowVersionId}; + use serde_json::{Value, json}; + use tower::ServiceExt; + + use super::{ + DEPENDENCY_NOT_FOUND_CODE, INVALID_JSON_CODE, INVALID_VERSION_CODE, + MAX_WORKFLOW_VERSION_BYTES, VERSION_TOO_LARGE_CODE, store_error, + }; + use crate::server; + use crate::test_support::{self, TestAppStateBuilder}; + + const GRAPH: &str = "digraph W { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }"; + + fn request(body: impl Into) -> Request { + Request::builder() + .method(Method::POST) + .uri("/api/v1/workflow-versions") + .header(header::CONTENT_TYPE, "application/json") + .body(body.into()) + .unwrap() + } + + fn version(graph: &str) -> Value { + json!({ + "entrypoint": "workflow.fabro", + "files": { "workflow.fabro": graph }, + "workflow_dependencies": {} + }) + } + + async fn response_json(response: axum::response::Response) -> Value { + let bytes = to_bytes(response.into_body(), usize::MAX).await.unwrap(); + serde_json::from_slice(&bytes).unwrap() + } + + fn error_code(body: &Value) -> &str { + body["errors"][0]["code"].as_str().unwrap() + } + + #[tokio::test] + async fn create_requires_authenticated_user() { + let state = TestAppStateBuilder::new().build(); + let app = server::build_router(state, test_support::test_auth_mode()); + let response = app + .oneshot(request(serde_json::to_vec(&version(GRAPH)).unwrap())) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::UNAUTHORIZED); + } + + #[tokio::test] + async fn valid_and_equivalent_requests_return_the_same_id() { + let state = TestAppStateBuilder::new().build(); + let app = test_support::build_test_router(Arc::clone(&state)); + let first = app + .clone() + .oneshot(request(serde_json::to_vec(&version(GRAPH)).unwrap())) + .await + .unwrap(); + assert_eq!(first.status(), StatusCode::CREATED); + let first = response_json(first).await; + assert_eq!(first.as_object().unwrap().len(), 1); + + let reordered = format!( + r#"{{"workflow_dependencies":{{}},"files":{{"workflow.fabro":{}}},"entrypoint":"workflow.fabro"}}"#, + serde_json::to_string(GRAPH).unwrap() + ); + let second = app.oneshot(request(reordered)).await.unwrap(); + assert_eq!(second.status(), StatusCode::CREATED); + assert_eq!(response_json(second).await, first); + + let id = first["workflow_version_id"] + .as_str() + .unwrap() + .parse::() + .unwrap(); + assert!( + state + .store_ref() + .blobs() + .await + .unwrap() + .read(&id.into()) + .await + .unwrap() + .is_some() + ); + } + + #[tokio::test] + async fn invalid_json_and_domain_content_have_distinct_codes() { + let app = test_support::build_test_router(TestAppStateBuilder::new().build()); + let malformed = app.clone().oneshot(request("{")).await.unwrap(); + assert_eq!(malformed.status(), StatusCode::BAD_REQUEST); + assert_eq!( + error_code(&response_json(malformed).await), + INVALID_JSON_CODE + ); + + let unknown = json!({ + "entrypoint": "workflow.fabro", + "files": { "workflow.fabro": GRAPH }, + "workflow_dependencies": {}, + "metadata": {} + }); + let invalid = app + .oneshot(request(serde_json::to_vec(&unknown).unwrap())) + .await + .unwrap(); + assert_eq!(invalid.status(), StatusCode::UNPROCESSABLE_ENTITY); + assert_eq!( + error_code(&response_json(invalid).await), + INVALID_VERSION_CODE + ); + } + + #[tokio::test] + async fn create_rejects_workflow_config_with_missing_goal_file_before_storage() { + let state = TestAppStateBuilder::new().build(); + let app = test_support::build_test_router(Arc::clone(&state)); + let payload = json!({ + "entrypoint": "workflow.fabro", + "files": { + "workflow.fabro": GRAPH, + "workflow.toml": "_version = 1\n[run.goal]\nfile = \"prompts/goal.md\"\n" + }, + "workflow_dependencies": {} + }); + let version = serde_json::from_value::(payload.clone()).unwrap(); + let id = WorkflowVersionId::from(BlobHash::new(&version.canonical_bytes().unwrap())); + + let response = app + .oneshot(request(serde_json::to_vec(&payload).unwrap())) + .await + .unwrap(); + let body = fabro_test::expect_axum_json( + response, + StatusCode::UNPROCESSABLE_ENTITY, + "POST /api/v1/workflow-versions with missing run goal file", + ) + .await; + + assert_eq!(error_code(&body), INVALID_VERSION_CODE); + assert!( + !state + .store_ref() + .blobs() + .await + .unwrap() + .exists(&id.into()) + .await + .unwrap() + ); + } + + #[tokio::test] + async fn unavailable_dependency_has_specific_code() { + let state = TestAppStateBuilder::new().build(); + let app = test_support::build_test_router(Arc::clone(&state)); + let missing_id = WorkflowVersionId::from(fabro_types::BlobHash::new(b"missing")); + let root = json!({ + "entrypoint": "workflow.fabro", + "files": { + "workflow.fabro": "digraph W { child [stack.child_workflow=\"child.fabro\"] }" + }, + "workflow_dependencies": { "child.fabro": missing_id } + }); + let response = app + .oneshot(request(serde_json::to_vec(&root).unwrap())) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); + assert_eq!( + error_code(&response_json(response).await), + DEPENDENCY_NOT_FOUND_CODE + ); + } + + #[tokio::test] + async fn invalid_stored_dependency_is_a_client_error_without_internals() { + let state = TestAppStateBuilder::new().build(); + let app = test_support::build_test_router(Arc::clone(&state)); + let dependency_id = WorkflowVersionId::from( + state + .store_ref() + .blobs() + .await + .unwrap() + .write(b"not a workflow version") + .await + .unwrap(), + ); + let root = json!({ + "entrypoint": "workflow.fabro", + "files": { + "workflow.fabro": "digraph W { child [stack.child_workflow=\"child.fabro\"] }" + }, + "workflow_dependencies": { "child.fabro": dependency_id } + }); + + let response = app + .oneshot(request(serde_json::to_vec(&root).unwrap())) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY); + let body = response_json(response).await; + assert_eq!(error_code(&body), DEPENDENCY_NOT_FOUND_CODE); + assert!( + body["errors"][0]["detail"] + .as_str() + .unwrap() + .contains("child.fabro") + ); + assert!(!body.to_string().contains("cannot be decoded")); + } + + #[tokio::test] + async fn stored_child_can_be_pinned_as_a_dependency() { + let app = test_support::build_test_router(TestAppStateBuilder::new().build()); + let child = app + .clone() + .oneshot(request(serde_json::to_vec(&version(GRAPH)).unwrap())) + .await + .unwrap(); + assert_eq!(child.status(), StatusCode::CREATED); + let child_id = response_json(child).await["workflow_version_id"].clone(); + let root = json!({ + "entrypoint": "workflow.fabro", + "files": { + "workflow.fabro": "digraph W { child [stack.child_workflow=\"child.fabro\"] }" + }, + "workflow_dependencies": { "child.fabro": child_id } + }); + + let response = app + .oneshot(request(serde_json::to_vec(&root).unwrap())) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::CREATED); + assert_eq!(response_json(response).await.as_object().unwrap().len(), 1); + } + + #[tokio::test] + async fn body_limit_has_specific_code() { + let app = test_support::build_test_router(TestAppStateBuilder::new().build()); + let response = app + .oneshot(request(vec![b' '; MAX_WORKFLOW_VERSION_BYTES + 1])) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::PAYLOAD_TOO_LARGE); + assert_eq!( + error_code(&response_json(response).await), + VERSION_TOO_LARGE_CODE + ); + } + + #[tokio::test] + async fn storage_fault_response_is_curated() { + let response = store_error(fabro_workflow_version::WorkflowVersionStoreError::Storage { + source: fabro_store::Error::Other("private persistence detail".to_string()), + }) + .into_response(); + assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR); + + let body = response_json(response).await; + assert_eq!( + body["errors"][0]["detail"], + "workflow version store operation failed" + ); + assert!(!body.to_string().contains("private persistence detail")); + } +} diff --git a/lib/apps/fabro-server/src/server/tests.rs b/lib/apps/fabro-server/src/server/tests.rs index a05443a00..c6562fc3f 100644 --- a/lib/apps/fabro-server/src/server/tests.rs +++ b/lib/apps/fabro-server/src/server/tests.rs @@ -26,12 +26,12 @@ use fabro_model::{Catalog, ModelRef, ProviderId, ReasoningEffort, Speed}; use fabro_types::settings::ServerAuthMethod; use fabro_types::settings::run::EnvironmentProvider; use fabro_types::{ - AgentBackend, AttrValue, AuthMethod, CommandTermination, FailureCategory, FailureDetail, Graph, - InterviewQuestionRecord, Node, Outcome, ParallelBranchId, QuestionType, RunBlobId, RunId, - RunSpec, SandboxProviderKind, StageContextWindowBreakdownItem, StageContextWindowCategory, - StageContextWindowCountMethod, StageContextWindowProjection, StageContextWindowStaleness, - StageContextWindowWarning, StageModelUsage, StageTiming, SuccessReason, SystemActorKind, - WorkflowSettings, fixtures, test_support, + AgentBackend, AttrValue, AuthMethod, BlobHash, CommandTermination, FailureCategory, + FailureDetail, Graph, InterviewQuestionRecord, Node, Outcome, ParallelBranchId, QuestionType, + RunId, RunSpec, SandboxProviderKind, StageContextWindowBreakdownItem, + StageContextWindowCategory, StageContextWindowCountMethod, StageContextWindowProjection, + StageContextWindowStaleness, StageContextWindowWarning, StageModelUsage, StageTiming, + SuccessReason, SystemActorKind, WorkflowSettings, fixtures, test_support, }; use fabro_util::check_report::CheckStatus; use fabro_workflow::records::CheckpointExt; @@ -3890,7 +3890,7 @@ layer = "project" let manifest_blob = created["properties"]["manifest_blob"] .as_str() .expect("run.created should carry the submitted source blob") - .parse::() + .parse::() .unwrap(); let persisted_manifest = run_store .read_blob(&manifest_blob) @@ -10786,12 +10786,12 @@ async fn create_run_persists_manifest_and_definition_blobs_without_bundle_file() let manifest_blob = created["properties"]["manifest_blob"] .as_str() .expect("run.created should carry manifest_blob") - .parse::() + .parse::() .unwrap(); let definition_blob = submitted["properties"]["definition_blob"] .as_str() .expect("run.submitted should carry definition_blob") - .parse::() + .parse::() .unwrap(); let submitted_manifest_bytes = run_store @@ -11034,7 +11034,7 @@ async fn get_checkpoint_returns_null_initially() { } #[tokio::test] -async fn write_and_read_run_blob_round_trip() { +async fn write_and_read_run_blob_accepts_uppercase_hash() { let state = test_app_state(); let app = crate::test_support::build_test_router(Arc::clone(&state)); @@ -11057,11 +11057,14 @@ async fn write_and_read_run_blob_round_trip() { .unwrap(); let response = app.clone().oneshot(req).await.unwrap(); let body = response_json!(response, StatusCode::OK).await; - let blob_id = body["id"].as_str().unwrap(); + let blob_hash = body["hash"].as_str().unwrap(); let req = Request::builder() .method("GET") - .uri(api(&format!("/runs/{run_id}/blobs/{blob_id}"))) + .uri(api(&format!( + "/runs/{run_id}/blobs/{}", + blob_hash.to_uppercase() + ))) .body(Body::empty()) .unwrap(); let response = app.oneshot(req).await.unwrap(); @@ -11459,7 +11462,7 @@ async fn worker_token_accepts_run_scoped_routes_and_falls_back_to_user_jwt() { let worker_token = issue_test_worker_token(&run_id); let other_run_id = create_run_with_bearer(&app, &user_jwt).await; let other_worker_token = issue_test_worker_token(&other_run_id); - let blob_id = state + let blob_hash = state .stores .runs .open_run(&run_id) @@ -11553,7 +11556,7 @@ async fn worker_token_accepts_run_scoped_routes_and_falls_back_to_user_jwt() { .clone() .oneshot(bearer_request( Method::GET, - &format!("/runs/{run_id}/blobs/{blob_id}"), + &format!("/runs/{run_id}/blobs/{blob_hash}"), &worker_token, Body::empty(), )) @@ -12058,7 +12061,7 @@ async fn worker_token_is_rejected_on_user_only_routes() { let user_jwt = issue_test_user_jwt(); let run_id = create_run_with_bearer(&app, &user_jwt).await; let worker_token = issue_test_worker_token(&run_id); - let blob_id = RunBlobId::new(b"blob"); + let blob_hash = BlobHash::new(b"blob"); let user_only_routes = vec![ (Method::GET, "/runs".to_string()), (Method::POST, "/runs".to_string()), @@ -12121,7 +12124,7 @@ async fn worker_token_is_rejected_on_user_only_routes() { .clone() .oneshot(bearer_request( Method::GET, - &format!("/runs/{run_id}/blobs/{blob_id}"), + &format!("/runs/{run_id}/blobs/{blob_hash}"), &worker_token, Body::empty(), )) diff --git a/lib/components/fabro-dump/src/lib.rs b/lib/components/fabro-dump/src/lib.rs index 1b3a10a4c..43cf278eb 100644 --- a/lib/components/fabro-dump/src/lib.rs +++ b/lib/components/fabro-dump/src/lib.rs @@ -4,6 +4,7 @@ )] use std::collections::HashMap; +use std::collections::hash_map::Entry; #[expect( clippy::disallowed_types, reason = "in-memory Vec::write_all for jsonl serialization; no filesystem or network I/O" @@ -16,10 +17,10 @@ use bytes::Bytes; use fabro_store::{ EventEnvelope, RunProjection, SerializableProjection, StageId, retry_storage_segment, }; -use fabro_types::{RunBlobId, parse_blob_ref}; +use fabro_types::{BlobHash, parse_blob_ref}; use futures::future::BoxFuture; -pub type BlobReader = Box BoxFuture<'static, Result>> + Send>; +pub type BlobReader = Box BoxFuture<'static, Result>> + Send>; const STAGE_RANK_WIDTH: usize = 3; const MAX_STAGES_IN_DUMP: usize = { @@ -208,37 +209,48 @@ impl RunDump { mut read_blob: F, ) -> Result<()> where - F: FnMut(RunBlobId) -> BoxFuture<'a, Result>>, + F: FnMut(BlobHash) -> BoxFuture<'a, Result>>, { let mut cache = HashMap::new(); for entry in &mut self.entries { match &mut entry.contents { RunDumpContents::Json(value) => { - let mut blob_ids = Vec::new(); - collect_blob_refs_in_value(value, &mut blob_ids); - for blob_id in blob_ids { - if cache.contains_key(&blob_id) { + let mut blob_hashes = Vec::new(); + collect_blob_refs_in_value(value, &mut blob_hashes); + for blob_hash in blob_hashes { + if cache.contains_key(&blob_hash) { continue; } - let blob = read_blob(blob_id).await?.with_context(|| { - format!("blob {blob_id:?} is missing from the store") + let blob = read_blob(blob_hash).await?.with_context(|| { + format!("blob {blob_hash:?} is missing from the store") })?; let hydrated: serde_json::Value = serde_json::from_slice(&blob) - .with_context(|| format!("blob {blob_id:?} is not valid JSON"))?; - cache.insert(blob_id, hydrated); + .with_context(|| format!("blob {blob_hash:?} is not valid JSON"))?; + cache.insert(blob_hash, hydrated); } replace_blob_refs_in_value(value, &cache)?; } RunDumpContents::Text(text) => { - let Some(blob_id) = parse_blob_ref(text) else { + let Some(blob_hash) = parse_blob_ref(text) else { continue; }; - let blob = read_blob(blob_id) - .await? - .with_context(|| format!("blob {blob_id:?} is missing from the store"))?; - *text = serde_json::from_slice::(&blob).with_context(|| { - format!("blob {blob_id:?} is not a JSON string text log") - })?; + let hydrated = match cache.entry(blob_hash) { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => { + let blob = read_blob(blob_hash).await?.with_context(|| { + format!("blob {blob_hash:?} is missing from the store") + })?; + let hydrated: serde_json::Value = serde_json::from_slice(&blob) + .with_context(|| format!("blob {blob_hash:?} is not valid JSON"))?; + entry.insert(hydrated) + } + }; + *text = hydrated + .as_str() + .with_context(|| { + format!("blob {blob_hash:?} is not a JSON string text log") + })? + .to_string(); } RunDumpContents::Bytes(_) => {} } @@ -386,21 +398,21 @@ fn validate_relative_path(kind: &str, value: &str) -> Result { Ok(normalized) } -fn collect_blob_refs_in_value(value: &serde_json::Value, blob_ids: &mut Vec) { +fn collect_blob_refs_in_value(value: &serde_json::Value, blob_hashes: &mut Vec) { match value { serde_json::Value::String(current) => { - if let Some(blob_id) = parse_blob_ref(current) { - blob_ids.push(blob_id); + if let Some(blob_hash) = parse_blob_ref(current) { + blob_hashes.push(blob_hash); } } serde_json::Value::Array(items) => { for item in items { - collect_blob_refs_in_value(item, blob_ids); + collect_blob_refs_in_value(item, blob_hashes); } } serde_json::Value::Object(map) => { for item in map.values() { - collect_blob_refs_in_value(item, blob_ids); + collect_blob_refs_in_value(item, blob_hashes); } } serde_json::Value::Null | serde_json::Value::Bool(_) | serde_json::Value::Number(_) => {} @@ -409,17 +421,16 @@ fn collect_blob_refs_in_value(value: &serde_json::Value, blob_ids: &mut Vec, + cache: &HashMap, ) -> Result<()> { match value { serde_json::Value::String(current) => { - let Some(blob_id) = parse_blob_ref(current) else { + let Some(blob_hash) = parse_blob_ref(current) else { return Ok(()); }; - let hydrated = cache - .get(&blob_id) - .cloned() - .with_context(|| format!("blob {blob_id:?} is missing from the hydration cache"))?; + let hydrated = cache.get(&blob_hash).cloned().with_context(|| { + format!("blob {blob_hash:?} is missing from the hydration cache") + })?; *value = hydrated; } serde_json::Value::Array(items) => { @@ -475,8 +486,7 @@ mod tests { use fabro_types::{ Checkpoint, CheckpointRecord, Conclusion, RunDiff, RunSandbox, RunSandboxInstance, RunSandboxPlan, RunStatus, SandboxProviderKind, StageCompletion, StageModelUsage, - StageOutcome, StartRecord, SuccessReason, WorkflowSettings, first_event_seq, fixtures, - test_support, + StageOutcome, StartRecord, SuccessReason, first_event_seq, fixtures, test_support, }; use futures::executor; @@ -484,24 +494,18 @@ mod tests { fn sample_run_spec() -> RunSpec { RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: Graph::new("ship"), - graph_source: Some("digraph Ship {}".to_string()), - workflow_slug: Some("demo".to_string()), - automation: None, + graph: Graph::new("ship"), + graph_source: Some("digraph Ship {}".to_string()), + workflow_slug: Some("demo".to_string()), source_directory: Some("/tmp/project".to_string()), - git: Some(fabro_types::GitContext { + git: Some(fabro_types::GitContext { origin_url: "https://github.com/fabro-sh/fabro.git".to_string(), branch: "main".to_string(), sha: None, dirty: fabro_types::DirtyStatus::Clean, }), - labels: HashMap::from([("team".to_string(), "platform".to_string())]), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - fork_source_ref: None, + labels: HashMap::from([("team".to_string(), "platform".to_string())]), + ..test_support::test_run_spec() } } @@ -724,8 +728,8 @@ mod tests { #[test] fn hydrate_referenced_blobs_ignores_legacy_artifact_file_refs() { let blob = serde_json::to_vec("hydrated legacy text").unwrap(); - let blob_id = fabro_types::RunBlobId::new(&blob); - let legacy_ref = format!("file:///sandbox/.fabro/artifacts/{blob_id}.json"); + let blob_hash = fabro_types::BlobHash::new(&blob); + let legacy_ref = format!("file:///sandbox/.fabro/artifacts/{blob_hash}.json"); let mut dump = RunDump { entries: vec![RunDumpEntry::json( "run.json", @@ -736,10 +740,10 @@ mod tests { }; executor::block_on(async { - dump.hydrate_referenced_blobs_with_reader(|read_blob_id| { + dump.hydrate_referenced_blobs_with_reader(|read_blob_hash| { let blob = blob.clone(); Box::pin(async move { - assert_eq!(read_blob_id, blob_id); + assert_eq!(read_blob_hash, blob_hash); Ok(Some(bytes::Bytes::from(blob))) }) }) @@ -752,4 +756,43 @@ mod tests { }; assert_eq!(value["stdout"], legacy_ref); } + + #[test] + fn hydrate_referenced_blobs_fetches_shared_blobs_once() { + let blob = serde_json::to_vec("offloaded response text").unwrap(); + let blob_hash = fabro_types::BlobHash::new(&blob); + let blob_ref = fabro_types::format_blob_ref(&blob_hash); + let mut dump = RunDump { + entries: vec![ + RunDumpEntry::json("run.json", serde_json::json!({ "response": blob_ref })), + RunDumpEntry::text("stages/001-demo@1/response.md", blob_ref.clone()), + ], + stage_ranks: HashMap::new(), + dump_log_index: None, + }; + + let reads = std::cell::Cell::new(0); + executor::block_on(async { + dump.hydrate_referenced_blobs_with_reader(|read_blob_hash| { + reads.set(reads.get() + 1); + let blob = blob.clone(); + Box::pin(async move { + assert_eq!(read_blob_hash, blob_hash); + Ok(Some(bytes::Bytes::from(blob))) + }) + }) + .await + }) + .unwrap(); + + assert_eq!(reads.get(), 1, "shared blob should be fetched once"); + let RunDumpContents::Json(value) = &dump.entries[0].contents else { + panic!("entry should be JSON"); + }; + assert_eq!(value["response"], "offloaded response text"); + let RunDumpContents::Text(text) = &dump.entries[1].contents else { + panic!("entry should be text"); + }; + assert_eq!(text, "offloaded response text"); + } } diff --git a/lib/components/fabro-llm/src/error.rs b/lib/components/fabro-llm/src/error.rs index 6ec6d7886..dd9a98347 100644 --- a/lib/components/fabro-llm/src/error.rs +++ b/lib/components/fabro-llm/src/error.rs @@ -355,7 +355,14 @@ pub fn error_from_status_code( // error types let kind = match status_code { 401 => ProviderErrorKind::Authentication, - 403 => ProviderErrorKind::AccessDenied, + // A 412 is never about the request: no LLM request carries + // conditional-request preconditions. Fireworks documents it as + // "Account is suspended or there's an issue with account status", + // also emitted for a LoRA model that failed to load + // (https://docs.fireworks.ai/guides/inference-error-codes). The same + // family as `account_deactivated`: deterministic here, but another + // provider has independent billing and model inventory. + 403 | 412 => ProviderErrorKind::AccessDenied, 404 => ProviderErrorKind::NotFound, 408 => { return Error::RequestTimeout { @@ -728,6 +735,53 @@ mod tests { assert_eq!(err.provider_kind(), Some(ProviderErrorKind::QuotaExceeded)); } + /// Fireworks reports an account suspension (spending cap reached or + /// unpaid invoices) as HTTP 412 with `code: "PRECONDITION_FAILED"` in + /// the body. A chat completion carries no conditional-request + /// preconditions, so a 412 is always an account-level lockout, never a + /// defect in the request: it must not classify as `InvalidRequest`, and + /// a fallback provider with independent billing must stay eligible. + #[test] + fn account_suspension_412_is_failover_eligible() { + let err = error_from_status_code( + 412, + "Account lithoscomputer is suspended, possibly due to reaching \ + the monthly spending limit or failure to pay past invoices." + .into(), + "fireworks".into(), + // The openai_compatible dialect reads `error.type` as the code, + // so the discriminating `PRECONDITION_FAILED` only reaches this + // mapping through the status code. + Some("error".into()), + Some(serde_json::json!({ + "error": { + "message": "Account lithoscomputer is suspended, possibly due to reaching the monthly spending limit or failure to pay past invoices. Please go to https://fireworks.ai/account/billing for more information.", + "param": null, + "code": "PRECONDITION_FAILED", + "type": "error" + }, + "request_id": "chatcmpl-d9652b89a6604931ac27dddd5ef5bdc0" + })), + None, + ); + + assert_eq!(err.provider_kind(), Some(ProviderErrorKind::AccessDenied)); + assert!(!err.retryable()); + assert!(err.failover_eligible()); + + // A bare 412 with no parseable body classifies the same way. + let err = error_from_status_code( + 412, + "Precondition Failed".into(), + "fireworks".into(), + None, + None, + None, + ); + assert_eq!(err.provider_kind(), Some(ProviderErrorKind::AccessDenied)); + assert!(err.failover_eligible()); + } + #[test] fn kind_from_error_code_covers_every_dialect() { for (code, expected) in [ diff --git a/lib/components/fabro-manifest/Cargo.toml b/lib/components/fabro-manifest/Cargo.toml index 29b32aadb..36b9d44c1 100644 --- a/lib/components/fabro-manifest/Cargo.toml +++ b/lib/components/fabro-manifest/Cargo.toml @@ -25,6 +25,8 @@ git2.workspace = true toml.workspace = true [dev-dependencies] +fabro-test.workspace = true +insta.workspace = true serde_json.workspace = true tempfile = "3" temp-env = "0.3" diff --git a/lib/components/fabro-manifest/src/lib.rs b/lib/components/fabro-manifest/src/lib.rs index eb1cc0dad..35891f419 100644 --- a/lib/components/fabro-manifest/src/lib.rs +++ b/lib/components/fabro-manifest/src/lib.rs @@ -3,34 +3,32 @@ reason = "CLI manifest builder: sync file I/O building install manifests" )] -use std::collections::{HashMap, HashSet}; +mod workflow_bundler; + +use std::collections::HashMap; use std::path::{Component, Path, PathBuf}; -use std::sync::Arc; use anyhow::{Context, Result, anyhow}; use fabro_api::types; use fabro_config::project::{self, WorkflowLocation, discover_project_config}; use fabro_config::run::{resolve_run_goal_from_layer, resolve_run_goal_from_namespace}; use fabro_config::{ - CliLayer, EnvironmentDockerfileLayer, EnvironmentImageLayer, EnvironmentLayer, - EnvironmentLifecycleLayer, MergeMap, ReplaceMap, RunEnvironmentLayer, RunExecutionLayer, - RunGoalLayer, RunLayer, RunModelLayer, SettingsLayer, WorkflowSettingsBuilder, + CliLayer, EnvironmentLayer, EnvironmentLifecycleLayer, MergeMap, ReplaceMap, + RunEnvironmentLayer, RunExecutionLayer, RunGoalLayer, RunLayer, RunModelLayer, + WorkflowSettingsBuilder, }; use fabro_graphviz::graph::AttrValue; use fabro_graphviz::parser; -use fabro_template::{ - BundleTemplateStore, FilesystemTemplateStore, RecordingTemplateStore, TemplateContext, - TemplateRenderMode, TemplateSource, discover_static_dependency_closure, render_source, -}; +use fabro_template::validate_static_reference; +use fabro_types::graph::ReferenceKind; use fabro_types::settings::interp::InterpString; use fabro_types::settings::run::{ApprovalMode, ResolvedGoalSource, ResolvedRunGoal, RunMode}; use fabro_types::{DirtyStatus, GitContext, ManifestPath, WorkflowSettings}; use fabro_workflow::git::{ GitSyncStatus, branch_needs_push, head_sha, push_branch_noninteractive, sync_status, }; -use fabro_workflow::static_reference::{ - AttributeScope, ReferenceKind, reference_kind_for_attribute, -}; + +use crate::workflow_bundler::WorkflowBundler; #[derive(Debug, Default)] pub struct ManifestBuildInput { @@ -127,20 +125,6 @@ pub fn build_sparse_run_overrides(input: RunOverrideInput<'_>) -> Option { - cwd: &'a Path, - inputs: HashMap, - workflows: HashMap, - visited_workflows: HashSet, -} - -#[derive(Clone)] -struct WorkflowScanInput { - absolute_dot_path: PathBuf, - dot_path: ManifestPath, - source: String, -} - pub fn build_run_manifest(input: ManifestBuildInput) -> Result { let root_location = WorkflowLocation::resolve(&input.workflow, &input.cwd)?; if root_location.toml.is_none() && !root_location.graph.is_file() { @@ -188,24 +172,12 @@ pub fn build_run_manifest(input: ManifestBuildInput) -> Result { let target_path = root_location.graph.clone(); let target_manifest_path = manifest_path_from_absolute(&target_path, &input.cwd)?; let target_key = target_manifest_path.to_string(); - - let mut context = CollectContext { - cwd: &input.cwd, - inputs: workflow_settings.run.inputs.clone(), - workflows: HashMap::new(), - visited_workflows: HashSet::new(), - }; - collect_workflow_entry(&mut context, &input.workflow, &input.cwd)?; - if let Some((_, config_path, source)) = project_config_source.as_ref() { - let workflow = context - .workflows - .get_mut(&target_key) - .ok_or_else(|| anyhow!("root workflow missing from manifest bundle"))?; - collect_config_dockerfile(context.cwd, config_path, source, &mut workflow.files)?; - } - - let root_source = context - .workflows + let project_config_input = project_config_source + .as_ref() + .map(|(_, path, source)| (path, source.as_str())); + let workflows = WorkflowBundler::new(&input.cwd, &workflow_settings.run.inputs) + .bundle(&input.workflow, project_config_input)?; + let root_source = workflows .get(&target_key) .map(|workflow| workflow.source.clone()) .ok_or_else(|| anyhow!("root workflow missing from manifest bundle"))?; @@ -218,7 +190,7 @@ pub fn build_run_manifest(input: ManifestBuildInput) -> Result { type_: types::ManifestConfigType::Project, }); } - if let Some(path) = input.user_settings_path.filter(|p| p.is_file()) { + if let Some(path) = input.user_settings_path.filter(|path| path.is_file()) { let source = std::fs::read_to_string(&path) .with_context(|| format!("Failed to read {}", path.display()))?; configs.push(types::ManifestConfig { @@ -254,415 +226,12 @@ pub fn build_run_manifest(input: ManifestBuildInput) -> Result { title: None, target: types::ManifestTarget { path: target_key }, version: 1, - workflows: context.workflows, + workflows, }, target_path, }) } -fn collect_workflow_entry( - context: &mut CollectContext<'_>, - workflow: &Path, - resolve_from: &Path, -) -> Result<()> { - let normalized_workflow = if workflow.extension().is_some() && workflow.is_relative() { - normalize_absolute_path(resolve_from, &workflow.to_string_lossy()).ok_or_else(|| { - anyhow!( - "unsupported manifest workflow reference: {}", - workflow.display() - ) - })? - } else { - workflow.to_path_buf() - }; - let location = WorkflowLocation::resolve(&normalized_workflow, resolve_from)?; - let dot_path = manifest_path_from_absolute(&location.graph, context.cwd)?; - let dot_key = dot_path.to_string(); - if !context.visited_workflows.insert(dot_key.clone()) { - return Ok(()); - } - - let source = std::fs::read_to_string(&location.graph) - .with_context(|| format!("Failed to read {}", location.graph.display()))?; - let config = if let Some(workflow_toml_path) = location.toml.as_ref() { - Some(types::ManifestWorkflowConfig { - path: manifest_path_from_absolute(workflow_toml_path, context.cwd)?.to_string(), - source: std::fs::read_to_string(workflow_toml_path) - .with_context(|| format!("Failed to read {}", workflow_toml_path.display()))?, - }) - } else { - None - }; - - let scan = WorkflowScanInput { - absolute_dot_path: location.graph, - dot_path, - source: source.clone(), - }; - let mut files = HashMap::new(); - let mut visited_imports = HashSet::new(); - if let Some(config) = config.as_ref() { - let config_path = ManifestPath::from_wire(&config.path) - .ok_or_else(|| anyhow!("invalid manifest workflow config path: {}", config.path))?; - collect_config_dockerfile(context.cwd, &config_path, &config.source, &mut files)?; - } - collect_workflow_files(context, &scan, &mut files, &mut visited_imports)?; - - context.workflows.insert(dot_key, types::ManifestWorkflow { - config, - files, - source, - }); - - Ok(()) -} - -fn collect_workflow_files( - context: &mut CollectContext<'_>, - workflow: &WorkflowScanInput, - files: &mut HashMap, - visited_imports: &mut HashSet, -) -> Result<()> { - let graph = parser::parse(&workflow.source).map_err(|err| { - anyhow!( - "Failed to parse {}: {err}", - workflow.absolute_dot_path.display() - ) - })?; - let workflow_base_dir = workflow - .absolute_dot_path - .parent() - .unwrap_or_else(|| Path::new(".")); - let workflow_template_root = manifest_parent_or_dot(&workflow.dot_path)?; - - if let Some(goal_ref) = graph.attrs.get("goal").and_then(AttrValue::as_str) { - if goal_ref.starts_with('@') { - let bundled = collect_bundled_file( - files, - workflow_base_dir, - context.cwd, - goal_ref.trim_start_matches('@'), - types::ManifestFileRefType::FileInline, - manifest_attr_reference_kind(AttributeScope::Graph, "goal", goal_ref)?, - Some(workflow.dot_path.clone()), - )?; - let source = std::fs::read_to_string(&bundled.absolute_path) - .with_context(|| format!("Failed to read {}", bundled.absolute_path.display()))?; - let template_root = - template_root_for_bundled_file(&bundled.path, &workflow_template_root)?; - collect_template_include_files( - files, - context.cwd, - TemplateSource::new(bundled.path.clone(), template_root, source), - Some(&bundled.path), - &context.inputs, - )?; - } else { - collect_template_include_files( - files, - context.cwd, - TemplateSource::new( - workflow.dot_path.clone(), - workflow_template_root.clone(), - goal_ref.to_owned(), - ), - Some(&workflow.dot_path), - &context.inputs, - )?; - } - } - - for node in graph.nodes.values() { - if let Some(prompt_ref) = node.attrs.get("prompt").and_then(AttrValue::as_str) { - if !prompt_ref.starts_with('@') { - collect_template_include_files( - files, - context.cwd, - TemplateSource::new( - workflow.dot_path.clone(), - workflow_template_root.clone(), - prompt_ref.to_owned(), - ), - Some(&workflow.dot_path), - &context.inputs, - )?; - } - } - - for (name, value) in &node.attrs { - let Some(value) = value.as_str() else { - continue; - }; - let Some(ReferenceKind::FileInline) = - reference_kind_for_attribute(AttributeScope::Node, name, value) - else { - continue; - }; - let reference = value.strip_prefix('@').ok_or_else(|| { - anyhow!("file inline reference must start with '@': {name}={value}") - })?; - let bundled = collect_bundled_file( - files, - workflow_base_dir, - context.cwd, - reference, - types::ManifestFileRefType::FileInline, - ReferenceKind::FileInline, - Some(workflow.dot_path.clone()), - )?; - - if name == "prompt" { - let source = - std::fs::read_to_string(&bundled.absolute_path).with_context(|| { - format!("Failed to read {}", bundled.absolute_path.display()) - })?; - let template_root = - template_root_for_bundled_file(&bundled.path, &workflow_template_root)?; - collect_template_include_files( - files, - context.cwd, - TemplateSource::new(bundled.path.clone(), template_root, source), - Some(&bundled.path), - &context.inputs, - )?; - } - } - - if let Some(import_ref) = node.attrs.get("import").and_then(AttrValue::as_str) { - let imported = collect_bundled_file( - files, - workflow_base_dir, - context.cwd, - import_ref, - types::ManifestFileRefType::Import, - manifest_attr_reference_kind(AttributeScope::Node, "import", import_ref)?, - Some(workflow.dot_path.clone()), - )?; - let import_key = imported.path.to_string(); - if visited_imports.insert(import_key) { - let imported_source = std::fs::read_to_string(&imported.absolute_path) - .with_context(|| { - format!("Failed to read {}", imported.absolute_path.display()) - })?; - let imported_scan = WorkflowScanInput { - absolute_dot_path: imported.absolute_path, - dot_path: imported.path, - source: imported_source, - }; - collect_workflow_files(context, &imported_scan, files, visited_imports)?; - } - } - - if let Some(child_ref) = node - .attrs - .get("stack.child_workflow") - .and_then(AttrValue::as_str) - { - manifest_attr_reference_kind(AttributeScope::Node, "stack.child_workflow", child_ref)? - .validate(child_ref) - .map_err(anyhow::Error::new)?; - collect_workflow_entry(context, Path::new(child_ref), workflow_base_dir)?; - } - } - - Ok(()) -} - -fn collect_template_include_files( - files: &mut HashMap, - cwd: &Path, - source: TemplateSource, - from: Option<&ManifestPath>, - inputs: &HashMap, -) -> Result<()> { - let source_path = source.path.clone(); - let store = FilesystemTemplateStore::new(cwd.to_path_buf()); - let closure = discover_static_dependency_closure([source], &store) - .map_err(|err| anyhow!("failed to discover template dependencies: {err}"))?; - verify_recorded_template_dependencies(&source_path, &closure, files, from, inputs)?; - - for (path, source) in closure.sources { - if path == source_path { - continue; - } - let key = path.to_string(); - files - .entry(key) - .or_insert_with(|| types::ManifestFileEntry { - content: source.content, - ref_: types::ManifestFileRef { - from: from.map(std::string::ToString::to_string), - original: path.to_string(), - type_: types::ManifestFileRefType::FileInline, - }, - }); - } - Ok(()) -} - -fn template_root_for_bundled_file( - path: &ManifestPath, - workflow_template_root: &ManifestPath, -) -> Result { - if manifest_path_is_within_root(path, workflow_template_root) { - Ok(workflow_template_root.clone()) - } else { - manifest_parent_or_dot(path) - } -} - -fn manifest_path_is_within_root(path: &ManifestPath, root: &ManifestPath) -> bool { - if root.as_path().as_os_str().is_empty() { - return !matches!( - path.as_path().components().next(), - Some(Component::ParentDir) - ); - } - path.starts_with(root) -} - -fn verify_recorded_template_dependencies( - source_path: &ManifestPath, - closure: &fabro_template::TemplateDependencyClosure, - files: &HashMap, - from: Option<&ManifestPath>, - inputs: &HashMap, -) -> Result<()> { - let Some(source) = closure.sources.get(source_path) else { - return Ok(()); - }; - let mut bundled_files = closure - .sources - .iter() - .map(|(path, source)| (path.clone(), source.content.clone())) - .collect::>(); - for (path, entry) in files { - if let Some(path) = ManifestPath::from_wire(path) { - bundled_files.insert(path, entry.content.clone()); - } - } - let allowed = bundled_files.keys().cloned().collect(); - let store = - RecordingTemplateStore::with_allowed(BundleTemplateStore::new(bundled_files), allowed); - let ctx = TemplateContext::for_input_scan(inputs.clone()); - render_source(source, &ctx, Arc::new(store), TemplateRenderMode::Lenient).with_context( - || { - let from = - from.map_or_else(|| source_path.to_string(), std::string::ToString::to_string); - format!("failed to verify template dependencies for {from}") - }, - )?; - Ok(()) -} - -fn manifest_attr_reference_kind( - scope: AttributeScope, - key: &str, - value: &str, -) -> Result { - reference_kind_for_attribute(scope, key, value) - .ok_or_else(|| anyhow!("unsupported manifest reference attribute: {key}={value}")) -} - -fn collect_config_dockerfile( - cwd: &Path, - config_path: &ManifestPath, - source: &str, - files: &mut HashMap, -) -> Result<()> { - let layer = source - .parse::() - .context("Failed to parse run config TOML")?; - let absolute_config_path = cwd.join(config_path.as_path()); - let base_dir = absolute_config_path - .parent() - .unwrap_or_else(|| Path::new(".")); - - for environment in layer.environments.values() { - collect_environment_dockerfile( - files, - base_dir, - cwd, - config_path, - environment.image.as_ref(), - )?; - } - if let Some(run_environment) = layer.run.as_ref().and_then(|run| run.environment.as_ref()) { - collect_environment_dockerfile( - files, - base_dir, - cwd, - config_path, - run_environment.image.as_ref(), - )?; - } - Ok(()) -} - -fn collect_environment_dockerfile( - files: &mut HashMap, - base_dir: &Path, - cwd: &Path, - config_path: &ManifestPath, - image: Option<&EnvironmentImageLayer>, -) -> Result<()> { - let dockerfile = image.and_then(|image| image.dockerfile.as_ref()); - let Some(EnvironmentDockerfileLayer::Path { path }) = dockerfile else { - return Ok(()); - }; - collect_bundled_file( - files, - base_dir, - cwd, - path, - types::ManifestFileRefType::Dockerfile, - ReferenceKind::Dockerfile, - Some(config_path.clone()), - )?; - Ok(()) -} - -struct BundledFile { - absolute_path: PathBuf, - path: ManifestPath, -} - -fn collect_bundled_file( - files: &mut HashMap, - base_dir: &Path, - cwd: &Path, - reference: &str, - ref_type: types::ManifestFileRefType, - reference_kind: ReferenceKind, - from: Option, -) -> Result { - reference_kind - .validate(reference) - .map_err(anyhow::Error::new)?; - - let absolute_path = normalize_absolute_path(base_dir, reference) - .ok_or_else(|| anyhow!("unsupported manifest reference: {reference}"))?; - let path = manifest_path_from_absolute(&absolute_path, cwd)?; - let key = path.to_string(); - if !files.contains_key(&key) { - let content = std::fs::read_to_string(&absolute_path) - .with_context(|| format!("Failed to read {}", absolute_path.display()))?; - files.insert(key.clone(), types::ManifestFileEntry { - content, - ref_: types::ManifestFileRef { - from: from.map(|value| value.to_string()), - original: reference.to_string(), - type_: ref_type, - }, - }); - } - - Ok(BundledFile { - absolute_path, - path, - }) -} - fn resolve_manifest_goal( run_overrides: Option<&RunLayer>, settings: &WorkflowSettings, @@ -697,8 +266,7 @@ fn resolve_manifest_goal( return Ok(None); }; if let Some(reference) = goal.strip_prefix('@') { - ReferenceKind::GraphGoalFile - .validate(reference) + validate_static_reference(reference, ReferenceKind::GraphGoalFile) .map_err(anyhow::Error::new)?; let goal_path = normalize_absolute_path( root_dot_path.parent().unwrap_or_else(|| Path::new(".")), @@ -854,12 +422,6 @@ fn manifest_path_from_absolute(path: &Path, cwd: &Path) -> Result .ok_or_else(|| anyhow!("Failed to compute manifest path for {}", path.display())) } -fn manifest_parent_or_dot(path: &ManifestPath) -> Result { - let parent = path.parent_or_dot().to_string_lossy(); - ManifestPath::from_wire(&parent) - .ok_or_else(|| anyhow!("invalid manifest parent path for {path}: {parent}")) -} - pub fn manifest_args_is_empty(args: &types::ManifestArgs) -> bool { args.auto_approve.is_none() && args.dry_run.is_none() @@ -872,6 +434,18 @@ pub fn manifest_args_is_empty(args: &types::ManifestArgs) -> bool { && args.verbose.is_none() } +#[cfg(test)] +pub(crate) mod test_fixtures { + use std::path::Path; + + pub(crate) fn write_file(path: &Path, source: &str) { + if let Some(parent) = path.parent() { + std::fs::create_dir_all(parent).expect("fixture directory should be created"); + } + std::fs::write(path, source).expect("fixture file should be written"); + } +} + #[cfg(test)] mod tests { use super::*; @@ -932,6 +506,178 @@ mod tests { assert_eq!(schema.content, schema_source); } + #[test] + fn build_manifest_characterizes_the_complete_legacy_projection() { + let temp = tempfile::tempdir().unwrap(); + let project = temp.path().join("project"); + let root = project.join(".fabro/workflows/root"); + let child = project.join(".fabro/workflows/child"); + let user_config_path = temp.path().join("home/.fabro/config.toml"); + let project_config = r#"_version = 1 + +[environments.project] +provider = "docker" + +[environments.project.image] +dockerfile = { path = "Project.Dockerfile" } +"#; + let root_config = r#"_version = 1 + +[workflow] +graph = "workflow.fabro" +"#; + let child_config = root_config; + let user_config = "_version = 1\n"; + let root_graph = r#"digraph Root { + graph [goal="@goals/goal.md"] + start [shape=Mdiamond] + prompt [prompt="@prompts/plan.md"] + schema [type="agent", prompt="schema", output_schema="@schemas/output.json"] + imported [import="imports/shared.fabro"] + child [shape=house, stack.child_workflow="../child/workflow.fabro"] + exit [shape=Msquare] + start -> prompt -> schema -> imported -> child -> exit + }"#; + let child_graph = + "digraph Child { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }"; + let imported_graph = r#"digraph Shared { + start [shape=Mdiamond] + shared [prompt="@../prompts/shared.md"] + exit [shape=Msquare] + start -> shared -> exit + }"#; + let plan_prompt = "{% include \"partial.md\" %}\n{% from \"helpers.md\" import render %}"; + let helpers = "{% macro render() %}{% include \"deep.md\" %}{% endmacro %}"; + let output_schema = r#"{"type":"object"}"#; + let write = test_fixtures::write_file; + write(&project.join(".fabro/project.toml"), project_config); + write(&project.join(".fabro/Project.Dockerfile"), "FROM project\n"); + write(&user_config_path, user_config); + write(&root.join("workflow.toml"), root_config); + write(&root.join("workflow.fabro"), root_graph); + write(&root.join("goals/goal.md"), "ship it\n"); + write(&root.join("prompts/plan.md"), plan_prompt); + write(&root.join("prompts/partial.md"), "partial\n"); + write(&root.join("prompts/helpers.md"), helpers); + write(&root.join("prompts/deep.md"), "deep\n"); + write(&root.join("prompts/shared.md"), "shared\n"); + write(&root.join("schemas/output.json"), output_schema); + write(&root.join("imports/shared.fabro"), imported_graph); + write(&child.join("workflow.toml"), child_config); + write(&child.join("workflow.fabro"), child_graph); + + let built = build_run_manifest(ManifestBuildInput { + workflow: PathBuf::from(".fabro/workflows/root/workflow.toml"), + cwd: project.clone(), + input_overrides: HashMap::from([("feature".to_owned(), toml::Value::Boolean(true))]), + args: Some(types::ManifestArgs { + dry_run: Some(true), + input: vec!["feature=true".to_owned()], + label: vec!["suite=characterization".to_owned()], + ..types::ManifestArgs::default() + }), + environment_defaults: test_environment_defaults(), + user_settings_path: Some(user_config_path), + ..ManifestBuildInput::default() + }) + .unwrap(); + + let mut actual = serde_json::to_value(&built.manifest).unwrap(); + actual["cwd"] = serde_json::json!(""); + actual["configs"][0]["path"] = serde_json::json!(""); + actual["configs"][1]["path"] = serde_json::json!(""); + fabro_test::fabro_json_snapshot!(sorted_json(actual)); + } + + /// `serde_json` is built with `preserve_order`, so `HashMap`-backed + /// manifest maps serialize in nondeterministic order; sort recursively + /// for a stable snapshot. + fn sorted_json(value: serde_json::Value) -> serde_json::Value { + match value { + serde_json::Value::Object(map) => { + let mut entries: Vec<_> = map.into_iter().collect(); + entries.sort_by(|(left, _), (right, _)| left.cmp(right)); + serde_json::Value::Object( + entries + .into_iter() + .map(|(key, value)| (key, sorted_json(value))) + .collect(), + ) + } + serde_json::Value::Array(items) => { + serde_json::Value::Array(items.into_iter().map(sorted_json).collect()) + } + other => other, + } + } + + #[test] + fn build_manifest_keeps_legacy_parent_paths_for_external_siblings() { + let temp = tempfile::tempdir().unwrap(); + let cwd = temp.path().join("checkout"); + let root = temp.path().join("user/workflows/root"); + let child = temp.path().join("user/workflows/child"); + std::fs::create_dir_all(&cwd).unwrap(); + for directory in [&root, &child] { + std::fs::create_dir_all(directory.join("prompts")).unwrap(); + std::fs::write( + directory.join("workflow.toml"), + "_version = 1\n\n[workflow]\ngraph = \"workflow.fabro\"\n", + ) + .unwrap(); + } + std::fs::write( + root.join("workflow.fabro"), + r#"digraph Root { + start [shape=Mdiamond] + prompt [prompt="@prompts/root.md"] + child [shape=house, stack.child_workflow="../child/workflow.fabro"] + exit [shape=Msquare] + start -> prompt -> child -> exit + }"#, + ) + .unwrap(); + std::fs::write(root.join("prompts/root.md"), "root prompt\n").unwrap(); + std::fs::write( + child.join("workflow.fabro"), + r#"digraph Child { + start [shape=Mdiamond] + prompt [prompt="@prompts/child.md"] + exit [shape=Msquare] + start -> prompt -> exit + }"#, + ) + .unwrap(); + std::fs::write(child.join("prompts/child.md"), "child prompt\n").unwrap(); + + let built = build_run_manifest(ManifestBuildInput { + workflow: root.join("workflow.fabro"), + cwd, + environment_defaults: test_environment_defaults(), + ..ManifestBuildInput::default() + }) + .unwrap(); + + let root_key = "../user/workflows/root/workflow.fabro"; + let child_key = "../user/workflows/child/workflow.fabro"; + assert_eq!(built.manifest.target.path, root_key); + let root_workflow = &built.manifest.workflows[root_key]; + assert_eq!( + root_workflow.config.as_ref().unwrap().path, + "../user/workflows/root/workflow.toml" + ); + let root_prompt = &root_workflow.files["../user/workflows/root/prompts/root.md"]; + assert_eq!(root_prompt.ref_.from.as_deref(), Some(root_key)); + assert_eq!(root_prompt.ref_.original, "prompts/root.md"); + let child_workflow = &built.manifest.workflows[child_key]; + assert_eq!( + child_workflow.config.as_ref().unwrap().path, + "../user/workflows/child/workflow.toml" + ); + let child_prompt = &child_workflow.files["../user/workflows/child/prompts/child.md"]; + assert_eq!(child_prompt.ref_.from.as_deref(), Some(child_key)); + } + #[test] fn build_run_overrides_sets_common_cli_and_mcp_layers() { let overrides = build_run_overrides(RunOverrideInput { @@ -1181,17 +927,26 @@ mod tests { .unwrap(); let root = &built.manifest.workflows[".fabro/workflows/demo/workflow.fabro"]; - assert!( - root.files - .contains_key(".fabro/workflows/demo/prompts/goal.tpl.md") + assert_eq!( + root.files[".fabro/workflows/demo/prompts/goal.tpl.md"] + .ref_ + .from + .as_deref(), + Some(".fabro/workflows/demo/prompts/goal.md") ); - assert!( - root.files - .contains_key(".fabro/workflows/demo/prompts/plan.tpl.md") + assert_eq!( + root.files[".fabro/workflows/demo/prompts/plan.tpl.md"] + .ref_ + .from + .as_deref(), + Some(".fabro/workflows/demo/prompts/plan.md") ); - assert!( - root.files - .contains_key(".fabro/workflows/demo/inline.tpl.md") + assert_eq!( + root.files[".fabro/workflows/demo/inline.tpl.md"] + .ref_ + .from + .as_deref(), + Some(".fabro/workflows/demo/workflow.fabro") ); } @@ -1290,7 +1045,9 @@ mod tests { .unwrap_err(); assert!( - err.to_string().contains("dynamic template dependency"), + err.chain().any(|cause| cause + .downcast_ref::() + .is_some()), "unexpected error: {err:#}" ); } diff --git a/lib/components/fabro-manifest/src/snapshots/fabro_manifest__tests__build_manifest_characterizes_the_complete_legacy_projection.snap b/lib/components/fabro-manifest/src/snapshots/fabro_manifest__tests__build_manifest_characterizes_the_complete_legacy_projection.snap new file mode 100644 index 000000000..4c655361e --- /dev/null +++ b/lib/components/fabro-manifest/src/snapshots/fabro_manifest__tests__build_manifest_characterizes_the_complete_legacy_projection.snap @@ -0,0 +1,126 @@ +--- +source: lib/components/fabro-manifest/src/lib.rs +expression: rendered +--- +{ + "args": { + "dry_run": true, + "input": [ + "feature=true" + ], + "label": [ + "suite=characterization" + ] + }, + "configs": [ + { + "path": "", + "source": "_version = 1/n/n[environments.project]/nprovider = \"docker\"/n/n[environments.project.image]/ndockerfile = { path = \"Project.Dockerfile\" }/n", + "type": "project" + }, + { + "path": "", + "source": "_version = 1/n", + "type": "user" + } + ], + "cwd": "", + "goal": { + "text": "ship it/n", + "type": "graph" + }, + "target": { + "path": ".fabro/workflows/root/workflow.fabro" + }, + "version": 1, + "workflows": { + ".fabro/workflows/child/workflow.fabro": { + "config": { + "path": ".fabro/workflows/child/workflow.toml", + "source": "_version = 1/n/n[workflow]/ngraph = \"workflow.fabro\"/n" + }, + "source": "digraph Child { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }" + }, + ".fabro/workflows/root/workflow.fabro": { + "config": { + "path": ".fabro/workflows/root/workflow.toml", + "source": "_version = 1/n/n[workflow]/ngraph = \"workflow.fabro\"/n" + }, + "files": { + ".fabro/Project.Dockerfile": { + "content": "FROM project/n", + "ref": { + "from": ".fabro/project.toml", + "original": "Project.Dockerfile", + "type": "dockerfile" + } + }, + ".fabro/workflows/root/goals/goal.md": { + "content": "ship it/n", + "ref": { + "from": ".fabro/workflows/root/workflow.fabro", + "original": "goals/goal.md", + "type": "file_inline" + } + }, + ".fabro/workflows/root/imports/shared.fabro": { + "content": "digraph Shared {/n start [shape=Mdiamond]/n shared [prompt=\"@../prompts/shared.md\"]/n exit [shape=Msquare]/n start -> shared -> exit/n }", + "ref": { + "from": ".fabro/workflows/root/workflow.fabro", + "original": "imports/shared.fabro", + "type": "import" + } + }, + ".fabro/workflows/root/prompts/deep.md": { + "content": "deep/n", + "ref": { + "from": ".fabro/workflows/root/prompts/plan.md", + "original": ".fabro/workflows/root/prompts/deep.md", + "type": "file_inline" + } + }, + ".fabro/workflows/root/prompts/helpers.md": { + "content": "{% macro render() %}{% include \"deep.md\" %}{% endmacro %}", + "ref": { + "from": ".fabro/workflows/root/prompts/plan.md", + "original": ".fabro/workflows/root/prompts/helpers.md", + "type": "file_inline" + } + }, + ".fabro/workflows/root/prompts/partial.md": { + "content": "partial/n", + "ref": { + "from": ".fabro/workflows/root/prompts/plan.md", + "original": ".fabro/workflows/root/prompts/partial.md", + "type": "file_inline" + } + }, + ".fabro/workflows/root/prompts/plan.md": { + "content": "{% include \"partial.md\" %}/n{% from \"helpers.md\" import render %}", + "ref": { + "from": ".fabro/workflows/root/workflow.fabro", + "original": "prompts/plan.md", + "type": "file_inline" + } + }, + ".fabro/workflows/root/prompts/shared.md": { + "content": "shared/n", + "ref": { + "from": ".fabro/workflows/root/imports/shared.fabro", + "original": "../prompts/shared.md", + "type": "file_inline" + } + }, + ".fabro/workflows/root/schemas/output.json": { + "content": "{\"type\":\"object\"}", + "ref": { + "from": ".fabro/workflows/root/workflow.fabro", + "original": "schemas/output.json", + "type": "file_inline" + } + } + }, + "source": "digraph Root {/n graph [goal=\"@goals/goal.md\"]/n start [shape=Mdiamond]/n prompt [prompt=\"@prompts/plan.md\"]/n schema [type=\"agent\", prompt=\"schema\", output_schema=\"@schemas/output.json\"]/n imported [import=\"imports/shared.fabro\"]/n child [shape=house, stack.child_workflow=\"../child/workflow.fabro\"]/n exit [shape=Msquare]/n start -> prompt -> schema -> imported -> child -> exit/n }" + } + } +} diff --git a/lib/components/fabro-manifest/src/workflow_bundler.rs b/lib/components/fabro-manifest/src/workflow_bundler.rs new file mode 100644 index 000000000..bd031df0b --- /dev/null +++ b/lib/components/fabro-manifest/src/workflow_bundler.rs @@ -0,0 +1,558 @@ +use std::collections::{HashMap, HashSet}; +use std::path::{Component, Path, PathBuf}; +use std::sync::Arc; + +use anyhow::{Context as _, Result, anyhow}; +use fabro_api::types; +use fabro_config::project::WorkflowLocation; +use fabro_config::{EnvironmentDockerfileLayer, EnvironmentImageLayer, SettingsLayer}; +use fabro_graphviz::parser; +use fabro_template::{ + BundleTemplateStore, FilesystemTemplateStore, GraphReference, GraphReferenceError, + RecordingTemplateStore, TemplateContext, TemplateDependencyClosure, TemplateRenderMode, + TemplateSource, validate_static_reference, visit_graph_references, +}; +use fabro_types::ManifestPath; +use fabro_types::graph::ReferenceKind; + +use crate::{manifest_path_from_absolute, normalize_absolute_path}; + +pub(super) struct WorkflowBundler<'a> { + cwd: &'a Path, + inputs: &'a HashMap, + template_store: FilesystemTemplateStore, + workflows: HashMap, + visited_workflows: HashSet, +} + +impl<'a> WorkflowBundler<'a> { + pub(super) fn new(cwd: &'a Path, inputs: &'a HashMap) -> Self { + Self { + cwd, + inputs, + template_store: FilesystemTemplateStore::new(cwd), + workflows: HashMap::new(), + visited_workflows: HashSet::new(), + } + } + + pub(super) fn bundle( + mut self, + workflow: &Path, + project_config: Option<(&ManifestPath, &str)>, + ) -> Result> { + let root_key = self.collect_workflow_entry(workflow, self.cwd)?; + + if let Some((config_path, source)) = project_config { + let mut root = self + .workflows + .remove(&root_key) + .ok_or_else(|| anyhow!("root workflow missing from manifest bundle"))?; + self.collect_config_dockerfile(config_path, source, &mut root.files)?; + self.workflows.insert(root_key, root); + } + + Ok(self.workflows) + } + + /// Collects the workflow at `location` and returns its manifest key. + fn collect_workflow_location(&mut self, location: &WorkflowLocation) -> Result { + let dot_path = manifest_path_from_absolute(&location.graph, self.cwd)?; + let dot_key = dot_path.to_string(); + if !self.visited_workflows.insert(dot_key.clone()) { + return Ok(dot_key); + } + + let source = std::fs::read_to_string(&location.graph) + .with_context(|| format!("Failed to read {}", location.graph.display()))?; + let config = if let Some(workflow_toml_path) = location.toml.as_ref() { + Some(types::ManifestWorkflowConfig { + path: manifest_path_from_absolute(workflow_toml_path, self.cwd)?.to_string(), + source: std::fs::read_to_string(workflow_toml_path) + .with_context(|| format!("Failed to read {}", workflow_toml_path.display()))?, + }) + } else { + None + }; + + let scan = WorkflowScanInput { + absolute_dot_path: location.graph.clone(), + dot_path, + source: source.clone(), + }; + let mut files = HashMap::new(); + let mut visited_imports = HashSet::new(); + if let Some(config) = config.as_ref() { + let config_path = ManifestPath::from_wire(&config.path) + .ok_or_else(|| anyhow!("invalid manifest workflow config path: {}", config.path))?; + self.collect_config_dockerfile(&config_path, &config.source, &mut files)?; + } + self.collect_workflow_files(&scan, &mut files, &mut visited_imports)?; + + self.workflows + .insert(dot_key.clone(), types::ManifestWorkflow { + config, + files, + source, + }); + + Ok(dot_key) + } + + /// Relative workflow references with an extension are lexically + /// normalized (`..` segments resolved without consulting the filesystem, + /// `~` rejected) before resolution, so the file read matches the manifest + /// key. Returns the collected workflow's manifest key. + fn collect_workflow_entry(&mut self, workflow: &Path, resolve_from: &Path) -> Result { + let normalized_workflow = if workflow.extension().is_some() && workflow.is_relative() { + normalize_absolute_path(resolve_from, &workflow.to_string_lossy()).ok_or_else(|| { + anyhow!( + "unsupported manifest workflow reference: {}", + workflow.display() + ) + })? + } else { + workflow.to_path_buf() + }; + let location = WorkflowLocation::resolve(&normalized_workflow, resolve_from)?; + self.collect_workflow_location(&location) + } + + fn collect_workflow_files( + &mut self, + workflow: &WorkflowScanInput, + files: &mut HashMap, + visited_imports: &mut HashSet, + ) -> Result<()> { + let graph = parser::parse(&workflow.source) + .with_context(|| format!("Failed to parse {}", workflow.absolute_dot_path.display()))?; + let workflow_base_dir = workflow + .absolute_dot_path + .parent() + .unwrap_or_else(|| Path::new(".")); + let workflow_template_root = manifest_parent_or_dot(&workflow.dot_path)?; + + // Imports and child workflows require a mutable borrow of self, so + // collect them during the walk and recurse after the visitor returns. + let mut imports = Vec::new(); + let mut children = Vec::new(); + + visit_graph_references(&graph, |reference| -> Result<()> { + match reference { + GraphReference::GoalFile { reference } => { + let bundled = self.collect_bundled_file( + files, + workflow_base_dir, + reference, + types::ManifestFileRefType::FileInline, + ReferenceKind::GraphGoalFile, + Some(workflow.dot_path.clone()), + )?; + self.collect_bundled_template_includes(files, &bundled, &workflow_template_root) + } + GraphReference::GoalInline { content } + | GraphReference::InlinePrompt { content } => self.collect_template_include_files( + files, + TemplateSource::new( + workflow.dot_path.clone(), + workflow_template_root.clone(), + content.to_owned(), + ), + Some(&workflow.dot_path), + ), + GraphReference::FileInline { key, reference } => { + let bundled = self.collect_bundled_file( + files, + workflow_base_dir, + reference, + types::ManifestFileRefType::FileInline, + ReferenceKind::FileInline, + Some(workflow.dot_path.clone()), + )?; + if key == "prompt" { + self.collect_bundled_template_includes( + files, + &bundled, + &workflow_template_root, + )?; + } + Ok(()) + } + GraphReference::Import { reference } => { + let imported = self.collect_bundled_file( + files, + workflow_base_dir, + reference, + types::ManifestFileRefType::Import, + ReferenceKind::Import, + Some(workflow.dot_path.clone()), + )?; + imports.push(imported); + Ok(()) + } + GraphReference::ChildWorkflow { reference } => { + children.push(reference); + Ok(()) + } + } + }) + .map_err(|error| match error { + GraphReferenceError::StaticReference(source) => anyhow::Error::new(source), + GraphReferenceError::Visit(error) => error, + })?; + + for imported in imports { + if visited_imports.insert(imported.path.to_string()) { + let imported_source = std::fs::read_to_string(&imported.absolute_path) + .with_context(|| { + format!("Failed to read {}", imported.absolute_path.display()) + })?; + let imported_scan = WorkflowScanInput { + absolute_dot_path: imported.absolute_path, + dot_path: imported.path, + source: imported_source, + }; + self.collect_workflow_files(&imported_scan, files, visited_imports)?; + } + } + for child in children { + self.collect_workflow_entry(Path::new(child), workflow_base_dir)?; + } + + Ok(()) + } + + fn collect_bundled_template_includes( + &self, + files: &mut HashMap, + bundled: &BundledFile, + workflow_template_root: &ManifestPath, + ) -> Result<()> { + let source = std::fs::read_to_string(&bundled.absolute_path) + .with_context(|| format!("Failed to read {}", bundled.absolute_path.display()))?; + let template_root = template_root_for_bundled_file(&bundled.path, workflow_template_root)?; + self.collect_template_include_files( + files, + TemplateSource::new(bundled.path.clone(), template_root, source), + Some(&bundled.path), + ) + } + + fn collect_template_include_files( + &self, + files: &mut HashMap, + source: TemplateSource, + from: Option<&ManifestPath>, + ) -> Result<()> { + let source_path = source.path.clone(); + let closure = + fabro_template::discover_static_dependency_closure([source], &self.template_store) + .context("failed to discover template dependencies")?; + self.verify_recorded_template_dependencies(&source_path, &closure, files, from)?; + + for (path, source) in closure.sources { + if path == source_path { + continue; + } + let key = path.to_string(); + files + .entry(key) + .or_insert_with(|| types::ManifestFileEntry { + content: source.content, + ref_: types::ManifestFileRef { + from: from.map(std::string::ToString::to_string), + original: path.to_string(), + type_: types::ManifestFileRefType::FileInline, + }, + }); + } + Ok(()) + } + + fn verify_recorded_template_dependencies( + &self, + source_path: &ManifestPath, + closure: &TemplateDependencyClosure, + files: &HashMap, + from: Option<&ManifestPath>, + ) -> Result<()> { + let Some(source) = closure.sources.get(source_path) else { + return Ok(()); + }; + let mut bundled_files = closure + .sources + .iter() + .map(|(path, source)| (path.clone(), source.content.clone())) + .collect::>(); + for (path, entry) in files { + if let Some(path) = ManifestPath::from_wire(path) { + bundled_files.insert(path, entry.content.clone()); + } + } + let allowed = bundled_files.keys().cloned().collect(); + let store = + RecordingTemplateStore::with_allowed(BundleTemplateStore::new(bundled_files), allowed); + let context = TemplateContext::for_input_scan(self.inputs.clone()); + fabro_template::render_source( + source, + &context, + Arc::new(store), + TemplateRenderMode::Lenient, + ) + .with_context(|| { + let from = + from.map_or_else(|| source_path.to_string(), std::string::ToString::to_string); + format!("failed to verify template dependencies for {from}") + })?; + Ok(()) + } + + fn collect_config_dockerfile( + &self, + config_path: &ManifestPath, + source: &str, + files: &mut HashMap, + ) -> Result<()> { + let layer = source + .parse::() + .context("Failed to parse run config TOML")?; + let absolute_config_path = self.cwd.join(config_path.as_path()); + let base_dir = absolute_config_path + .parent() + .unwrap_or_else(|| Path::new(".")); + + for image in layer.environment_images() { + self.collect_environment_dockerfile(files, base_dir, config_path, image)?; + } + Ok(()) + } + + fn collect_environment_dockerfile( + &self, + files: &mut HashMap, + base_dir: &Path, + config_path: &ManifestPath, + image: &EnvironmentImageLayer, + ) -> Result<()> { + let Some(EnvironmentDockerfileLayer::Path { path }) = image.dockerfile.as_ref() else { + return Ok(()); + }; + self.collect_bundled_file( + files, + base_dir, + path, + types::ManifestFileRefType::Dockerfile, + ReferenceKind::Dockerfile, + Some(config_path.clone()), + )?; + Ok(()) + } + + fn collect_bundled_file( + &self, + files: &mut HashMap, + base_dir: &Path, + reference: &str, + ref_type: types::ManifestFileRefType, + reference_kind: ReferenceKind, + from: Option, + ) -> Result { + validate_static_reference(reference, reference_kind).map_err(anyhow::Error::new)?; + + let absolute_path = normalize_absolute_path(base_dir, reference) + .ok_or_else(|| anyhow!("unsupported manifest reference: {reference}"))?; + let path = manifest_path_from_absolute(&absolute_path, self.cwd)?; + let key = path.to_string(); + if !files.contains_key(&key) { + let content = std::fs::read_to_string(&absolute_path) + .with_context(|| format!("Failed to read {}", absolute_path.display()))?; + files.insert(key.clone(), types::ManifestFileEntry { + content, + ref_: types::ManifestFileRef { + from: from.map(|value| value.to_string()), + original: reference.to_owned(), + type_: ref_type, + }, + }); + } + + Ok(BundledFile { + absolute_path, + path, + }) + } +} + +struct WorkflowScanInput { + absolute_dot_path: PathBuf, + dot_path: ManifestPath, + source: String, +} + +struct BundledFile { + absolute_path: PathBuf, + path: ManifestPath, +} + +fn manifest_parent_or_dot(path: &ManifestPath) -> Result { + let parent = path.parent_or_dot().to_string_lossy(); + ManifestPath::from_wire(&parent) + .ok_or_else(|| anyhow!("invalid manifest parent path for {path}: {parent}")) +} + +fn template_root_for_bundled_file( + path: &ManifestPath, + workflow_template_root: &ManifestPath, +) -> Result { + if manifest_path_is_within_root(path, workflow_template_root) { + Ok(workflow_template_root.clone()) + } else { + manifest_parent_or_dot(path) + } +} + +fn manifest_path_is_within_root(path: &ManifestPath, root: &ManifestPath) -> bool { + if root.as_path().as_os_str().is_empty() { + return !matches!( + path.as_path().components().next(), + Some(Component::ParentDir) + ); + } + path.starts_with(root) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_fixtures::write_file; + + fn bundle_graph(cwd: &Path, graph: &Path) -> Result> { + let inputs = HashMap::new(); + WorkflowBundler::new(cwd, &inputs).bundle(graph, None) + } + + #[test] + fn repeated_references_collect_one_file() { + let temp = tempfile::tempdir().expect("temp directory should be created"); + let graph = temp.path().join("workflow.fabro"); + write_file( + &graph, + r#"digraph Root { + start [shape=Mdiamond] + first [prompt="@prompt.md"] + second [prompt="@prompt.md"] + exit [shape=Msquare] + start -> first -> second -> exit + }"#, + ); + write_file(&temp.path().join("prompt.md"), "prompt\n"); + + let workflows = bundle_graph(temp.path(), &graph).expect("workflow should bundle"); + + assert_eq!(workflows["workflow.fabro"].files.len(), 1); + } + + #[test] + fn graph_goal_bundles_filename_with_at_prefix() { + let temp = tempfile::tempdir().expect("temp directory should be created"); + let graph = temp.path().join("workflow.fabro"); + write_file( + &graph, + r#"digraph Root { + graph [goal="@@goal.md"] + start [shape=Mdiamond] + exit [shape=Msquare] + start -> exit + }"#, + ); + write_file(&temp.path().join("@goal.md"), "goal\n"); + + let workflows = bundle_graph(temp.path(), &graph).expect("workflow should bundle"); + + let goal = &workflows["workflow.fabro"].files["@goal.md"]; + assert_eq!(goal.content, "goal\n"); + assert_eq!(goal.ref_.original, "@goal.md"); + } + + #[test] + fn parse_errors_keep_the_graphviz_error_in_the_source_chain() { + let temp = tempfile::tempdir().expect("temp directory should be created"); + let graph = temp.path().join("workflow.fabro"); + write_file(&graph, "not a graph"); + + let error = bundle_graph(temp.path(), &graph).expect_err("invalid graph should fail"); + + assert!( + error + .chain() + .any(|cause| cause.downcast_ref::().is_some()), + "unexpected error chain: {error:#}" + ); + } + + #[test] + fn read_errors_keep_the_io_error_in_the_source_chain() { + let temp = tempfile::tempdir().expect("temp directory should be created"); + let graph = temp.path().join("workflow.fabro"); + write_file( + &graph, + r#"digraph Root { + start [shape=Mdiamond] + work [prompt="@missing.md"] + exit [shape=Msquare] + start -> work -> exit + }"#, + ); + + let error = bundle_graph(temp.path(), &graph).expect_err("missing file should fail"); + + assert!( + error + .chain() + .any(|cause| cause.downcast_ref::().is_some()), + "unexpected error chain: {error:#}" + ); + } + + #[cfg(unix)] + #[test] + fn root_workflow_normalizes_parent_components_lexically_before_reading() { + let temp = tempfile::tempdir().expect("temp directory should be created"); + let cwd = temp.path(); + let lexical_graph = + "digraph Lexical { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }"; + let symlinked_graph = + "digraph Symlinked { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }"; + write_file(&cwd.join("wf/workflow.fabro"), lexical_graph); + write_file(&cwd.join("nested/wf/workflow.fabro"), symlinked_graph); + std::fs::create_dir_all(cwd.join("nested/elsewhere")) + .expect("symlink target should be created"); + // `link` points into `nested/`, so OS resolution of `link/..` lands in + // `nested/` while lexical resolution lands in the invocation directory. + std::os::unix::fs::symlink(cwd.join("nested/elsewhere"), cwd.join("link")) + .expect("symlink should be created"); + + let workflows = bundle_graph(cwd, Path::new("link/../wf/workflow.fabro")) + .expect("workflow should bundle"); + + // `link/..` must resolve lexically to `wf/workflow.fabro`, not through + // the symlink to `nested/wf/workflow.fabro`, so the bundled source + // matches the file the manifest key names. + assert_eq!(workflows["wf/workflow.fabro"].source, lexical_graph); + } + + #[test] + fn root_workflow_rejects_tilde_relative_references() { + let temp = tempfile::tempdir().expect("temp directory should be created"); + + let error = bundle_graph(temp.path(), Path::new("~/workflow.fabro")) + .expect_err("tilde reference should be rejected"); + + assert!( + error + .to_string() + .contains("unsupported manifest workflow reference"), + "unexpected error: {error:#}" + ); + } +} diff --git a/lib/components/fabro-sandbox/src/daytona/mod.rs b/lib/components/fabro-sandbox/src/daytona/mod.rs index 6371f23d2..91a0cc797 100644 --- a/lib/components/fabro-sandbox/src/daytona/mod.rs +++ b/lib/components/fabro-sandbox/src/daytona/mod.rs @@ -68,6 +68,12 @@ const DAYTONA_START_TIMEOUT: Duration = Duration::from_mins(1); /// deletion, temporary stdin files) so a stalled REST call cannot block /// cancellation/timeout paths indefinitely. const DAYTONA_CLEANUP_TIMEOUT: Duration = Duration::from_secs(10); +/// Auto-stop applied when `lifecycle.auto_stop` is unset. Omitting the field +/// would inherit Daytona's server-side default of 15 idle minutes, which is +/// shorter than a single long inference call and stops the sandbox mid-run; +/// 120 minutes clears any realistic call while still reclaiming sandboxes +/// leaked by a dead worker. An explicit `0` disables auto-stop entirely. +const DEFAULT_AUTO_STOP_INTERVAL_MINUTES: i32 = 120; /// Permissions a Daytona API key needs for Fabro's snapshot and sandbox flow. pub const REQUIRED_DAYTONA_PERMISSIONS: &[Permissions] = &[ @@ -727,7 +733,10 @@ impl DaytonaSandbox { daytona_sdk::SandboxBaseParams { name: Some(name), env_vars: Some(clean_bash_env(None)), - auto_stop_interval: self.config.auto_stop_interval, + auto_stop_interval: self + .config + .auto_stop_interval + .or(Some(DEFAULT_AUTO_STOP_INTERVAL_MINUTES)), labels: Some(managed_labels::merge_for_run( self.config.labels.as_ref(), self.run_id.as_ref(), @@ -2950,6 +2959,10 @@ mod tests { assert_eq!(params.ephemeral, Some(false)); assert_eq!(params.auto_delete_interval, Some(-1)); + assert_eq!( + params.auto_stop_interval, + Some(DEFAULT_AUTO_STOP_INTERVAL_MINUTES) + ); assert_eq!( params.env_vars, Some(HashMap::from([(BASH_ENV_VAR.to_string(), String::new())])) @@ -2963,6 +2976,27 @@ mod tests { ); } + #[tokio::test] + async fn base_params_passes_explicit_auto_stop_through() { + for interval in [0, 45] { + let sandbox = DaytonaSandbox::new( + DaytonaConfig { + auto_stop_interval: Some(interval), + ..DaytonaConfig::default() + }, + None, + None, + None, + None, + Some("dtn_test".to_string()), + ) + .await + .expect("sandbox config should be valid"); + + assert_eq!(sandbox.base_params().auto_stop_interval, Some(interval)); + } + } + #[tokio::test] async fn activate_skips_start_when_daytona_reports_started() { let server = MockServer::start_async().await; diff --git a/lib/components/fabro-store/src/blob_store.rs b/lib/components/fabro-store/src/blob_store.rs new file mode 100644 index 000000000..6d19ed978 --- /dev/null +++ b/lib/components/fabro-store/src/blob_store.rs @@ -0,0 +1,301 @@ +use std::sync::Arc; + +use bytes::Bytes; +use fabro_types::BlobHash; +use sqlx::SqlitePool; + +use crate::record::{RawBytesCodec, Record, Repository}; +use crate::{Error, Result}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Blob(pub Bytes); + +impl AsRef<[u8]> for Blob { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl From for Blob { + fn from(value: Bytes) -> Self { + Self(value) + } +} + +impl Record for Blob { + type Id = BlobHash; + type Codec = RawBytesCodec; + + const PREFIX: &'static str = "blobs/sha256"; + + fn id(&self) -> Self::Id { + BlobHash::new(&self.0) + } +} + +/// Which storage engine holds the blobs. +/// +/// This enum is a transition vehicle, not a permanent abstraction: `Slate` +/// preserves current production behavior while the SQLite backend rolls out. +/// Once runtime blob storage switches to SQLite and legacy blobs are +/// imported, delete the `Slate` arm (and this enum) and inline the SQLite +/// implementation into [`BlobStore`]. The SQLite arm's semantics — verified +/// reads and loud failure on hash conflicts — are the intended end state. +enum BlobBackend { + Slate(Repository), + Sqlite(SqlitePool), +} + +pub struct BlobStore { + backend: BlobBackend, +} + +impl std::fmt::Debug for BlobStore { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let backend = match &self.backend { + BlobBackend::Slate(_) => "slate", + BlobBackend::Sqlite(_) => "sqlite", + }; + f.debug_struct("BlobStore") + .field("backend", &backend) + .finish_non_exhaustive() + } +} + +impl BlobStore { + /// Creates a blob store backed by a SQLite pool whose migrations have run. + #[must_use] + pub fn new(pool: SqlitePool) -> Self { + Self { + backend: BlobBackend::Sqlite(pool), + } + } + + pub(crate) fn from_slate(db: Arc) -> Self { + Self { + backend: BlobBackend::Slate(Repository::new(db)), + } + } + + pub async fn write(&self, bytes: &[u8]) -> Result { + match &self.backend { + BlobBackend::Slate(repo) => { + let blob = Blob(Bytes::copy_from_slice(bytes)); + let id = blob.id(); + repo.put(&blob).await?; + Ok(id) + } + BlobBackend::Sqlite(pool) => { + let blob_hash = BlobHash::new(bytes); + let result = sqlx::query( + "INSERT INTO blobs (hash, data) VALUES (?, ?) \ + ON CONFLICT(hash) DO NOTHING", + ) + .bind(blob_hash.to_string()) + .bind(bytes) + .execute(pool) + .await?; + + if result.rows_affected() == 1 { + return Ok(blob_hash); + } + + let stored: Vec = sqlx::query_scalar("SELECT data FROM blobs WHERE hash = ?") + .bind(blob_hash.to_string()) + .fetch_one(pool) + .await?; + if stored == bytes { + Ok(blob_hash) + } else { + Err(Error::BlobHashConflict { blob_hash }) + } + } + } + } + + pub async fn read(&self, blob_hash: &BlobHash) -> Result> { + match &self.backend { + BlobBackend::Slate(repo) => Ok(repo.get(blob_hash).await?.map(|blob| blob.0)), + BlobBackend::Sqlite(pool) => { + let stored: Option> = + sqlx::query_scalar("SELECT data FROM blobs WHERE hash = ?") + .bind(blob_hash.to_string()) + .fetch_optional(pool) + .await?; + let Some(stored) = stored else { + return Ok(None); + }; + if BlobHash::new(&stored) != *blob_hash { + return Err(Error::BlobIntegrity { + blob_hash: *blob_hash, + }); + } + Ok(Some(Bytes::from(stored))) + } + } + } + + pub async fn exists(&self, blob_hash: &BlobHash) -> Result { + match &self.backend { + BlobBackend::Slate(repo) => repo.exists(blob_hash).await, + BlobBackend::Sqlite(pool) => { + let exists: bool = + sqlx::query_scalar("SELECT EXISTS(SELECT 1 FROM blobs WHERE hash = ?)") + .bind(blob_hash.to_string()) + .fetch_one(pool) + .await?; + Ok(exists) + } + } + } +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + use std::time::Duration; + + use bytes::Bytes; + use fabro_types::BlobHash; + use object_store::memory::InMemory; + + use super::BlobStore; + use crate::keys::SlateKey; + use crate::{Database, Error}; + + type TestResult = std::result::Result>; + + async fn slate_store() -> Arc { + let db = Database::new( + Arc::new(InMemory::new()), + "", + Duration::from_millis(1), + None, + ); + db.blobs().await.unwrap() + } + + async fn raw_slate_store(name: &str) -> (Arc, BlobStore) { + let raw_db = Arc::new( + slatedb::Db::open(name, Arc::new(InMemory::new())) + .await + .unwrap(), + ); + let store = BlobStore::from_slate(raw_db.clone()); + (raw_db, store) + } + + async fn sqlite_store() -> TestResult<(tempfile::TempDir, fabro_db::Database, BlobStore)> { + let dir = tempfile::tempdir()?; + let database = fabro_db::Database::connect(dir.path().join("fabro.sqlite3")).await?; + database.migrate().await?; + let store = BlobStore::new(database.clone_pool()); + Ok((dir, database, store)) + } + + #[tokio::test] + async fn slate_writes_reads_and_checks_existence() { + let store = slate_store().await; + let bytes = b"hello world"; + let id = store.write(bytes).await.unwrap(); + + assert_eq!( + store.read(&id).await.unwrap(), + Some(Bytes::from_static(bytes)) + ); + assert_eq!(store.write(bytes).await.unwrap(), id); + assert!(store.exists(&id).await.unwrap()); + assert!(!store.exists(&BlobHash::new(b"missing")).await.unwrap()); + } + + #[tokio::test] + async fn slate_empty_blobs_round_trip() { + let store = slate_store().await; + let id = store.write(b"").await.unwrap(); + + assert_eq!(store.read(&id).await.unwrap(), Some(Bytes::new())); + } + + #[tokio::test] + async fn raw_slate_db_reads_exact_blob_bytes() { + let (raw_db, store) = raw_slate_store("blob-store-tests").await; + let bytes = b"{\"ok\":true}"; + let id = store.write(bytes).await.unwrap(); + + let saved = raw_db + .get(SlateKey::new("blobs").with("sha256").with(id)) + .await + .unwrap() + .unwrap(); + assert_eq!(saved.as_ref(), bytes); + } + + #[tokio::test] + async fn sqlite_writes_reads_and_checks_existence() -> TestResult<()> { + let (_dir, database, store) = sqlite_store().await?; + let store = Arc::new(store); + + let binary = [0_u8, 0xff, 0x80, b'a']; + let (first_write, concurrent_write) = + tokio::join!(store.write(&binary), store.write(&binary)); + let binary_hash = first_write?; + assert_eq!(concurrent_write?, binary_hash); + let empty_hash = store.write(b"").await?; + + assert_eq!(store.write(&binary).await?, binary_hash); + assert_eq!( + store.read(&binary_hash).await?, + Some(Bytes::copy_from_slice(&binary)) + ); + assert_eq!(store.read(&empty_hash).await?, Some(Bytes::new())); + assert!(store.exists(&binary_hash).await?); + let missing_hash = BlobHash::new(b"missing"); + assert_eq!(store.read(&missing_hash).await?, None); + assert!(!store.exists(&missing_hash).await?); + + let row_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM blobs") + .fetch_one(database.pool()) + .await?; + assert_eq!(row_count, 2); + Ok(()) + } + + #[tokio::test] + async fn sqlite_write_rejects_conflicting_stored_bytes() -> TestResult<()> { + let (_dir, database, store) = sqlite_store().await?; + let expected = b"expected"; + let blob_hash = BlobHash::new(expected); + sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, ?)") + .bind(blob_hash.to_string()) + .bind(b"different".as_slice()) + .execute(database.pool()) + .await?; + + let error = store + .write(expected) + .await + .expect_err("conflicting bytes should fail"); + assert!( + matches!(error, Error::BlobHashConflict { blob_hash: value } if value == blob_hash) + ); + Ok(()) + } + + #[tokio::test] + async fn sqlite_read_rejects_bytes_that_do_not_match_hash() -> TestResult<()> { + let (_dir, database, store) = sqlite_store().await?; + let blob_hash = BlobHash::new(b"expected"); + sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, ?)") + .bind(blob_hash.to_string()) + .bind(b"different".as_slice()) + .execute(database.pool()) + .await?; + + let error = store + .read(&blob_hash) + .await + .expect_err("mismatched stored bytes should fail"); + assert!(matches!(error, Error::BlobIntegrity { blob_hash: value } if value == blob_hash)); + Ok(()) + } +} diff --git a/lib/components/fabro-store/src/error.rs b/lib/components/fabro-store/src/error.rs index 3b6c93f5d..7cc31d9f5 100644 --- a/lib/components/fabro-store/src/error.rs +++ b/lib/components/fabro-store/src/error.rs @@ -1,3 +1,5 @@ +use fabro_types::BlobHash; + pub type Result = std::result::Result; #[derive(Debug, thiserror::Error)] @@ -10,6 +12,10 @@ pub enum Error { Serde(#[from] serde_json::Error), #[error("SQLite error: {0}")] Sqlite(#[from] sqlx::Error), + #[error("stored blob {blob_hash} has bytes that conflict with its hash")] + BlobHashConflict { blob_hash: BlobHash }, + #[error("stored blob data does not match requested hash {blob_hash}")] + BlobIntegrity { blob_hash: BlobHash }, #[error("I/O error: {0}")] Io(#[from] std::io::Error), #[error("Invalid event payload: {0}")] diff --git a/lib/components/fabro-store/src/keys.rs b/lib/components/fabro-store/src/keys.rs index 343cdc1d0..13f24a246 100644 --- a/lib/components/fabro-store/src/keys.rs +++ b/lib/components/fabro-store/src/keys.rs @@ -1,7 +1,7 @@ use std::fmt::{self, Write}; use std::ops::Range; -use fabro_types::{RunBlobId, RunId, SessionId}; +use fabro_types::{RunId, SessionId}; pub(crate) const MAX_EVENT_SEQ: u32 = 999_999; @@ -91,10 +91,6 @@ pub(crate) fn run_events_range(run_id: &RunId, start_seq: u32) -> Range SlateKey { - SlateKey::new("blobs").with("sha256").into_prefix() -} - pub(crate) fn sessions_by_id_prefix() -> SlateKey { SlateKey::new("sessions").with("by-id").into_prefix() } @@ -115,21 +111,6 @@ pub(crate) fn parse_event_seq(key: &str) -> Option { segments.next()?.split_once('-')?.0.parse().ok() } -pub(crate) fn parse_blob_id(key: &str) -> Option { - let mut segments = SlateKey::segments(key); - if segments.next()? != "blobs" { - return None; - } - if segments.next()? != "sha256" { - return None; - } - let id = segments.next()?; - if segments.next().is_some() { - return None; - } - id.parse().ok() -} - #[cfg(test)] mod tests { use fabro_types::RunId; @@ -161,14 +142,6 @@ mod tests { ]); } - #[test] - fn blob_key_segments() { - let blob_id = RunBlobId::new(b"summary"); - let key = SlateKey::new("blobs").with("sha256").with(blob_id); - let segments: Vec<&str> = SlateKey::segments(key.as_str()).collect(); - assert_eq!(segments, ["blobs", "sha256", &blob_id.to_string()]); - } - #[test] fn sequence_keys_are_zero_padded() { let run_id: RunId = "01JT56VE4Z5NZ814GZN2JZD65A".parse().unwrap(); @@ -196,20 +169,16 @@ mod tests { } #[test] - fn parse_helpers_roundtrip() { + fn parse_event_seq_roundtrips() { let run_id: RunId = "01JT56VE4Z5NZ814GZN2JZD65A".parse().unwrap(); assert_eq!( parse_event_seq(run_event_key(&run_id, 7, 123).as_str()), Some(7) ); - - let blob_id = RunBlobId::new(b"summary"); - let key = SlateKey::new("blobs").with("sha256").with(blob_id); - assert_eq!(parse_blob_id(key.as_str()), Some(blob_id)); } #[test] - fn parse_helpers_reject_invalid_keys() { + fn parse_event_seq_rejects_invalid_keys() { assert_eq!( parse_event_seq( SlateKey::new("runs") @@ -220,18 +189,5 @@ mod tests { ), None ); - assert_eq!( - parse_blob_id(SlateKey::new("blobs").with("not-a-uuid").as_str()), - None - ); - assert_eq!( - parse_blob_id( - SlateKey::new("blobs") - .with("01JT56VE4Z5NZ814GZN2JZD65A") - .with("not-a-blob") - .as_str() - ), - None - ); } } diff --git a/lib/components/fabro-store/src/lib.rs b/lib/components/fabro-store/src/lib.rs index e99eadd0f..00a95d4e0 100644 --- a/lib/components/fabro-store/src/lib.rs +++ b/lib/components/fabro-store/src/lib.rs @@ -1,6 +1,7 @@ use chrono::{DateTime, Utc}; mod artifact_store; +mod blob_store; mod error; mod keyed_mutex; mod keys; @@ -18,9 +19,10 @@ pub use artifact_store::{ ArtifactKey, ArtifactStore, NodeArtifact, StageArtifactEntry, retry_storage_segment, stage_storage_segment, }; +pub use blob_store::{Blob, BlobStore}; pub use error::{Error, Result}; pub use fabro_types::{ - EventEnvelope, PendingInterviewRecord, Run, RunBlobId, RunProjection, StageId, StageProjection, + BlobHash, EventEnvelope, PendingInterviewRecord, Run, RunProjection, StageId, StageProjection, }; pub use keyed_mutex::{KeyedMutex, KeyedMutexGuard}; pub use run_sessions::{ @@ -34,8 +36,8 @@ pub use run_summary_store::{ }; pub use serializable_projection::SerializableProjection; pub use slate::{ - AuthCode, AuthCodeStore, Blob, BlobStore, CachedRunProjection, ConsumeOutcome, Database, - RefreshToken, RefreshTokenStore, RunCatalogIndex, RunDatabase, Runs, UnreadableRun, + AuthCode, AuthCodeStore, CachedRunProjection, ConsumeOutcome, Database, RefreshToken, + RefreshTokenStore, RunCatalogIndex, RunDatabase, Runs, UnreadableRun, }; pub use types::EventPayload; diff --git a/lib/components/fabro-store/src/record/record_id.rs b/lib/components/fabro-store/src/record/record_id.rs index 1ce67f069..b926d9c12 100644 --- a/lib/components/fabro-store/src/record/record_id.rs +++ b/lib/components/fabro-store/src/record/record_id.rs @@ -1,4 +1,4 @@ -use fabro_types::{RunBlobId, RunId}; +use fabro_types::{BlobHash, RunId}; use super::RecordId; use crate::{Error, Result}; @@ -38,7 +38,7 @@ impl RecordId for String { } } -impl RecordId for RunBlobId { +impl RecordId for BlobHash { fn key_segments(&self) -> Vec { vec![self.to_string()] } @@ -46,13 +46,13 @@ impl RecordId for RunBlobId { fn from_key_segments(segs: &[&str]) -> Result { let [segment] = segs else { return Err(Error::KeyParse(format!( - "expected 1 segment for RunBlobId, got {}", + "expected 1 segment for BlobHash, got {}", segs.len() ))); }; segment .parse() - .map_err(|err| Error::KeyParse(format!("invalid RunBlobId segment {segment:?}: {err}"))) + .map_err(|err| Error::KeyParse(format!("invalid BlobHash segment {segment:?}: {err}"))) } } diff --git a/lib/components/fabro-store/src/run_state.rs b/lib/components/fabro-store/src/run_state.rs index 720a76f0e..4e2c35621 100644 --- a/lib/components/fabro-store/src/run_state.rs +++ b/lib/components/fabro-store/src/run_state.rs @@ -1681,15 +1681,16 @@ mod tests { use fabro_types::settings::run::{DockerfileSource, EnvironmentProvider}; use fabro_types::{ AgentBackend, AgentControlState, AttrValue, AutomationRef, BilledModelUsage, - BilledTokenCounts, BlockedReason, Checkpoint, CheckpointRecord, CommandTermination, - EventBody, FailureCategory, FailureDetail, FailureReason, Graph, McpServerStatus, Node, - Outcome, ParallelBranchId, PendingReason, PermissionLevel, PullRequestCreationStatus, - PullRequestLink, QuestionType, ReasoningEffort, RunApprovalState, RunBillingSummary, - RunBlobId, RunControlAction, RunDiff, RunEvent, RunSize, RunSpec, RunStatus, Speed, - StageContextWindowBreakdownItem, StageContextWindowCategory, StageContextWindowCountMethod, - StageContextWindowProjection, StageContextWindowStaleness, StageContextWindowWarning, - StageHandler, StageModelUsage, StageOutcome, StageState, StageTiming, SubAgentStatus, - SuccessReason, WorkflowSettings, first_event_seq, fixtures, test_support, + BilledTokenCounts, BlobHash, BlockedReason, Checkpoint, CheckpointRecord, + CommandTermination, EventBody, FailureCategory, FailureDetail, FailureReason, Graph, + McpServerStatus, Node, Outcome, ParallelBranchId, PendingReason, PermissionLevel, + PullRequestCreationStatus, PullRequestLink, QuestionType, ReasoningEffort, + RunApprovalState, RunBillingSummary, RunControlAction, RunDiff, RunEvent, RunSize, RunSpec, + RunStatus, Speed, StageContextWindowBreakdownItem, StageContextWindowCategory, + StageContextWindowCountMethod, StageContextWindowProjection, StageContextWindowStaleness, + StageContextWindowWarning, StageHandler, StageModelUsage, StageOutcome, StageState, + StageTiming, SubAgentStatus, SuccessReason, WorkflowSettings, first_event_seq, fixtures, + test_support, }; use serde_json::json; @@ -2272,19 +2273,8 @@ mod tests { fn test_run_spec() -> RunSpec { RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: Graph::new("test"), - graph_source: Some("digraph test {}".to_string()), - workflow_slug: None, - automation: None, - source_directory: None, - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: None, - fork_source_ref: None, + graph_source: Some("digraph test {}".to_string()), + ..test_support::test_run_spec() } } @@ -4077,19 +4067,9 @@ mod tests { fn summary_synthesizes_submitted_when_run_exists_without_status() { let mut state = initialized_projection(); state.spec = fabro_types::RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: fabro_types::Graph::new("test"), - graph_source: None, - workflow_slug: Some("test".to_string()), - automation: None, + workflow_slug: Some("test".to_string()), source_directory: Some("/tmp/repo".to_string()), - git: None, - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - fork_source_ref: None, + ..test_support::test_run_spec() }; let summary_json = serde_json::to_value(build_summary(&state, &fixtures::RUN_1)).unwrap(); @@ -4103,19 +4083,10 @@ mod tests { fn summary_preserves_absent_workflow_name_and_reports_graph_name() { let mut state = initialized_projection(); state.spec = fabro_types::RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: fabro_types::Graph::new("GraphName"), - graph_source: None, - workflow_slug: Some("release-flow".to_string()), - automation: None, + graph: fabro_types::Graph::new("GraphName"), + workflow_slug: Some("release-flow".to_string()), source_directory: Some("/tmp/repo".to_string()), - git: None, - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - fork_source_ref: None, + ..test_support::test_run_spec() }; let summary = build_summary(&state, &fixtures::RUN_1); @@ -4229,9 +4200,9 @@ mod tests { #[test] fn projection_serialization_includes_manifest_and_definition_blob_refs() { - let manifest_blob = RunBlobId::new(br#"{"version":1}"#).to_string(); + let manifest_blob = BlobHash::new(br#"{"version":1}"#).to_string(); let definition_blob = - RunBlobId::new(br#"{"version":1,"workflow_path":"workflow.fabro"}"#).to_string(); + BlobHash::new(br#"{"version":1,"workflow_path":"workflow.fabro"}"#).to_string(); let events = vec![ EventEnvelope { seq: 1, diff --git a/lib/components/fabro-store/src/slate/blob_store.rs b/lib/components/fabro-store/src/slate/blob_store.rs deleted file mode 100644 index 3c058b3c8..000000000 --- a/lib/components/fabro-store/src/slate/blob_store.rs +++ /dev/null @@ -1,132 +0,0 @@ -use std::sync::Arc; - -use bytes::Bytes; -use fabro_types::RunBlobId; - -use crate::Result; -use crate::record::{RawBytesCodec, Record, Repository}; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Blob(pub Bytes); - -impl AsRef<[u8]> for Blob { - fn as_ref(&self) -> &[u8] { - self.0.as_ref() - } -} - -impl From for Blob { - fn from(value: Bytes) -> Self { - Self(value) - } -} - -impl Record for Blob { - type Id = RunBlobId; - type Codec = RawBytesCodec; - - const PREFIX: &'static str = "blobs/sha256"; - - fn id(&self) -> Self::Id { - RunBlobId::new(&self.0) - } -} - -pub struct BlobStore { - repo: Repository, -} - -impl std::fmt::Debug for BlobStore { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("BlobStore").finish_non_exhaustive() - } -} - -impl BlobStore { - pub(crate) fn new(db: Arc) -> Self { - Self { - repo: Repository::new(db), - } - } - - pub async fn write(&self, bytes: &[u8]) -> Result { - let blob = Blob(Bytes::copy_from_slice(bytes)); - let id = blob.id(); - self.repo.put(&blob).await?; - Ok(id) - } - - pub async fn read(&self, id: &RunBlobId) -> Result> { - Ok(self.repo.get(id).await?.map(|blob| blob.0)) - } - - pub async fn exists(&self, id: &RunBlobId) -> Result { - self.repo.exists(id).await - } -} - -#[cfg(test)] -mod tests { - use std::sync::Arc; - use std::time::Duration; - - use bytes::Bytes; - use fabro_types::RunBlobId; - use object_store::memory::InMemory; - - use super::BlobStore; - use crate::Database; - use crate::keys::SlateKey; - - async fn store() -> Arc { - let db = Database::new( - Arc::new(InMemory::new()), - "", - Duration::from_millis(1), - None, - ); - db.blobs().await.unwrap() - } - - #[tokio::test] - async fn writes_reads_and_checks_existence() { - let store = store().await; - let bytes = b"hello world"; - let id = store.write(bytes).await.unwrap(); - - assert_eq!( - store.read(&id).await.unwrap(), - Some(Bytes::from_static(bytes)) - ); - assert_eq!(store.write(bytes).await.unwrap(), id); - assert!(store.exists(&id).await.unwrap()); - assert!(!store.exists(&RunBlobId::new(b"missing")).await.unwrap()); - } - - #[tokio::test] - async fn empty_blobs_round_trip() { - let store = store().await; - let id = store.write(b"").await.unwrap(); - - assert_eq!(store.read(&id).await.unwrap(), Some(Bytes::new())); - } - - #[tokio::test] - async fn raw_db_reads_exact_blob_bytes() { - let raw_db = Arc::new( - slatedb::Db::open("blob-store-tests", Arc::new(InMemory::new())) - .await - .unwrap(), - ); - let store = BlobStore::new(Arc::clone(&raw_db)); - let bytes = b"{\"ok\":true}"; - let id = store.write(bytes).await.unwrap(); - - let saved = raw_db - .get(SlateKey::new("blobs").with("sha256").with(id)) - .await - .unwrap() - .unwrap(); - assert_eq!(saved.as_ref(), bytes); - } -} diff --git a/lib/components/fabro-store/src/slate/mod.rs b/lib/components/fabro-store/src/slate/mod.rs index 5d9ae3bd9..efed28796 100644 --- a/lib/components/fabro-store/src/slate/mod.rs +++ b/lib/components/fabro-store/src/slate/mod.rs @@ -1,6 +1,5 @@ mod auth_codes; mod auth_tokens; -mod blob_store; mod projection_cache; mod run_catalog_index; mod run_store; @@ -12,7 +11,6 @@ use std::time::Duration; pub use auth_codes::{AuthCode, AuthCodeStore}; pub use auth_tokens::{ConsumeOutcome, RefreshToken, RefreshTokenStore}; -pub use blob_store::{Blob, BlobStore}; use chrono::{DateTime, Utc}; use fabro_types::{Run, RunId, SessionId}; use object_store::ObjectStore; @@ -25,7 +23,7 @@ use slatedb::config::{CompressionCodec, Settings}; use tokio::sync::{Mutex, OnceCell}; use tracing::warn; -use crate::{Error, ListRunsQuery, Result, RunProjection, RunSummaryStore, keys}; +use crate::{BlobStore, Error, ListRunsQuery, Result, RunProjection, RunSummaryStore, keys}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct UnreadableRun { @@ -143,18 +141,23 @@ impl Database { .map(RunDatabase::from_inner) } - pub async fn create_run(&self, run_id: &RunId) -> Result { - self.warm_projection_cache().await?; - let db = self.open_db().await?; - - self.catalog_index().await?.add(run_id).await?; - let run_store = RunDatabase::open_writer( + /// Builds a run handle wired to the Database-owned shared stores. + async fn open_run_database(&self, run_id: &RunId, read_only: bool) -> Result { + RunDatabase::build( *run_id, - db, + self.open_db().await?, + read_only, + self.blobs().await?, Arc::clone(&self.projection_cache), Arc::clone(&self.run_summary_store), ) - .await?; + .await + } + + pub async fn create_run(&self, run_id: &RunId) -> Result { + self.warm_projection_cache().await?; + self.catalog_index().await?.add(run_id).await?; + let run_store = self.open_run_database(run_id, false).await?; let mut active_runs = self.active_runs.lock().await; Self::cache_active_run(&mut active_runs, &run_store); Ok(run_store) @@ -178,13 +181,7 @@ impl Database { if !RunDatabase::has_any_events(&db, run_id).await? { return Err(Error::RunNotFound(run_id.to_string())); } - let run_store = RunDatabase::open_writer( - *run_id, - db, - Arc::clone(&self.projection_cache), - Arc::clone(&self.run_summary_store), - ) - .await?; + let run_store = self.open_run_database(run_id, false).await?; Self::cache_active_run(&mut active_runs, &run_store); Ok(run_store) } @@ -202,13 +199,7 @@ impl Database { if !RunDatabase::has_any_events(&db, run_id).await? { return Err(Error::RunNotFound(run_id.to_string())); } - RunDatabase::open_reader( - *run_id, - db, - Arc::clone(&self.projection_cache), - Arc::clone(&self.run_summary_store), - ) - .await + self.open_run_database(run_id, true).await } pub async fn list_runs(&self, query: &ListRunsQuery, now: DateTime) -> Result> { @@ -456,7 +447,7 @@ impl Database { .blobs .get_or_try_init(|| async { let db = Arc::new(self.open_db().await?); - Ok::<_, Error>(Arc::new(BlobStore::new(db))) + Ok::<_, Error>(Arc::new(BlobStore::from_slate(db))) }) .await?; Ok(Arc::clone(store)) @@ -843,12 +834,12 @@ mod tests { append_created(&run_2, "run-2", dt("2026-03-27T12:00:10Z")).await; let shared_blob = br#"{"summary":"shared"}"#; - let shared_blob_id = run_1.write_blob(shared_blob).await.unwrap(); + let shared_blob_hash = run_1.write_blob(shared_blob).await.unwrap(); store.delete_run(&test_run_id("run-1")).await.unwrap(); let reopened = store.open_run(&test_run_id("run-2")).await.unwrap(); - let read = reopened.read_blob(&shared_blob_id).await.unwrap(); + let read = reopened.read_blob(&shared_blob_hash).await.unwrap(); assert_eq!(read.as_deref(), Some(shared_blob.as_slice())); } @@ -857,8 +848,21 @@ mod tests { let (_object_store, store) = make_store(); let run = store.create_run(&test_run_id("run-1")).await.unwrap(); append_created(&run, "run-1", dt("2026-03-27T12:00:00Z")).await; + let blob = br#"{"summary":"readable"}"#; + let blob_hash = run.write_blob(blob).await.unwrap(); + + // Evict the cached writer so the reader is built through the real + // `open_run_reader` construction path, not a clone of the writer. + let _ = store.remove_active_run(&test_run_id("run-1")).await; let reader = store.open_run_reader(&test_run_id("run-1")).await.unwrap(); + assert_eq!( + reader.read_blob(&blob_hash).await.unwrap().as_deref(), + Some(blob.as_slice()) + ); + let err = reader.write_blob(b"blocked").await.unwrap_err(); + assert!(matches!(err, Error::ReadOnly)); + let err = reader .append_event(&event_payload( "run-1", diff --git a/lib/components/fabro-store/src/slate/run_store.rs b/lib/components/fabro-store/src/slate/run_store.rs index ced57d33d..81450b44a 100644 --- a/lib/components/fabro-store/src/slate/run_store.rs +++ b/lib/components/fabro-store/src/slate/run_store.rs @@ -4,18 +4,18 @@ use std::sync::{Arc, OnceLock}; use bytes::Bytes; use chrono::Utc; -use fabro_types::{RunBlobId, RunEvent, RunId, SessionId}; +use fabro_types::{BlobHash, RunEvent, RunId, SessionId}; use futures::Stream; use slatedb::{Db, DbIterator, DbRead}; use tokio::sync::{Mutex, broadcast, mpsc}; use tokio_stream::wrappers::UnboundedReceiverStream; use tracing::warn; -use super::blob_store::BlobStore; use super::projection_cache::{CachedRunProjection, RunProjectionCache}; use crate::run_state::{EventProjectionCache, RunProjectionReducer}; use crate::{ - Error, EventEnvelope, EventPayload, Result, RunProjection, RunSummaryStore, StageId, keys, + BlobStore, Error, EventEnvelope, EventPayload, Result, RunProjection, RunSummaryStore, StageId, + keys, }; const DEFAULT_EVENT_TAIL_LIMIT: usize = 1024; @@ -37,7 +37,7 @@ impl std::fmt::Debug for RunDatabase { pub(crate) struct RunDatabaseInner { run_id: RunId, db: Db, - blob_store: BlobStore, + blob_store: Arc, // `None` for reader-built inners: readers never append, so they carry no // next-write sequence and any append through them fails as read-only. event_seq: Option, @@ -54,35 +54,11 @@ pub(crate) struct RunDatabaseInner { } impl RunDatabase { - pub(crate) async fn open_writer( - run_id: RunId, - db: Db, - shared_projection_cache: Arc, - run_summary_store: Arc>>, - ) -> Result { - Self::build( - run_id, - db, - false, - shared_projection_cache, - run_summary_store, - ) - .await - } - - pub(crate) async fn open_reader( - run_id: RunId, - db: Db, - shared_projection_cache: Arc, - run_summary_store: Arc>>, - ) -> Result { - Self::build(run_id, db, true, shared_projection_cache, run_summary_store).await - } - - async fn build( + pub(crate) async fn build( run_id: RunId, db: Db, read_only: bool, + blob_store: Arc, shared_projection_cache: Arc, run_summary_store: Arc>>, ) -> Result { @@ -106,7 +82,6 @@ impl RunDatabase { Some(AtomicU32::new(next_seq)) }; let (event_tx, _) = broadcast::channel(DEFAULT_EVENT_TAIL_LIMIT.max(16)); - let blob_store = BlobStore::new(Arc::new(db.clone())); Ok(Self { inner: Arc::new(RunDatabaseInner { run_id, @@ -579,19 +554,15 @@ impl RunDatabase { Ok(Box::pin(UnboundedReceiverStream::new(receiver))) } - pub async fn write_blob(&self, data: &[u8]) -> Result { + pub async fn write_blob(&self, data: &[u8]) -> Result { if self.read_only { return Err(Error::ReadOnly); } self.inner.blob_store.write(data).await } - pub async fn read_blob(&self, id: &RunBlobId) -> Result> { - self.inner.blob_store.read(id).await - } - - pub async fn list_blobs(&self) -> Result> { - list_blobs(&self.inner.db).await + pub async fn read_blob(&self, blob_hash: &BlobHash) -> Result> { + self.inner.blob_store.read(blob_hash).await } pub async fn state(&self) -> Result { @@ -904,23 +875,6 @@ where Ok(events) } -async fn list_blobs(db: &R) -> Result> -where - R: DbRead + Sync, -{ - let mut iter = db.scan_prefix(keys::blobs_prefix()).await?; - let mut blob_ids = Vec::new(); - while let Some(entry) = iter.next().await? { - let key = key_to_str(&entry.key)?; - let Some(blob_id) = keys::parse_blob_id(key) else { - continue; - }; - blob_ids.push(blob_id); - } - blob_ids.sort(); - Ok(blob_ids) -} - fn key_to_str(key: &Bytes) -> Result<&str> { std::str::from_utf8(key) .map_err(|err| Error::Other(format!("stored key is not valid UTF-8: {err}"))) @@ -938,23 +892,6 @@ mod tests { use crate::{Database, Error, EventPayload, keys}; - #[tokio::test] - async fn list_blobs_reads_global_cas_namespace() { - let object_store = Arc::new(InMemory::new()); - let store = Database::new(object_store, "", Duration::from_millis(1), None); - let run_id = "01JT56VE4Z5NZ814GZN2JZD65A".parse().unwrap(); - let run = store.create_run(&run_id).await.unwrap(); - let first_blob = br#"{"a":1}"#; - let second_blob = br#"{"b":2}"#; - - let first_id = run.write_blob(first_blob).await.unwrap(); - let second_id = run.write_blob(second_blob).await.unwrap(); - let mut blob_ids = run.list_blobs().await.unwrap(); - blob_ids.sort(); - - assert_eq!(blob_ids, vec![first_id, second_id]); - } - fn stage_prompt_payload(run_id: &RunId, idx: u32, node_id: Option<&str>) -> EventPayload { stage_prompt_payload_for_stage(run_id, idx, node_id, None) } diff --git a/lib/components/fabro-store/tests/serializable_projection.rs b/lib/components/fabro-store/tests/serializable_projection.rs index ef0ed067b..d6fdcc682 100644 --- a/lib/components/fabro-store/tests/serializable_projection.rs +++ b/lib/components/fabro-store/tests/serializable_projection.rs @@ -8,30 +8,23 @@ use fabro_types::{ BilledModelUsage, BilledTokenCounts, Checkpoint, CheckpointRecord, InterviewQuestionRecord, ParallelBranchResult, QuestionType, RunDiff, RunSandbox, RunSandboxInstance, RunSandboxPlan, RunSandboxRuntime, RunStatus, SandboxProviderKind, StageCompletion, StageModelUsage, - StageOutcome, StartRecord, WorkflowSettings, first_event_seq, fixtures, test_support, + StageOutcome, StartRecord, first_event_seq, fixtures, test_support, }; use serde_json::json; fn sample_run_spec() -> RunSpec { RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: Graph::new("ship"), - graph_source: None, - workflow_slug: Some("demo".to_string()), - automation: None, + graph: Graph::new("ship"), + workflow_slug: Some("demo".to_string()), source_directory: Some("/tmp/project".to_string()), - labels: HashMap::from([("team".to_string(), "platform".to_string())]), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: Some(fabro_types::GitContext { + labels: HashMap::from([("team".to_string(), "platform".to_string())]), + git: Some(fabro_types::GitContext { origin_url: "https://github.com/fabro-sh/fabro.git".to_string(), branch: "main".to_string(), sha: None, dirty: fabro_types::DirtyStatus::Clean, }), - fork_source_ref: None, + ..test_support::test_run_spec() } } diff --git a/lib/components/fabro-workflow-version/Cargo.toml b/lib/components/fabro-workflow-version/Cargo.toml new file mode 100644 index 000000000..bc91e3f89 --- /dev/null +++ b/lib/components/fabro-workflow-version/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "fabro-workflow-version" +edition.workspace = true +version.workspace = true +publish = false +license.workspace = true +description = "Semantic validation and storage for immutable workflow versions" + +[lib] +doctest = false + +[lints] +workspace = true + +[dependencies] +fabro-config = { path = "../../foundation/fabro-config" } +fabro-graphviz = { path = "../fabro-graphviz" } +fabro-store = { path = "../fabro-store" } +fabro-template = { path = "../../foundation/fabro-template" } +fabro-types = { path = "../../foundation/fabro-types" } +serde.workspace = true +serde_json.workspace = true +thiserror.workspace = true + +[dev-dependencies] +object_store.workspace = true +tokio = { workspace = true, features = ["full"] } diff --git a/lib/components/fabro-workflow-version/src/lib.rs b/lib/components/fabro-workflow-version/src/lib.rs new file mode 100644 index 000000000..75731fb49 --- /dev/null +++ b/lib/components/fabro-workflow-version/src/lib.rs @@ -0,0 +1,857 @@ +//! Semantic validation for immutable workflow versions. +//! +//! The wire type ([`fabro_types::WorkflowVersion`]) enforces structural +//! invariants at construction. This crate owns the expensive semantic +//! validation — graph closure, config, and template checks — behind the +//! [`ValidatedWorkflowVersion`] newtype, and the content-addressed +//! [`WorkflowVersionStore`] that only accepts and returns validated versions. + +use std::collections::{BTreeSet, HashMap, VecDeque}; + +use fabro_config::parse::{SettingsSource, validate_settings_source}; +use fabro_config::{ + EnvironmentDockerfileLayer, EnvironmentImageLayer, RunGoalLayer, SettingsLayer, +}; +use fabro_graphviz::parser; +use fabro_template::{ + BundleTemplateStore, GraphReference, GraphReferenceError, StaticReferenceError, + TemplateDiscoveryError, TemplateSource, discover_static_dependency_closure, + validate_static_reference, visit_graph_references, +}; +use fabro_types::graph::ReferenceKind; +use fabro_types::settings::InterpString; +use fabro_types::{ManifestPath, WorkflowPath, WorkflowPathParseError, WorkflowVersion}; +use thiserror::Error; + +mod store; + +pub use store::{LoadedWorkflowVersionClosure, WorkflowVersionStore, WorkflowVersionStoreError}; + +#[derive(Debug, Error)] +pub enum WorkflowVersionError { + #[error("workflow graph `{path}` is invalid")] + GraphParse { + path: WorkflowPath, + #[source] + source: fabro_graphviz::Error, + }, + #[error("invalid {kind} in `{path}`: `{reference}`")] + InvalidReference { + path: WorkflowPath, + kind: ReferenceKind, + reference: String, + #[source] + source: WorkflowPathParseError, + }, + #[error("invalid static reference in `{path}`")] + StaticReference { + path: WorkflowPath, + #[source] + source: StaticReferenceError, + }, + #[error("{kind} in `{path}` references missing file `{target}`")] + MissingFile { + path: WorkflowPath, + kind: ReferenceKind, + target: WorkflowPath, + }, + #[error("template dependencies for `{path}` are invalid")] + Template { + path: WorkflowPath, + #[source] + source: Box, + }, + #[error("workflow.toml is invalid")] + Config { + #[source] + source: fabro_config::ParseError, + }, + #[error( + "workflow.toml selects graph `{configured}`, but the version entrypoint is `{entrypoint}`" + )] + ConfigEntrypointMismatch { + configured: WorkflowPath, + entrypoint: WorkflowPath, + }, + #[error("workflow dependencies do not match child workflow references")] + DependencyMismatch { + missing: Vec, + unused: Vec, + }, +} + +/// A workflow version whose graph, config, and template content passed +/// semantic validation. +/// +/// This is the only door: functions that require a semantically valid +/// version take this type, and the only way to obtain one is [`Self::new`] +/// (or loading through [`WorkflowVersionStore`], which validates on read). +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ValidatedWorkflowVersion(WorkflowVersion); + +impl ValidatedWorkflowVersion { + pub fn new(version: WorkflowVersion) -> Result { + let mut template_roots = TemplateRoots::new(); + validate_config(&version, &mut template_roots)?; + validate_graph_closure(&version, &mut template_roots)?; + validate_template_closure(&version, template_roots.sources)?; + Ok(Self(version)) + } + + #[must_use] + pub fn version(&self) -> &WorkflowVersion { + &self.0 + } + + #[must_use] + pub fn into_version(self) -> WorkflowVersion { + self.0 + } +} + +/// Template sources that anchor static dependency discovery, all rooted at +/// the workflow package root. +struct TemplateRoots { + package_root: ManifestPath, + sources: Vec, +} + +impl TemplateRoots { + fn new() -> Self { + Self { + package_root: ManifestPath::from_wire(".") + .expect("the template package root must be a valid manifest path"), + sources: Vec::new(), + } + } + + fn push(&mut self, path: &WorkflowPath, content: impl Into) { + self.sources.push(TemplateSource::new( + manifest_path(path), + self.package_root.clone(), + content, + )); + } +} + +fn validate_config( + version: &WorkflowVersion, + template_roots: &mut TemplateRoots, +) -> Result<(), WorkflowVersionError> { + let config_path = + WorkflowPath::new("workflow.toml").expect("the static workflow config path must be valid"); + let Some(source) = version.files().get(&config_path) else { + return Ok(()); + }; + let layer = source + .parse::() + .map_err(|source| WorkflowVersionError::Config { source })?; + validate_settings_source(&layer, SettingsSource::Workflow) + .map_err(|source| WorkflowVersionError::Config { source })?; + + if let Some(configured) = layer + .workflow + .as_ref() + .and_then(|workflow| workflow.graph.as_deref()) + { + let configured = resolve_reference(&config_path, ReferenceKind::FileInline, configured)?; + if configured != *version.entrypoint() { + return Err(WorkflowVersionError::ConfigEntrypointMismatch { + configured, + entrypoint: version.entrypoint().clone(), + }); + } + } + + for image in layer.environment_images() { + validate_dockerfile(version, &config_path, image)?; + } + + // The run engine inlines the effective goal (file contents included) into + // the entrypoint graph and renders it under the entrypoint's template + // source, so goal includes anchor at the entrypoint for both goal forms. + match layer.run.as_ref().and_then(|run| run.goal.as_ref()) { + Some(RunGoalLayer::Inline(goal)) => { + template_roots.push(version.entrypoint(), unresolved_source(goal)); + } + Some(RunGoalLayer::File { file }) => { + let (_, content) = validate_config_file_reference( + version, + &config_path, + ReferenceKind::RunGoalFile, + &unresolved_source(file), + )?; + template_roots.push(version.entrypoint(), content); + } + None => {} + } + Ok(()) +} + +#[expect( + clippy::disallowed_methods, + reason = "workflow-version validation preserves authored template source for dependency discovery" +)] +fn unresolved_source(value: &InterpString) -> String { + value.as_source() +} + +fn validate_dockerfile( + version: &WorkflowVersion, + config_path: &WorkflowPath, + image: &EnvironmentImageLayer, +) -> Result<(), WorkflowVersionError> { + let Some(EnvironmentDockerfileLayer::Path { path }) = image.dockerfile.as_ref() else { + return Ok(()); + }; + validate_config_file_reference(version, config_path, ReferenceKind::Dockerfile, path) + .map(|_| ()) +} + +/// Validate a static file reference in `workflow.toml` and require its target +/// to exist in the version, returning the target path and its content. +fn validate_config_file_reference<'version>( + version: &'version WorkflowVersion, + config_path: &WorkflowPath, + kind: ReferenceKind, + reference: &str, +) -> Result<(WorkflowPath, &'version str), WorkflowVersionError> { + validate_static_reference(reference, kind).map_err(|source| { + WorkflowVersionError::StaticReference { + path: config_path.clone(), + source, + } + })?; + let target = resolve_reference(config_path, kind, reference)?; + let content = require_file(version, config_path, kind, target.clone())?; + Ok((target, content)) +} + +fn validate_graph_closure( + version: &WorkflowVersion, + template_roots: &mut TemplateRoots, +) -> Result<(), WorkflowVersionError> { + let mut queue = VecDeque::from([version.entrypoint().clone()]); + let mut visited = BTreeSet::new(); + let mut child_workflows = BTreeSet::new(); + + while let Some(path) = queue.pop_front() { + if !visited.insert(path.clone()) { + continue; + } + let source = + version + .files() + .get(&path) + .ok_or_else(|| WorkflowVersionError::MissingFile { + path: path.clone(), + kind: ReferenceKind::Import, + target: path.clone(), + })?; + let graph = parser::parse(source).map_err(|source| WorkflowVersionError::GraphParse { + path: path.clone(), + source, + })?; + + visit_graph_references(&graph, |reference| match reference { + GraphReference::GoalFile { reference } => { + let target = resolve_reference(&path, ReferenceKind::GraphGoalFile, reference)?; + let content = + require_file(version, &path, ReferenceKind::GraphGoalFile, target.clone())?; + template_roots.push(&target, content); + Ok(()) + } + GraphReference::GoalInline { content } | GraphReference::InlinePrompt { content } => { + template_roots.push(&path, content); + Ok(()) + } + GraphReference::Import { reference } => { + let target = resolve_reference(&path, ReferenceKind::Import, reference)?; + require_file(version, &path, ReferenceKind::Import, target.clone())?; + queue.push_back(target); + Ok(()) + } + GraphReference::ChildWorkflow { reference } => { + let target = resolve_reference(&path, ReferenceKind::ChildWorkflow, reference)?; + child_workflows.insert(target); + Ok(()) + } + GraphReference::FileInline { key, reference } => { + let target = resolve_reference(&path, ReferenceKind::FileInline, reference)?; + let content = + require_file(version, &path, ReferenceKind::FileInline, target.clone())?; + if key == "prompt" { + template_roots.push(&target, content); + } + Ok(()) + } + }) + .map_err(|error| match error { + GraphReferenceError::StaticReference(source) => WorkflowVersionError::StaticReference { + path: path.clone(), + source, + }, + GraphReferenceError::Visit(error) => error, + })?; + } + + let configured = version + .workflow_dependencies() + .keys() + .cloned() + .collect::>(); + if child_workflows != configured { + return Err(WorkflowVersionError::DependencyMismatch { + missing: child_workflows.difference(&configured).cloned().collect(), + unused: configured.difference(&child_workflows).cloned().collect(), + }); + } + Ok(()) +} + +fn validate_template_closure( + version: &WorkflowVersion, + roots: Vec, +) -> Result<(), WorkflowVersionError> { + discover_static_dependency_closure(roots, &template_store(version)).map_err(|source| { + WorkflowVersionError::Template { + path: template_discovery_path(&source), + source: Box::new(source), + } + })?; + Ok(()) +} + +fn template_discovery_path(error: &TemplateDiscoveryError) -> WorkflowPath { + WorkflowPath::new(error.source_path().to_string()) + .expect("template paths sourced from a workflow version must be valid") +} + +fn template_store(version: &WorkflowVersion) -> BundleTemplateStore { + BundleTemplateStore::new( + version + .files() + .iter() + .map(|(path, content)| (manifest_path(path), content.clone())) + .collect::>(), + ) +} + +fn resolve_reference( + path: &WorkflowPath, + kind: ReferenceKind, + reference: &str, +) -> Result { + path.resolve_reference(reference) + .map_err(|source| WorkflowVersionError::InvalidReference { + path: path.clone(), + kind, + reference: reference.to_owned(), + source, + }) +} + +fn require_file<'version>( + version: &'version WorkflowVersion, + path: &WorkflowPath, + kind: ReferenceKind, + target: WorkflowPath, +) -> Result<&'version str, WorkflowVersionError> { + version + .files() + .get(&target) + .map(String::as_str) + .ok_or_else(|| WorkflowVersionError::MissingFile { + path: path.clone(), + kind, + target, + }) +} + +fn manifest_path(path: &WorkflowPath) -> ManifestPath { + ManifestPath::from_wire(path.as_str()) + .expect("validated workflow paths must also be valid manifest paths") +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + + use fabro_template::{TemplateDiscoveryError, TemplateLoadError}; + use fabro_types::graph::ReferenceKind; + use fabro_types::{BlobHash, WorkflowPath, WorkflowVersion, WorkflowVersionId}; + + use super::{ValidatedWorkflowVersion, WorkflowVersionError}; + + fn path(value: &str) -> WorkflowPath { + value.parse().unwrap() + } + + fn dependency_id(value: &[u8]) -> WorkflowVersionId { + BlobHash::new(value).into() + } + + fn version_with( + files: impl IntoIterator, + dependencies: impl IntoIterator, + ) -> Result { + ValidatedWorkflowVersion::new( + WorkflowVersion::new( + path("workflow.fabro"), + files + .into_iter() + .map(|(path_value, content)| (path(path_value), content.to_owned())) + .collect(), + dependencies + .into_iter() + .map(|(path_value, id)| (path(path_value), id)) + .collect(), + ) + .expect("test fixtures must be structurally valid"), + ) + } + + fn version_with_config( + config: impl Into, + extra_files: impl IntoIterator, + ) -> Result { + let mut files = extra_files + .into_iter() + .map(|(path_value, content)| (path(path_value), content.to_owned())) + .collect::>(); + files.insert(path("workflow.fabro"), "digraph W {}".to_owned()); + files.insert(path("workflow.toml"), config.into()); + ValidatedWorkflowVersion::new( + WorkflowVersion::new(path("workflow.fabro"), files, BTreeMap::default()) + .expect("test fixtures must be structurally valid"), + ) + } + + fn version_with_goal_file( + reference: &str, + ) -> Result { + let reference = serde_json::to_string(reference).unwrap(); + let config = format!("_version = 1\n[run.goal]\nfile = {reference}\n"); + version_with_config(config, []) + } + + fn version_with_inline_goal( + goal: &str, + extra_files: impl IntoIterator, + ) -> Result { + let goal = serde_json::to_string(goal).unwrap(); + version_with_config(format!("_version = 1\n[run]\ngoal = {goal}\n"), extra_files) + } + + #[test] + fn validates_imports_templates_file_refs_and_dependencies() { + let version = version_with( + [ + ( + "workflow.fabro", + r#"digraph W { + graph [goal="@prompts/goal.md"] + start [shape=Mdiamond] + imported [import="graphs/imported.fabro"] + child [stack.child_workflow="children/check.fabro"] + exit [shape=Msquare] + start -> imported -> child -> exit + }"#, + ), + ( + "graphs/imported.fabro", + r#"digraph I { step [prompt="{% include \"../prompts/partial.md\" %}"] }"#, + ), + ("prompts/goal.md", "{% include \"partial.md\" %}"), + ("prompts/partial.md", "Do the work"), + ], + [("children/check.fabro", dependency_id(b"child"))], + ) + .unwrap(); + + assert_eq!(version.version().workflow_dependencies().len(), 1); + } + + #[test] + fn rejects_missing_and_unused_dependencies() { + let error = version_with( + [( + "workflow.fabro", + r#"digraph W { child [stack.child_workflow="child.fabro"] }"#, + )], + [("unused.fabro", dependency_id(b"unused"))], + ) + .unwrap_err(); + + let WorkflowVersionError::DependencyMismatch { missing, unused } = error else { + panic!("expected dependency mismatch"); + }; + assert_eq!(missing, vec![path("child.fabro")]); + assert_eq!(unused, vec![path("unused.fabro")]); + } + + #[test] + fn rejects_config_entrypoint_and_missing_dockerfile() { + let error = version_with( + [ + ( + "workflow.fabro", + "digraph W { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }", + ), + ( + "workflow.toml", + "_version = 1\n[workflow]\ngraph = \"other.fabro\"\n", + ), + ], + [], + ) + .unwrap_err(); + assert!(matches!( + error, + WorkflowVersionError::ConfigEntrypointMismatch { .. } + )); + + let missing_dockerfile = version_with( + [ + ("workflow.fabro", "digraph W {}"), + ( + "workflow.toml", + "_version = 1\n[run.environment.image]\ndockerfile = { path = \"docker/Dockerfile\" }\n", + ), + ], + [], + ) + .unwrap_err(); + assert!(matches!( + missing_dockerfile, + WorkflowVersionError::MissingFile { .. } + )); + + let invalid_config = version_with( + [ + ("workflow.fabro", "digraph W {}"), + ("workflow.toml", "not valid toml = ["), + ], + [], + ) + .unwrap_err(); + assert!(matches!( + invalid_config, + WorkflowVersionError::Config { .. } + )); + } + + #[test] + fn rejects_missing_workflow_goal_file() { + let error = version_with_goal_file("prompts/goal.md").unwrap_err(); + + assert!(matches!( + error, + WorkflowVersionError::MissingFile { + path: source_path, + kind, + target, + } + if source_path == path("workflow.toml") + && kind == ReferenceKind::RunGoalFile + && target == path("prompts/goal.md") + )); + } + + #[test] + fn accepts_inline_workflow_goal_with_static_template_closure() { + let version = version_with_inline_goal( + r#"Review {{ vars.target }} with {{ inputs.mode }} after {{ goal }}. {% include "prompts/shared.md" %}"#, + [("prompts/shared.md", "Use {{ vars.detail }}")], + ) + .unwrap(); + + assert_eq!(version.version().files().len(), 3); + } + + #[test] + fn accepts_file_workflow_goal_with_transitive_template_closure() { + // The goal file's own includes anchor at the entrypoint's directory + // (the package root here), not at the goal file's directory; loaded + // dependencies then anchor at their own directories as usual. + let version = + version_with_config("_version = 1\n[run.goal]\nfile = \"prompts/goal.md\"\n", [ + ("prompts/goal.md", r#"{% include "prompts/partial.md" %}"#), + ("prompts/partial.md", r#"{% include "nested/detail.md" %}"#), + ("prompts/nested/detail.md", "Use {{ vars.detail }}"), + ]) + .unwrap(); + + assert_eq!(version.version().files().len(), 5); + } + + #[test] + fn rejects_broken_transitive_includes_under_a_workflow_goal_file() { + // Guards the root push for file goals: without it the goal file is + // never parsed and the broken include below is silently accepted. + let error = + version_with_config("_version = 1\n[run.goal]\nfile = \"prompts/goal.md\"\n", [ + ("prompts/goal.md", r#"{% include "prompts/partial.md" %}"#), + ("prompts/partial.md", r#"{% include "missing.md" %}"#), + ]) + .unwrap_err(); + + assert!(matches!( + error, + WorkflowVersionError::Template { path: source_path, source } + if source_path == path("prompts/partial.md") + && matches!( + source.as_ref(), + TemplateDiscoveryError::Missing { reference, .. } if reference == "missing.md" + ) + )); + } + + #[test] + fn anchors_workflow_goal_includes_at_the_entrypoint() { + let version_with_entrypoint = |goal_include_target: &'static str| { + ValidatedWorkflowVersion::new( + WorkflowVersion::new( + path("graphs/main.fabro"), + BTreeMap::from([ + (path("graphs/main.fabro"), "digraph W {}".to_owned()), + ( + path("workflow.toml"), + "_version = 1\n[run]\ngoal = \"{% include \\\"shared.md\\\" %}\"\n" + .to_owned(), + ), + (path(goal_include_target), "shared".to_owned()), + ]), + BTreeMap::default(), + ) + .expect("test fixtures must be structurally valid"), + ) + }; + + // The include resolves beside the entrypoint graph, matching where + // the run engine renders the inlined goal. + version_with_entrypoint("graphs/shared.md").unwrap(); + + let error = version_with_entrypoint("shared.md").unwrap_err(); + assert!(matches!( + error, + WorkflowVersionError::Template { path: source_path, source } + if source_path == path("graphs/main.fabro") + && matches!( + source.as_ref(), + TemplateDiscoveryError::Missing { reference, .. } if reference == "shared.md" + ) + )); + } + + #[test] + fn rejects_non_static_or_nonportable_workflow_goal_file_references() { + for reference in ["{{ vars.NAME }}", "{% include \"goal.md\" %}"] { + let error = version_with_goal_file(reference).unwrap_err(); + let WorkflowVersionError::StaticReference { + path: source_path, + source, + } = error + else { + panic!("expected static-reference error for {reference:?}"); + }; + assert_eq!(source_path, path("workflow.toml")); + assert_eq!(source.kind(), ReferenceKind::RunGoalFile); + } + + for reference in [ + "", + "/absolute.md", + "../outside.md", + "~/goal.md", + "C:/goal.md", + "prompts\\goal.md", + "prompts//goal.md", + "prompts/", + "prompts/goal\n.md", + ] { + let error = version_with_goal_file(reference).unwrap_err(); + assert!( + matches!( + &error, + WorkflowVersionError::InvalidReference { + path: source_path, + kind: ReferenceKind::RunGoalFile, + .. + } if *source_path == path("workflow.toml") + ), + "expected invalid-reference error for {reference:?}, got {error:?}" + ); + } + } + + #[test] + fn rejects_invalid_workflow_goal_template_closure() { + let missing = version_with_inline_goal(r#"{% include "missing.md" %}"#, []).unwrap_err(); + let WorkflowVersionError::Template { + path: source_path, + source, + } = missing + else { + panic!("expected missing template dependency"); + }; + assert_eq!(source_path, path("workflow.fabro")); + assert!(matches!( + source.as_ref(), + TemplateDiscoveryError::Missing { parent, reference } + if parent.to_string() == "workflow.fabro" && reference == "missing.md" + )); + + let dynamic = version_with_inline_goal(r"{% include inputs.partial %}", []).unwrap_err(); + let WorkflowVersionError::Template { source, .. } = dynamic else { + panic!("expected dynamic template dependency"); + }; + assert!(matches!( + source.as_ref(), + TemplateDiscoveryError::Dynamic { parent } + if parent.to_string() == "workflow.fabro" + )); + + let escaping = + version_with_inline_goal(r#"{% include "../outside.md" %}"#, []).unwrap_err(); + let WorkflowVersionError::Template { source, .. } = escaping else { + panic!("expected escaping template dependency"); + }; + assert!(matches!( + source.as_ref(), + TemplateDiscoveryError::Load { + source: TemplateLoadError::EscapesRoot { parent, .. }, + .. + } if parent.to_string() == "workflow.fabro" + )); + } + + #[test] + fn validates_all_inline_graph_roots_that_share_the_graph_path() { + let error = version_with( + [( + "workflow.fabro", + r#"digraph W { + graph [goal="valid"] + step [prompt="{% include inputs.partial %}"] + }"#, + )], + [], + ) + .unwrap_err(); + + assert!(matches!( + error, + WorkflowVersionError::Template { + source, + .. + } if matches!(source.as_ref(), TemplateDiscoveryError::Dynamic { .. }) + )); + } + + #[test] + fn validates_graph_files_included_from_goal_templates() { + // The graph file's inline prompt anchors a template root at the graph + // path; that root must not shadow the raw graph content when a goal + // template includes the graph file itself. + let error = version_with( + [ + ( + "workflow.fabro", + r#"digraph W { + graph [goal="@goal.md"] + step [prompt="hello", note="{% include 'missing.md' %}"] + }"#, + ), + ("goal.md", r#"{% include "workflow.fabro" %}"#), + ], + [], + ) + .unwrap_err(); + + assert!(matches!( + error, + WorkflowVersionError::Template { path: source_path, source } + if source_path == path("workflow.fabro") + && matches!( + source.as_ref(), + TemplateDiscoveryError::Missing { reference, .. } if reference == "missing.md" + ) + )); + } + + #[test] + fn accepts_root_config_and_all_dockerfile_path_sources() { + let version = version_with( + [ + ("workflow.fabro", "digraph W {}"), + ( + "workflow.toml", + r#"_version = 1 +[workflow] +graph = "workflow.fabro" + +[environments.cloud] +provider = "daytona" + +[environments.cloud.image] +dockerfile = { path = "docker/named.Dockerfile" } + +[run.environment.image] +dockerfile = { path = "docker/run.Dockerfile" } +"#, + ), + ("docker/named.Dockerfile", "FROM alpine\n"), + ("docker/run.Dockerfile", "FROM ubuntu\n"), + ], + [], + ) + .unwrap(); + + assert_eq!(version.version().entrypoint(), &path("workflow.fabro")); + } + + #[test] + fn rejects_server_managed_environment_cwd_in_workflow_config() { + let error = version_with( + [ + ("workflow.fabro", "digraph W {}"), + ( + "workflow.toml", + "_version = 1\n[environments.local]\nprovider = \"local\"\ncwd = \"/tmp\"\n", + ), + ], + [], + ) + .unwrap_err(); + + assert!(matches!(error, WorkflowVersionError::Config { .. })); + assert!(error.to_string().contains("workflow.toml is invalid")); + } + + #[test] + fn rejects_escaping_and_dynamic_template_references() { + let escaping = version_with( + [( + "workflow.fabro", + r#"digraph W { imported [import="../outside.fabro"] }"#, + )], + [], + ) + .unwrap_err(); + assert!(matches!( + escaping, + WorkflowVersionError::InvalidReference { .. } + )); + + let dynamic = version_with( + [( + "workflow.fabro", + r#"digraph W { step [prompt="{% include template_name %}"] }"#, + )], + [], + ) + .unwrap_err(); + assert!(matches!(dynamic, WorkflowVersionError::Template { .. })); + } +} diff --git a/lib/components/fabro-workflow-version/src/store.rs b/lib/components/fabro-workflow-version/src/store.rs new file mode 100644 index 000000000..2d468619f --- /dev/null +++ b/lib/components/fabro-workflow-version/src/store.rs @@ -0,0 +1,495 @@ +use std::collections::{BTreeMap, HashSet, VecDeque}; +use std::sync::Arc; + +use fabro_store::BlobStore; +use fabro_types::{WorkflowPath, WorkflowVersion, WorkflowVersionId, WorkflowVersionShapeError}; +use thiserror::Error; + +use crate::{ValidatedWorkflowVersion, WorkflowVersionError}; + +#[derive(Debug, Error)] +pub enum WorkflowVersionStoreError { + #[error(transparent)] + InvalidVersion(#[from] WorkflowVersionError), + #[error(transparent)] + InvalidShape(#[from] WorkflowVersionShapeError), + #[error("workflow-version dependency `{id}` at `{path}` is not stored")] + DependencyNotFound { + path: WorkflowPath, + id: WorkflowVersionId, + }, + #[error("workflow-version dependency `{id}` at `{path}` is invalid")] + DependencyInvalid { + path: WorkflowPath, + id: WorkflowVersionId, + #[source] + source: Box, + }, + #[error("workflow-version blob `{id}` cannot be decoded as a valid workflow version")] + Decode { + id: WorkflowVersionId, + #[source] + source: serde_json::Error, + }, + #[error("workflow-version blob `{id}` is not canonical")] + NonCanonical { id: WorkflowVersionId }, + #[error("workflow-version storage operation failed")] + Storage { + #[source] + source: fabro_store::Error, + }, +} + +/// A fully loaded and validated workflow-version dependency graph: the +/// requested root alongside every unique transitive dependency, keyed by +/// canonical content ID. +/// +/// Deliberately not `Clone`: a closure owns the full file contents of every +/// version in the graph, so copies should be explicit and deliberate. +#[derive(Debug)] +pub struct LoadedWorkflowVersionClosure { + root_id: WorkflowVersionId, + root: ValidatedWorkflowVersion, + dependencies: BTreeMap, +} + +impl LoadedWorkflowVersionClosure { + #[must_use] + pub fn root_id(&self) -> WorkflowVersionId { + self.root_id + } + + #[must_use] + pub fn root(&self) -> &WorkflowVersion { + self.root.version() + } + + #[must_use] + pub fn get(&self, id: &WorkflowVersionId) -> Option<&WorkflowVersion> { + if *id == self.root_id { + return Some(self.root.version()); + } + self.dependencies + .get(id) + .map(ValidatedWorkflowVersion::version) + } + + pub fn versions(&self) -> impl Iterator + '_ { + std::iter::once((self.root_id, self.root.version())).chain( + self.dependencies + .iter() + .map(|(id, version)| (*id, version.version())), + ) + } +} + +/// Content-addressed storage for validated workflow versions. +/// +/// `put` only accepts semantically validated versions; `get` re-validates +/// blobs on read because the blob namespace is shared and storage is not +/// trusted to contain only canonical versions. +#[derive(Clone, Debug)] +pub struct WorkflowVersionStore { + blobs: Arc, +} + +impl WorkflowVersionStore { + #[must_use] + pub fn new(blobs: Arc) -> Self { + Self { blobs } + } + + pub async fn put( + &self, + version: &ValidatedWorkflowVersion, + ) -> Result { + let canonical = version.version().canonical_bytes()?; + self.walk_dependency_closure(version.version().workflow_dependencies(), |_, _| ()) + .await?; + self.blobs + .write(&canonical) + .await + .map(WorkflowVersionId::from) + .map_err(|source| WorkflowVersionStoreError::Storage { source }) + } + + pub async fn get( + &self, + id: &WorkflowVersionId, + ) -> Result, WorkflowVersionStoreError> { + let Some(version) = self.load_one(id).await? else { + return Ok(None); + }; + self.walk_dependency_closure(version.version().workflow_dependencies(), |_, _| ()) + .await?; + Ok(Some(version)) + } + + pub async fn get_closure( + &self, + root_id: &WorkflowVersionId, + ) -> Result, WorkflowVersionStoreError> { + let Some(root) = self.load_one(root_id).await? else { + return Ok(None); + }; + let mut dependencies = BTreeMap::new(); + self.walk_dependency_closure(root.version().workflow_dependencies(), |id, version| { + dependencies.insert(id, version); + }) + .await?; + Ok(Some(LoadedWorkflowVersionClosure { + root_id: *root_id, + root, + dependencies, + })) + } + + async fn load_one( + &self, + id: &WorkflowVersionId, + ) -> Result, WorkflowVersionStoreError> { + let blob_hash = (*id).into(); + let Some(bytes) = self + .blobs + .read(&blob_hash) + .await + .map_err(|source| WorkflowVersionStoreError::Storage { source })? + else { + return Ok(None); + }; + let version = serde_json::from_slice::(&bytes) + .map_err(|source| WorkflowVersionStoreError::Decode { id: *id, source })?; + let validated = ValidatedWorkflowVersion::new(version)?; + let canonical = validated.version().canonical_bytes()?; + if canonical.as_slice() != bytes.as_ref() { + return Err(WorkflowVersionStoreError::NonCanonical { id: *id }); + } + Ok(Some(validated)) + } + + /// Walk the transitive dependency closure, validating every dependency + /// and handing each loaded version to `visit` exactly once. + async fn walk_dependency_closure( + &self, + dependencies: &BTreeMap, + mut visit: impl FnMut(WorkflowVersionId, ValidatedWorkflowVersion), + ) -> Result<(), WorkflowVersionStoreError> { + let mut pending = dependencies + .iter() + .map(|(path, id)| (path.clone(), *id)) + .collect::>(); + let mut visited = HashSet::new(); + + while let Some((path, id)) = pending.pop_front() { + if !visited.insert(id) { + continue; + } + match self.load_one(&id).await { + Ok(Some(dependency)) => { + pending.extend( + dependency + .version() + .workflow_dependencies() + .iter() + .map(|(path, id)| (path.clone(), *id)), + ); + visit(id, dependency); + } + Ok(None) => { + return Err(WorkflowVersionStoreError::DependencyNotFound { path, id }); + } + // Persistence failures are server faults, not evidence that + // the caller supplied an invalid dependency. + Err(source @ WorkflowVersionStoreError::Storage { .. }) => return Err(source), + Err(source) => { + return Err(WorkflowVersionStoreError::DependencyInvalid { + path, + id, + source: Box::new(source), + }); + } + } + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + use std::sync::Arc; + use std::time::Duration; + + use fabro_store::{BlobStore, Database}; + use fabro_types::{WorkflowPath, WorkflowVersion, WorkflowVersionId}; + use object_store::memory::InMemory; + + use super::{WorkflowVersionStore, WorkflowVersionStoreError}; + use crate::ValidatedWorkflowVersion; + + fn path(value: &str) -> WorkflowPath { + value.parse().unwrap() + } + + fn version( + graph: &str, + dependencies: BTreeMap, + ) -> ValidatedWorkflowVersion { + ValidatedWorkflowVersion::new( + WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([(path("workflow.fabro"), graph.to_owned())]), + dependencies, + ) + .unwrap(), + ) + .unwrap() + } + + fn version_id(version: &ValidatedWorkflowVersion) -> WorkflowVersionId { + WorkflowVersionId::from(fabro_types::BlobHash::new( + &version.version().canonical_bytes().unwrap(), + )) + } + + async fn stores() -> (Arc, WorkflowVersionStore) { + let database = Database::new( + Arc::new(InMemory::new()), + "", + Duration::from_millis(1), + None, + ); + let blobs = database.blobs().await.unwrap(); + let versions = WorkflowVersionStore::new(Arc::clone(&blobs)); + (blobs, versions) + } + + #[tokio::test] + async fn put_get_reuses_exact_blob_digest() { + let (blobs, store) = stores().await; + let version = version("digraph W {}", BTreeMap::new()); + let expected_bytes = version.version().canonical_bytes().unwrap(); + let expected_id = version_id(&version); + + let id = store.put(&version).await.unwrap(); + assert_eq!(id, expected_id); + let blob_hash = id.into(); + assert_eq!( + blobs.read(&blob_hash).await.unwrap().unwrap(), + expected_bytes + ); + assert_eq!(store.get(&id).await.unwrap(), Some(version)); + } + + #[tokio::test] + async fn identical_content_is_idempotent() { + let (_, store) = stores().await; + let original = version("digraph W {}", BTreeMap::new()); + + assert_eq!( + store.put(&original).await.unwrap(), + store.put(&original).await.unwrap() + ); + + let changed = version("digraph W { changed [label=\"yes\"] }", BTreeMap::new()); + assert_ne!( + store.put(&original).await.unwrap(), + store.put(&changed).await.unwrap() + ); + } + + #[tokio::test] + async fn dependency_must_be_stored_first() { + let (blobs, store) = stores().await; + let child = version("digraph Child {}", BTreeMap::new()); + let child_id = version_id(&child); + let root = version( + r#"digraph Root { child [stack.child_workflow="child.fabro"] }"#, + BTreeMap::from([(path("child.fabro"), child_id)]), + ); + let root_id = version_id(&root); + + let error = store.put(&root).await.unwrap_err(); + assert!(matches!( + error, + WorkflowVersionStoreError::DependencyNotFound { .. } + )); + assert!(!blobs.exists(&root_id.into()).await.unwrap()); + assert_eq!(store.put(&child).await.unwrap(), child_id); + assert!(store.put(&root).await.is_ok()); + } + + #[tokio::test] + async fn dependency_closure_must_be_complete_before_root_write() { + let (blobs, store) = stores().await; + let missing_grandchild_id = WorkflowVersionId::from(fabro_types::BlobHash::new(b"missing")); + let child = version( + r#"digraph Child { grandchild [stack.child_workflow="grandchild.fabro"] }"#, + BTreeMap::from([(path("grandchild.fabro"), missing_grandchild_id)]), + ); + let child_bytes = child.version().canonical_bytes().unwrap(); + let child_id = WorkflowVersionId::from(blobs.write(&child_bytes).await.unwrap()); + let root = version( + r#"digraph Root { child [stack.child_workflow="child.fabro"] }"#, + BTreeMap::from([(path("child.fabro"), child_id)]), + ); + let root_id = version_id(&root); + + assert!(matches!( + store.put(&root).await.unwrap_err(), + WorkflowVersionStoreError::DependencyNotFound { id, .. } + if id == missing_grandchild_id + )); + assert!(!blobs.exists(&root_id.into()).await.unwrap()); + assert!(matches!( + store.get_closure(&child_id).await.unwrap_err(), + WorkflowVersionStoreError::DependencyNotFound { id, .. } + if id == missing_grandchild_id + )); + } + + #[tokio::test] + async fn get_closure_returns_root_and_transitive_dependencies() { + let (_, store) = stores().await; + let grandchild = version("digraph Grandchild {}", BTreeMap::new()); + let grandchild_id = store.put(&grandchild).await.unwrap(); + let child = version( + r#"digraph Child { grandchild [stack.child_workflow="grandchild.fabro"] }"#, + BTreeMap::from([(path("grandchild.fabro"), grandchild_id)]), + ); + let child_id = store.put(&child).await.unwrap(); + let root = version( + r#"digraph Root { child [stack.child_workflow="child.fabro"] }"#, + BTreeMap::from([(path("child.fabro"), child_id)]), + ); + let root_id = store.put(&root).await.unwrap(); + + let closure = store.get_closure(&root_id).await.unwrap().unwrap(); + + assert_eq!(closure.root_id(), root_id); + assert_eq!(closure.root(), root.version()); + assert_eq!(closure.get(&child_id), Some(child.version())); + assert_eq!(closure.get(&grandchild_id), Some(grandchild.version())); + assert_eq!( + closure + .versions() + .map(|(id, version)| (id, version.clone())) + .collect::>(), + BTreeMap::from([ + (root_id, root.version().clone()), + (child_id, child.version().clone()), + (grandchild_id, grandchild.version().clone()), + ]) + ); + } + + #[tokio::test] + async fn get_closure_deduplicates_a_diamond() { + let (_, store) = stores().await; + let leaf = version("digraph Leaf {}", BTreeMap::new()); + let leaf_id = store.put(&leaf).await.unwrap(); + let left = version( + r#"digraph Left { leaf [stack.child_workflow="leaf.fabro"] }"#, + BTreeMap::from([(path("leaf.fabro"), leaf_id)]), + ); + let left_id = store.put(&left).await.unwrap(); + let right = version( + r#"digraph Right { leaf [stack.child_workflow="leaf.fabro"] }"#, + BTreeMap::from([(path("leaf.fabro"), leaf_id)]), + ); + let right_id = store.put(&right).await.unwrap(); + let root = version( + r#"digraph Root { + left [stack.child_workflow="left.fabro"] + right [stack.child_workflow="right.fabro"] + }"#, + BTreeMap::from([ + (path("left.fabro"), left_id), + (path("right.fabro"), right_id), + ]), + ); + let root_id = store.put(&root).await.unwrap(); + + let closure = store.get_closure(&root_id).await.unwrap().unwrap(); + let ids = closure.versions().map(|(id, _)| id).collect::>(); + + assert_eq!(ids.len(), 4); + assert_eq!(ids.iter().filter(|&&id| id == leaf_id).count(), 1); + } + + #[tokio::test] + async fn get_closure_preserves_noncanonical_dependency_errors() { + let (blobs, store) = stores().await; + let dependency = version("digraph Dependency {}", BTreeMap::new()); + let pretty = serde_json::to_vec_pretty(dependency.version()).unwrap(); + let dependency_id = WorkflowVersionId::from(blobs.write(&pretty).await.unwrap()); + let root = version( + r#"digraph Root { dependency [stack.child_workflow="dependency.fabro"] }"#, + BTreeMap::from([(path("dependency.fabro"), dependency_id)]), + ); + let root_id = WorkflowVersionId::from( + blobs + .write(&root.version().canonical_bytes().unwrap()) + .await + .unwrap(), + ); + + let error = store.get_closure(&root_id).await.unwrap_err(); + let WorkflowVersionStoreError::DependencyInvalid { source, .. } = error else { + panic!("expected invalid dependency error"); + }; + assert!(matches!( + source.as_ref(), + WorkflowVersionStoreError::NonCanonical { id } if *id == dependency_id + )); + assert!(matches!( + store.get_closure(&dependency_id).await.unwrap_err(), + WorkflowVersionStoreError::NonCanonical { id } if id == dependency_id + )); + } + + #[tokio::test] + async fn get_projects_the_same_validated_root_as_get_closure() { + let (_, store) = stores().await; + let child = version("digraph Child {}", BTreeMap::new()); + let child_id = store.put(&child).await.unwrap(); + let root = version( + r#"digraph Root { child [stack.child_workflow="child.fabro"] }"#, + BTreeMap::from([(path("child.fabro"), child_id)]), + ); + let root_id = store.put(&root).await.unwrap(); + + let closure = store.get_closure(&root_id).await.unwrap().unwrap(); + let projected = store.get(&root_id).await.unwrap().unwrap(); + + assert_eq!(projected.version(), closure.root()); + let absent = version_id(&version("digraph Absent {}", BTreeMap::new())); + assert!(store.get_closure(&absent).await.unwrap().is_none()); + assert!(store.get(&absent).await.unwrap().is_none()); + } + + #[tokio::test] + async fn get_rejects_arbitrary_and_noncanonical_blobs() { + let (blobs, store) = stores().await; + let arbitrary = WorkflowVersionId::from(blobs.write(b"not json").await.unwrap()); + assert!(matches!( + store.get(&arbitrary).await.unwrap_err(), + WorkflowVersionStoreError::Decode { .. } + )); + + let invalid_bytes = br#"{"entrypoint":"missing.fabro","files":{"workflow.fabro":"digraph W {}"},"workflow_dependencies":{}}"#; + let invalid = WorkflowVersionId::from(blobs.write(invalid_bytes).await.unwrap()); + assert!(matches!( + store.get(&invalid).await.unwrap_err(), + WorkflowVersionStoreError::Decode { .. } + )); + + let version = version("digraph W {}", BTreeMap::new()); + let pretty = serde_json::to_vec_pretty(version.version()).unwrap(); + let noncanonical = WorkflowVersionId::from(blobs.write(&pretty).await.unwrap()); + assert!(matches!( + store.get(&noncanonical).await.unwrap_err(), + WorkflowVersionStoreError::NonCanonical { .. } + )); + } +} diff --git a/lib/components/fabro-workflow/src/artifact.rs b/lib/components/fabro-workflow/src/artifact.rs index 517f5a435..a457e7395 100644 --- a/lib/components/fabro-workflow/src/artifact.rs +++ b/lib/components/fabro-workflow/src/artifact.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use fabro_agent::Sandbox; use fabro_config::RunScratch; use fabro_types::{ - ParallelBranchResult, RunBlobId, format_blob_ref, parse_blob_ref, parse_managed_blob_file_ref, + BlobHash, ParallelBranchResult, format_blob_ref, parse_blob_ref, parse_managed_blob_file_ref, }; use futures::future::BoxFuture; use serde_json::Value; @@ -26,7 +26,7 @@ const ARTIFACT_POINTER_PREFIX: &str = "file://"; /// /// For each entry in `updates` whose serialized JSON exceeds /// `BLOB_OFFLOAD_THRESHOLD`, the value is persisted as a blob in `run_store` -/// and replaced with a `"blob://sha256/{blob_id}"` reference. +/// and replaced with a `"blob://sha256/{blob_hash}"` reference. /// Small values are left untouched. /// /// `parallel.results` is offloaded at each branch context-update boundary @@ -102,11 +102,11 @@ async fn offload_value(value: &mut Value, run_store: &RunStoreHandle) -> Result< .map_err(|e| Error::engine_with_source("artifact serialize failed", e))?; if bytes.len() > BLOB_OFFLOAD_THRESHOLD { - let blob_id = run_store + let blob_hash = run_store .write_blob(&bytes) .await .map_err(|e| Error::engine_with_anyhow("artifact blob write failed", e))?; - *value = Value::String(format_blob_ref(&blob_id)); + *value = Value::String(format_blob_ref(&blob_hash)); } Ok(()) } @@ -204,8 +204,16 @@ pub async fn resolve_outcomes_for_execution( run_dir: &Path, ) -> Result> { let mut resolved = node_outcomes.clone(); + let mut locality = SandboxLocality::default(); for outcome in resolved.values_mut() { - resolve_execution_values(&mut outcome.context_updates, run_store, env, run_dir).await?; + resolve_execution_values( + &mut outcome.context_updates, + run_store, + env, + run_dir, + &mut locality, + ) + .await?; } Ok(resolved) } @@ -217,7 +225,8 @@ pub async fn resolved_context_snapshot( run_dir: &Path, ) -> Result> { let mut values = context.snapshot(); - resolve_execution_values(&mut values, run_store, env, run_dir).await?; + let mut locality = SandboxLocality::default(); + resolve_execution_values(&mut values, run_store, env, run_dir, &mut locality).await?; Ok(values) } @@ -232,17 +241,17 @@ pub async fn resolve_text_or_blob_ref(value: &Value, run_store: &RunStoreHandle) /// blob reference. /// /// Managed `file://` references are normalized through their content-addressed -/// blob id instead of reading an execution-local path. Ordinary strings and +/// blob hash instead of reading an execution-local path. Ordinary strings and /// ordinary file references remain unchanged for the caller to validate. pub(crate) async fn resolve_json_value(value: Value, run_store: &RunStoreHandle) -> Result { - let blob_id = value.as_str().and_then(|reference| { + let blob_hash = value.as_str().and_then(|reference| { parse_blob_ref(reference).or_else(|| parse_managed_blob_file_ref(reference)) }); - let Some(blob_id) = blob_id else { + let Some(blob_hash) = blob_hash else { return Ok(value); }; - let bytes = read_required_blob(&blob_id, run_store).await?; + let bytes = read_required_blob(&blob_hash, run_store).await?; serde_json::from_slice(&bytes) .map_err(|err| Error::engine_with_source("artifact blob was not valid JSON", err)) } @@ -267,14 +276,14 @@ pub async fn resolve_text_or_blob_ref_str( current: &str, run_store: &RunStoreHandle, ) -> Result { - let Some(blob_id) = parse_blob_ref(current) else { + let Some(blob_hash) = parse_blob_ref(current) else { return Ok(current.to_string()); }; let bytes = run_store - .read_blob(&blob_id) + .read_blob(&blob_hash) .await .map_err(|e| Error::engine_with_anyhow("text blob read failed", e))? - .ok_or_else(|| Error::engine(format!("text blob missing: {blob_id}")))?; + .ok_or_else(|| Error::engine(format!("text blob missing: {blob_hash}")))?; serde_json::from_slice::(&bytes) .map_err(|e| Error::engine_with_source("text blob was not a JSON string", e)) } @@ -334,8 +343,8 @@ pub async fn sync_artifacts_to_env( fn normalize_durable_value(value: &mut Value) { match value { Value::String(current) => { - if let Some(blob_id) = parse_managed_blob_file_ref(current) { - *current = format_blob_ref(&blob_id); + if let Some(blob_hash) = parse_managed_blob_file_ref(current) { + *current = format_blob_ref(&blob_hash); } } Value::Array(items) => { @@ -357,10 +366,12 @@ fn resolve_execution_values<'a>( run_store: &'a RunStoreHandle, env: &'a dyn Sandbox, run_dir: &'a Path, + locality: &'a mut SandboxLocality, ) -> BoxFuture<'a, Result<()>> { Box::pin(async move { for (key, value) in values.iter_mut() { - resolve_execution_value(Some(key.as_str()), value, run_store, env, run_dir).await?; + resolve_execution_value(Some(key.as_str()), value, run_store, env, run_dir, locality) + .await?; } Ok(()) }) @@ -376,14 +387,16 @@ fn resolve_execution_value<'a>( run_store: &'a RunStoreHandle, env: &'a dyn Sandbox, run_dir: &'a Path, + locality: &'a mut SandboxLocality, ) -> BoxFuture<'a, Result<()>> { Box::pin(async move { match value { Value::String(current) => { if key.is_some_and(is_text_context_key) { *current = resolve_text_or_blob_ref_str(current, run_store).await?; - } else if let Some(blob_id) = parse_blob_ref(current) { - *current = materialize_blob_ref(&blob_id, run_store, env, run_dir).await?; + } else if let Some(blob_hash) = parse_blob_ref(current) { + *current = + materialize_blob_ref(&blob_hash, run_store, env, run_dir, locality).await?; } else if current.starts_with(ARTIFACT_POINTER_PREFIX) && parse_managed_blob_file_ref(current).is_none() { @@ -392,7 +405,7 @@ fn resolve_execution_value<'a>( } Value::Array(items) => { for item in items { - resolve_execution_value(key, item, run_store, env, run_dir).await?; + resolve_execution_value(key, item, run_store, env, run_dir, locality).await?; } } Value::Object(map) => { @@ -402,8 +415,15 @@ fn resolve_execution_value<'a>( } else { Some(child_key.as_str()) }; - resolve_execution_value(child_context_key, item, run_store, env, run_dir) - .await?; + resolve_execution_value( + child_context_key, + item, + run_store, + env, + run_dir, + locality, + ) + .await?; } } Value::Null | Value::Bool(_) | Value::Number(_) => {} @@ -413,17 +433,18 @@ fn resolve_execution_value<'a>( } async fn materialize_blob_ref( - blob_id: &RunBlobId, + blob_hash: &BlobHash, run_store: &RunStoreHandle, env: &dyn Sandbox, run_dir: &Path, + locality: &mut SandboxLocality, ) -> Result { // Blobs are content-addressed, so an existing materialized file is always // current — check before paying for the store read. - if is_local_execution(env, run_dir).await? { - let path = local_materialized_blob_path(run_dir, blob_id); + if locality.is_local(env, run_dir).await? { + let path = local_materialized_blob_path(run_dir, blob_hash); if !path.exists() { - let bytes = read_required_blob(blob_id, run_store).await?; + let bytes = read_required_blob(blob_hash, run_store).await?; if let Some(parent) = path.parent() { fs::create_dir_all(parent).await.map_err(|err| { Error::Io(format!( @@ -439,13 +460,13 @@ async fn materialize_blob_ref( return Ok(format!("{ARTIFACT_POINTER_PREFIX}{}", path.display())); } - let remote_path = format!("{}/.fabro/blobs/{blob_id}.json", env.working_directory()); + let remote_path = format!("{}/.fabro/blobs/{blob_hash}.json", env.working_directory()); if !env .file_exists(&remote_path) .await .map_err(|e| Error::engine_with_source("failed to check blob existence", e))? { - let bytes = read_required_blob(blob_id, run_store).await?; + let bytes = read_required_blob(blob_hash, run_store).await?; let content = String::from_utf8(bytes.to_vec()) .map_err(|e| Error::engine_with_source("artifact blob was not valid UTF-8 JSON", e))?; env.write_file(&remote_path, &content).await.map_err(|e| { @@ -457,14 +478,14 @@ async fn materialize_blob_ref( } async fn read_required_blob( - blob_id: &RunBlobId, + blob_hash: &BlobHash, run_store: &RunStoreHandle, ) -> Result { run_store - .read_blob(blob_id) + .read_blob(blob_hash) .await .map_err(|e| Error::engine_with_anyhow("artifact blob read failed", e))? - .ok_or_else(|| Error::engine(format!("artifact blob missing: {blob_id}"))) + .ok_or_else(|| Error::engine(format!("artifact blob missing: {blob_hash}"))) } async fn resolve_explicit_file_ref(value: &str, env: &dyn Sandbox) -> Result { @@ -502,17 +523,33 @@ async fn resolve_explicit_file_ref(value: &str, env: &dyn Sandbox) -> Result Result { - env.file_exists(&run_dir.to_string_lossy()) - .await - .map_err(|e| Error::engine_with_source("failed to inspect sandbox locality", e)) +/// Memoized sandbox locality for one resolution pass. The sandbox and run +/// directory are invariant across a pass, so the (possibly remote) probe is +/// paid at most once instead of once per blob reference. +#[derive(Default)] +struct SandboxLocality { + cached: Option, } -fn local_materialized_blob_path(run_dir: &Path, blob_id: &RunBlobId) -> PathBuf { +impl SandboxLocality { + async fn is_local(&mut self, env: &dyn Sandbox, run_dir: &Path) -> Result { + if let Some(local) = self.cached { + return Ok(local); + } + let local = env + .file_exists(&run_dir.to_string_lossy()) + .await + .map_err(|e| Error::engine_with_source("failed to inspect sandbox locality", e))?; + self.cached = Some(local); + Ok(local) + } +} + +fn local_materialized_blob_path(run_dir: &Path, blob_hash: &BlobHash) -> PathBuf { RunScratch::new(run_dir) .runtime_dir() .join("blobs") - .join(format!("{blob_id}.json")) + .join(format!("{blob_hash}.json")) } #[cfg(test)] @@ -549,7 +586,7 @@ mod tests { let large_string = "x".repeat(BLOB_OFFLOAD_THRESHOLD + 1); let serialized = serde_json::to_vec(&serde_json::json!(large_string.clone())).unwrap(); - let expected_blob_id = fabro_types::RunBlobId::new(&serialized); + let expected_blob_hash = fabro_types::BlobHash::new(&serialized); let mut updates = HashMap::new(); updates.insert("response.plan".to_string(), serde_json::json!(large_string)); @@ -561,11 +598,11 @@ mod tests { let pointer = updates.get("response.plan").unwrap(); assert_eq!( pointer, - &serde_json::json!(fabro_types::format_blob_ref(&expected_blob_id)) + &serde_json::json!(fabro_types::format_blob_ref(&expected_blob_hash)) ); let blob = run_store - .read_blob(&expected_blob_id) + .read_blob(&expected_blob_hash) .await .unwrap() .expect("blob should exist"); @@ -591,21 +628,21 @@ mod tests { async fn resolve_json_value_hydrates_blob_and_managed_file_references() { let run_store = make_run_store("structured-json-resolution").await; let value = serde_json::json!([{"name": "api"}, {"name": "web"}]); - let blob_id = run_store + let blob_hash = run_store .write_blob(&serde_json::to_vec(&value).unwrap()) .await .unwrap(); let handle = run_store.clone().into(); assert_eq!( - resolve_json_value(serde_json::json!(format_blob_ref(&blob_id)), &handle) + resolve_json_value(serde_json::json!(format_blob_ref(&blob_hash)), &handle) .await .unwrap(), value ); assert_eq!( resolve_json_value( - serde_json::json!(format!("file:///sandbox/.fabro/blobs/{blob_id}.json")), + serde_json::json!(format!("file:///sandbox/.fabro/blobs/{blob_hash}.json")), &handle, ) .await @@ -636,7 +673,7 @@ mod tests { Value::String("small".to_string()); BLOB_OFFLOAD_THRESHOLD / 4 ]); - let expected_report_blob = RunBlobId::new(&serde_json::to_vec(&large_report).unwrap()); + let expected_report_blob = BlobHash::new(&serde_json::to_vec(&large_report).unwrap()); let mut typed_results = vec![ParallelBranchResult { id: "branch_a".to_string(), index: Some(0), @@ -787,15 +824,43 @@ mod tests { ); } + #[tokio::test] + async fn resolve_context_probes_sandbox_locality_once_per_pass() { + let run_store = make_run_store("locality-probe-memoization").await; + let first_blob = run_store + .write_blob(&serde_json::to_vec(&serde_json::json!({"a": 1})).unwrap()) + .await + .unwrap(); + let second_blob = run_store + .write_blob(&serde_json::to_vec(&serde_json::json!({"b": 2})).unwrap()) + .await + .unwrap(); + let context = Context::new(); + context.set("first", fabro_types::format_blob_ref(&first_blob).into()); + context.set("second", fabro_types::format_blob_ref(&second_blob).into()); + let env = TestSyncEnv::new(true, "/workspace"); + let run_dir = tempfile::tempdir().unwrap(); + + resolved_context_snapshot(&context, &run_store.clone().into(), &env, run_dir.path()) + .await + .unwrap(); + + assert_eq!( + *env.exists_calls.lock().unwrap(), + 1, + "sandbox locality should be probed once per resolution pass" + ); + } + #[test] fn normalize_durable_updates_rewrites_managed_blob_file_refs_recursively() { - let blob_id = fabro_types::RunBlobId::new(b"hello"); + let blob_hash = fabro_types::BlobHash::new(b"hello"); let mut updates = HashMap::from([( "nested".to_string(), serde_json::json!({ "items": [ - format!("file:///tmp/run/runtime/blobs/{blob_id}.json"), - format!("file:///sandbox/.fabro/blobs/{blob_id}.json"), + format!("file:///tmp/run/runtime/blobs/{blob_hash}.json"), + format!("file:///sandbox/.fabro/blobs/{blob_hash}.json"), "file:///tmp/report.json", ] }), @@ -807,8 +872,8 @@ mod tests { updates["nested"], serde_json::json!({ "items": [ - fabro_types::format_blob_ref(&blob_id), - fabro_types::format_blob_ref(&blob_id), + fabro_types::format_blob_ref(&blob_hash), + fabro_types::format_blob_ref(&blob_hash), "file:///tmp/report.json", ] }) @@ -870,7 +935,7 @@ mod tests { #[test] fn normalize_checkpoint_for_resume_converts_managed_blob_file_refs_and_drops_preamble() { - let blob_id = fabro_types::RunBlobId::new(b"managed"); + let blob_hash = fabro_types::BlobHash::new(b"managed"); let mut checkpoint = crate::records::Checkpoint { timestamp: chrono::Utc::now(), current_node: "work".to_string(), @@ -883,7 +948,7 @@ mod tests { ), ( "response.work".to_string(), - serde_json::json!(format!("file:///sandbox/.fabro/blobs/{blob_id}.json")), + serde_json::json!(format!("file:///sandbox/.fabro/blobs/{blob_hash}.json")), ), ]), node_outcomes: HashMap::from([( @@ -891,7 +956,7 @@ mod tests { crate::outcome::Outcome { context_updates: HashMap::from([( "response.work".to_string(), - serde_json::json!(format!("file:///sandbox/.fabro/blobs/{blob_id}.json")), + serde_json::json!(format!("file:///sandbox/.fabro/blobs/{blob_hash}.json")), )]), ..crate::outcome::Outcome::success() }, @@ -912,14 +977,14 @@ mod tests { ); assert_eq!( checkpoint.context_values.get("response.work"), - Some(&serde_json::json!(fabro_types::format_blob_ref(&blob_id))) + Some(&serde_json::json!(fabro_types::format_blob_ref(&blob_hash))) ); assert_eq!( checkpoint .node_outcomes .get("work") .and_then(|outcome| outcome.context_updates.get("response.work")), - Some(&serde_json::json!(fabro_types::format_blob_ref(&blob_id))) + Some(&serde_json::json!(fabro_types::format_blob_ref(&blob_hash))) ); } @@ -928,9 +993,10 @@ mod tests { use std::sync::Mutex; struct TestSyncEnv { - accessible: bool, - written: Mutex>, - working_dir: String, + accessible: bool, + written: Mutex>, + working_dir: String, + exists_calls: Mutex, } impl TestSyncEnv { @@ -939,6 +1005,7 @@ mod tests { accessible, written: Mutex::new(Vec::new()), working_dir: working_dir.to_string(), + exists_calls: Mutex::new(0), } } } @@ -962,6 +1029,7 @@ mod tests { } async fn file_exists(&self, _path: &str) -> fabro_sandbox::Result { + *self.exists_calls.lock().unwrap() += 1; Ok(self.accessible) } diff --git a/lib/components/fabro-workflow/src/billing_rollup.rs b/lib/components/fabro-workflow/src/billing_rollup.rs index 986b541d4..1b6487f36 100644 --- a/lib/components/fabro-workflow/src/billing_rollup.rs +++ b/lib/components/fabro-workflow/src/billing_rollup.rs @@ -126,12 +126,10 @@ pub fn billing_rollup_from_projection( #[cfg(test)] mod tests { - use std::collections::HashMap; - use fabro_model::{Catalog, ModelRef, ProviderId}; use fabro_types::{ AttrValue, BilledTokenCounts, Graph, Node, RunProjection, RunSpec, StageCompletion, - StageOutcome, WorkflowSettings, first_event_seq, fixtures, test_support, + StageOutcome, first_event_seq, test_support, }; use super::billing_rollup_from_projection; @@ -311,19 +309,8 @@ mod tests { }); RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), graph, - graph_source: None, - workflow_slug: None, - automation: None, - source_directory: None, - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: None, - fork_source_ref: None, + ..test_support::test_run_spec() } } } diff --git a/lib/components/fabro-workflow/src/command_log.rs b/lib/components/fabro-workflow/src/command_log.rs index 67c4373e1..ed998d208 100644 --- a/lib/components/fabro-workflow/src/command_log.rs +++ b/lib/components/fabro-workflow/src/command_log.rs @@ -109,14 +109,14 @@ pub async fn read_json_string_blob( run_store: &RunStoreHandle, blob_ref: &str, ) -> Result> { - let Some(blob_id) = fabro_types::parse_blob_ref(blob_ref) else { + let Some(blob_hash) = fabro_types::parse_blob_ref(blob_ref) else { return Ok(None); }; let bytes = run_store - .read_blob(&blob_id) + .read_blob(&blob_hash) .await .map_err(|err| Error::engine_with_anyhow("command log blob read failed", err))? - .ok_or_else(|| Error::engine(format!("command log blob missing: {blob_id}")))?; + .ok_or_else(|| Error::engine(format!("command log blob missing: {blob_hash}")))?; let text = serde_json::from_slice::(&bytes) .map_err(|err| Error::engine_with_source("command log blob was not a JSON string", err))?; Ok(Some(text)) @@ -155,9 +155,9 @@ async fn write_json_string_blob(run_store: &RunStoreHandle, text: &str) -> Resul let value = Value::String(text.to_string()); let bytes = serde_json::to_vec(&value) .map_err(|err| Error::engine_with_source("command log JSON serialization failed", err))?; - let blob_id = run_store + let blob_hash = run_store .write_blob(&bytes) .await .map_err(|err| Error::engine_with_anyhow("command log blob write failed", err))?; - Ok(format_blob_ref(&blob_id)) + Ok(format_blob_ref(&blob_hash)) } diff --git a/lib/components/fabro-workflow/src/error.rs b/lib/components/fabro-workflow/src/error.rs index f8c08ca15..21833a8df 100644 --- a/lib/components/fabro-workflow/src/error.rs +++ b/lib/components/fabro-workflow/src/error.rs @@ -84,6 +84,8 @@ const TRANSIENT_INFRA_HINTS: &[&str] = &[ "cross-device link", "invalid cross-device link", "os error 18", + "state change in progress", + "sandbox stop still in progress", ]; const BUDGET_EXHAUSTED_HINTS: &[&str] = &[ @@ -807,6 +809,18 @@ mod tests { assert_eq!(err.failure_category(), FailureCategory::TransientInfra); } + #[test] + fn engine_error_with_sandbox_state_change_cause_classifies_transient() { + let source = TestOuterError { + message: "Failed to start Daytona sandbox", + source: TestCause("Sandbox state change in progress"), + }; + let err = Error::engine_with_source("Pipeline lifecycle operation failed", source); + + assert_eq!(err.failure_category(), FailureCategory::TransientInfra); + assert!(err.is_retryable()); + } + #[test] fn handler_error_display() { let err = Error::handler("LLM call failed"); @@ -1281,7 +1295,7 @@ mod tests { #[test] fn transient_infra_hints_count() { - assert_eq!(TRANSIENT_INFRA_HINTS.len(), 38); + assert_eq!(TRANSIENT_INFRA_HINTS.len(), 40); } #[test] @@ -1450,6 +1464,25 @@ mod tests { ); } + #[test] + fn classify_reason_sandbox_state_change_in_progress() { + assert_eq!( + classify_failure_reason( + "Pipeline lifecycle operation failed: failed to activate sandbox after node \ + attempt survey: Failed to start Daytona sandbox: Sandbox state change in progress" + ), + FailureCategory::TransientInfra + ); + } + + #[test] + fn classify_reason_sandbox_stop_still_in_progress() { + assert_eq!( + classify_failure_reason("Daytona sandbox stop still in progress after 120s"), + FailureCategory::TransientInfra + ); + } + #[test] fn classify_reason_500() { assert_eq!( diff --git a/lib/components/fabro-workflow/src/event/events.rs b/lib/components/fabro-workflow/src/event/events.rs index f36d01a16..a38cefbd0 100644 --- a/lib/components/fabro-workflow/src/event/events.rs +++ b/lib/components/fabro-workflow/src/event/events.rs @@ -1,12 +1,12 @@ use std::collections::BTreeMap; use ::fabro_types::{ - AutomationRef, BilledTokenCounts, BlockedReason, CommandTermination, DiffSummary, + AutomationRef, BilledTokenCounts, BlobHash, BlockedReason, CommandTermination, DiffSummary, FailureReason, ForkSourceRef, GitContext, PairId, PairMessageId, PairSystemMessageKind, PairTarget, ParallelBranchId, ParallelBranchResult, PendingReason, PermissionLevel, Principal, - PullRequestCreationId, PullRequestLink, ReviewTarget, RunBlobId, RunFailure, RunId, - RunNoticeLevel, RunPairEndedReason, RunPairFailedReason, RunProvenance, RunRunnableSource, - RunTiming, SandboxProviderKind, StageId, StageOutcome, StageTiming, SuccessReason, + PullRequestCreationId, PullRequestLink, ReviewTarget, RunFailure, RunId, RunNoticeLevel, + RunPairEndedReason, RunPairFailedReason, RunProvenance, RunRunnableSource, RunTiming, + SandboxProviderKind, StageId, StageOutcome, StageTiming, SuccessReason, run_event as fabro_types, }; use fabro_agent::{AgentEvent, SandboxEvent}; @@ -39,7 +39,7 @@ pub enum Event { automation: Option, provenance: RunProvenance, #[serde(default, skip_serializing_if = "Option::is_none")] - manifest_blob: Option, + manifest_blob: Option, #[serde(default, skip_serializing_if = "Option::is_none")] git: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -67,7 +67,7 @@ pub enum Event { }, RunSubmitted { #[serde(default, skip_serializing_if = "Option::is_none")] - definition_blob: Option, + definition_blob: Option, }, RunStartRequested { resume: bool, diff --git a/lib/components/fabro-workflow/src/handler/command.rs b/lib/components/fabro-workflow/src/handler/command.rs index 5dfc41e46..d36ef8be8 100644 --- a/lib/components/fabro-workflow/src/handler/command.rs +++ b/lib/components/fabro-workflow/src/handler/command.rs @@ -354,7 +354,7 @@ mod tests { #[derive(Default)] struct MemoryRunStoreBackend { - blobs: Mutex>, + blobs: Mutex>, } #[async_trait::async_trait] @@ -389,17 +389,20 @@ mod tests { Ok(()) } - async fn write_blob(&self, data: &[u8]) -> anyhow::Result { - let blob_id = fabro_types::RunBlobId::new(data); + async fn write_blob(&self, data: &[u8]) -> anyhow::Result { + let blob_hash = fabro_types::BlobHash::new(data); self.blobs .lock() .await - .insert(blob_id, Bytes::copy_from_slice(data)); - Ok(blob_id) + .insert(blob_hash, Bytes::copy_from_slice(data)); + Ok(blob_hash) } - async fn read_blob(&self, id: &fabro_types::RunBlobId) -> anyhow::Result> { - Ok(self.blobs.lock().await.get(id).cloned()) + async fn read_blob( + &self, + blob_hash: &fabro_types::BlobHash, + ) -> anyhow::Result> { + Ok(self.blobs.lock().await.get(blob_hash).cloned()) } async fn read_run_log(&self) -> anyhow::Result>> { diff --git a/lib/components/fabro-workflow/src/handler/manager_loop.rs b/lib/components/fabro-workflow/src/handler/manager_loop.rs index 5668954c6..8cc82f634 100644 --- a/lib/components/fabro-workflow/src/handler/manager_loop.rs +++ b/lib/components/fabro-workflow/src/handler/manager_loop.rs @@ -6,7 +6,9 @@ use std::time::Duration; use async_trait::async_trait; use fabro_graphviz::graph::{AttrValue, Graph, Node}; use fabro_store::{ArtifactStore, Database}; +use fabro_template::validate_static_reference; use fabro_types::WorkflowSettings; +use fabro_types::graph::ReferenceKind; use object_store::memory::InMemory; use tokio::fs; use tokio::time::{sleep, timeout}; @@ -20,7 +22,6 @@ use crate::operations::{ValidateInput, WorkflowInput, validate_with_catalog}; use crate::outcome::{Outcome, OutcomeExt, StageOutcome}; use crate::pipeline::types::Initialized; use crate::run_options::RunOptions; -use crate::static_reference::{ReferenceKind, validate_static_reference}; use crate::{ManifestPath, pipeline, stage_scope}; /// Orchestrates a child workflow engine, polling for completion or stop diff --git a/lib/components/fabro-workflow/src/handler/parallel.rs b/lib/components/fabro-workflow/src/handler/parallel.rs index 62fc59630..9da654d1d 100644 --- a/lib/components/fabro-workflow/src/handler/parallel.rs +++ b/lib/components/fabro-workflow/src/handler/parallel.rs @@ -1847,7 +1847,7 @@ mod tests { Some(serde_json::json!({"not": "an array"})), Some(serde_json::json!("ordinary string")), Some(serde_json::json!(format_blob_ref( - &fabro_types::RunBlobId::new(b"missing") + &fabro_types::BlobHash::new(b"missing") ))), ] { let (handler, calls) = ScriptedHandler::new(Scripted::Succeed); @@ -1917,7 +1917,7 @@ mod tests { "name": "large-item", "body": "x".repeat(101 * 1024) }]); - let blob_id = run_store + let blob_hash = run_store .write_blob(&serde_json::to_vec(&items).unwrap()) .await .unwrap(); @@ -1933,7 +1933,7 @@ mod tests { ))); let (node, graph) = for_each_graph("items", 1); let context = test_context(); - context.set("items", serde_json::json!(format_blob_ref(&blob_id))); + context.set("items", serde_json::json!(format_blob_ref(&blob_hash))); let outcome = ParallelHandler .execute(&node, &context, &graph, sandbox_dir.path(), &services) diff --git a/lib/components/fabro-workflow/src/lib.rs b/lib/components/fabro-workflow/src/lib.rs index bd7f3e665..c34bec62c 100644 --- a/lib/components/fabro-workflow/src/lib.rs +++ b/lib/components/fabro-workflow/src/lib.rs @@ -332,7 +332,6 @@ pub(crate) mod sandbox_git_runtime; pub mod services; pub(crate) mod stage_execution; mod stage_scope; -pub mod static_reference; pub mod steering_hub; #[cfg(any(test, feature = "test-support"))] pub mod test_support; diff --git a/lib/components/fabro-workflow/src/lifecycle/git.rs b/lib/components/fabro-workflow/src/lifecycle/git.rs index fce72da6e..18f4139bf 100644 --- a/lib/components/fabro-workflow/src/lifecycle/git.rs +++ b/lib/components/fabro-workflow/src/lifecycle/git.rs @@ -613,7 +613,7 @@ mod tests { use fabro_model::Catalog; use fabro_store::{Database, EventEnvelope, RunDatabase, RunProjection}; use fabro_types::run_event::{MetadataSnapshotFailureKind, MetadataSnapshotPhase}; - use fabro_types::{EventBody, RunBlobId, RunEvent, WorkflowSettings, fixtures, test_support}; + use fabro_types::{BlobHash, EventBody, RunEvent, WorkflowSettings, fixtures, test_support}; use object_store::memory::InMemory; use super::*; @@ -1324,11 +1324,11 @@ mod tests { Ok(()) } - async fn write_blob(&self, data: &[u8]) -> Result { - Ok(RunBlobId::new(data)) + async fn write_blob(&self, data: &[u8]) -> Result { + Ok(BlobHash::new(data)) } - async fn read_blob(&self, _id: &RunBlobId) -> Result> { + async fn read_blob(&self, _blob_hash: &BlobHash) -> Result> { Ok(None) } diff --git a/lib/components/fabro-workflow/src/operations/retry.rs b/lib/components/fabro-workflow/src/operations/retry.rs index 27a9df68a..8163efa55 100644 --- a/lib/components/fabro-workflow/src/operations/retry.rs +++ b/lib/components/fabro-workflow/src/operations/retry.rs @@ -117,8 +117,8 @@ mod tests { use fabro_store::{Database, RunProjectionReducer}; use fabro_types::{ - AuthMethod, DirtyStatus, FailureReason, ForkSourceRef, GitContext, Graph, IdpIdentity, - Principal, PullRequestLink, RunBlobId, RunRunnableSource, RunServerProvenance, RunTiming, + AuthMethod, BlobHash, DirtyStatus, FailureReason, ForkSourceRef, GitContext, Graph, + IdpIdentity, Principal, PullRequestLink, RunRunnableSource, RunServerProvenance, RunTiming, WorkflowSettings, fixtures, }; use object_store::memory::InMemory; @@ -164,7 +164,7 @@ mod tests { async fn append_created( store: &fabro_store::RunDatabase, run_id: RunId, - manifest_blob: Option, + manifest_blob: Option, fork_source_ref: Option, ) { let mut settings = WorkflowSettings::default(); @@ -248,7 +248,7 @@ mod tests { async fn seed_retryable_failed_source( store: &Database, source_run_id: RunId, - ) -> (Option, Option, ForkSourceRef) { + ) -> (Option, Option, ForkSourceRef) { let source_store = store.create_run(&source_run_id).await.unwrap(); let manifest_blob = Some( source_store diff --git a/lib/components/fabro-workflow/src/operations/source.rs b/lib/components/fabro-workflow/src/operations/source.rs index 3e275937c..195566b7a 100644 --- a/lib/components/fabro-workflow/src/operations/source.rs +++ b/lib/components/fabro-workflow/src/operations/source.rs @@ -109,8 +109,8 @@ pub(crate) fn resolve_workflow(request: ResolveWorkflowInput) -> anyhow::Result< /// Resolve the `run.goal` override for a direct (non-manifest) workflow /// run. Reads the file from disk if the goal layer is the `file` variant. -/// Relative paths that survived config load (e.g. env-interpolated ones) -/// are anchored at `working_directory`. +/// Relative paths that survived config load are anchored at +/// `working_directory`. fn resolve_goal_override( settings: &WorkflowSettings, working_directory: &Path, diff --git a/lib/components/fabro-workflow/src/operations/start.rs b/lib/components/fabro-workflow/src/operations/start.rs index 12b7455a9..c295ae145 100644 --- a/lib/components/fabro-workflow/src/operations/start.rs +++ b/lib/components/fabro-workflow/src/operations/start.rs @@ -359,8 +359,8 @@ impl RunSession { let git = git_checkpoint_options_from_start(settings, &record.run_id, state.start); let definition_blob = state.spec.definition_blob; let accepted_definition = match definition_blob { - Some(blob_id) => { - Some(load_accepted_run_definition(&services.run_store, blob_id).await?) + Some(blob_hash) => { + Some(load_accepted_run_definition(&services.run_store, blob_hash).await?) } None => None, }; @@ -570,15 +570,15 @@ fn vault_token_lookup(vault: &Vault, name: &str) -> Option { async fn load_accepted_run_definition( run_store: &RunStoreHandle, - blob_id: fabro_types::RunBlobId, + blob_hash: fabro_types::BlobHash, ) -> Result { let bytes = run_store - .read_blob(&blob_id) + .read_blob(&blob_hash) .await .map_err(|err| Error::engine(err.to_string()))? .ok_or_else(|| { Error::engine(format!( - "run definition blob is missing from the run store: {blob_id}" + "run definition blob is missing from the run store: {blob_hash}" )) })?; serde_json::from_slice(&bytes).map_err(|err| Error::Parse(err.to_string())) diff --git a/lib/components/fabro-workflow/src/pipeline/execute/tests.rs b/lib/components/fabro-workflow/src/pipeline/execute/tests.rs index 118767be8..5aadd6018 100644 --- a/lib/components/fabro-workflow/src/pipeline/execute/tests.rs +++ b/lib/components/fabro-workflow/src/pipeline/execute/tests.rs @@ -751,11 +751,11 @@ impl HandlerTrait for BlobCommandOutputHandler { services: &crate::handler::EngineServices, ) -> std::result::Result { let blob = serde_json::to_vec("routed-ok").unwrap(); - let blob_id = services.run.run_store.write_blob(&blob).await.unwrap(); + let blob_hash = services.run.run_store.write_blob(&blob).await.unwrap(); let mut outcome = Outcome::success(); outcome.context_updates.insert( context::keys::COMMAND_OUTPUT.to_string(), - serde_json::json!(format_blob_ref(&blob_id)), + serde_json::json!(format_blob_ref(&blob_hash)), ); Ok(outcome) } diff --git a/lib/components/fabro-workflow/src/pipeline/finalize.rs b/lib/components/fabro-workflow/src/pipeline/finalize.rs index 8c497175d..b1e7847ee 100644 --- a/lib/components/fabro-workflow/src/pipeline/finalize.rs +++ b/lib/components/fabro-workflow/src/pipeline/finalize.rs @@ -684,7 +684,7 @@ mod tests { use fabro_store::{Database, EventEnvelope, RunDatabase, RunProjection}; use fabro_types::run_event::{MetadataSnapshotFailureKind, MetadataSnapshotPhase}; use fabro_types::{ - BilledTokenCounts, EventBody, RunBlobId, RunEvent, RunId, RunSpec, StageCompletion, + BilledTokenCounts, BlobHash, EventBody, RunEvent, RunId, RunSpec, StageCompletion, WorkflowSettings, first_event_seq, fixtures, test_support, }; use object_store::memory::InMemory; @@ -1819,11 +1819,11 @@ mod tests { Ok(()) } - async fn write_blob(&self, data: &[u8]) -> Result { - Ok(RunBlobId::new(data)) + async fn write_blob(&self, data: &[u8]) -> Result { + Ok(BlobHash::new(data)) } - async fn read_blob(&self, _id: &RunBlobId) -> Result> { + async fn read_blob(&self, _blob_hash: &BlobHash) -> Result> { Ok(None) } diff --git a/lib/components/fabro-workflow/src/run_lookup.rs b/lib/components/fabro-workflow/src/run_lookup.rs index 99e9825fe..1edd36290 100644 --- a/lib/components/fabro-workflow/src/run_lookup.rs +++ b/lib/components/fabro-workflow/src/run_lookup.rs @@ -445,13 +445,11 @@ fn run_id_matches(run_id: RunId, prefix: &str) -> bool { #[cfg(test)] mod tests { - use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; - use fabro_graphviz::graph::Graph; use fabro_store::Database; - use fabro_types::{RunStatus, WorkflowSettings, fixtures, test_support}; + use fabro_types::{RunStatus, fixtures, test_support}; use object_store::memory::InMemory; use super::scan_runs_combined; @@ -470,24 +468,15 @@ mod tests { fn sample_run_spec() -> RunSpec { RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: Graph::new("test"), - graph_source: None, - workflow_slug: Some("test".to_string()), - automation: None, + workflow_slug: Some("test".to_string()), source_directory: Some("/tmp/project".to_string()), - git: Some(fabro_types::GitContext { + git: Some(fabro_types::GitContext { origin_url: String::new(), branch: "main".to_string(), sha: None, dirty: fabro_types::DirtyStatus::Clean, }), - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - fork_source_ref: None, + ..test_support::test_run_spec() } } diff --git a/lib/components/fabro-workflow/src/run_options.rs b/lib/components/fabro-workflow/src/run_options.rs index 46fffe790..7c4ca98d6 100644 --- a/lib/components/fabro-workflow/src/run_options.rs +++ b/lib/components/fabro-workflow/src/run_options.rs @@ -78,8 +78,8 @@ pub struct LifecycleOptions { } /// A single setup (prepare) command and the per-step environment it runs with. -/// Both the command string and the env values are already fully resolved (their -/// `{{ env.* }}` tokens replaced at the run boundary) by the time they reach +/// Both the command string and the env values are already fully resolved +/// (interpolation tokens replaced at the run boundary) by the time they reach /// the sandbox. pub struct SetupCommand { pub command: String, diff --git a/lib/components/fabro-workflow/src/runtime_store.rs b/lib/components/fabro-workflow/src/runtime_store.rs index c376c47e7..63d55ca64 100644 --- a/lib/components/fabro-workflow/src/runtime_store.rs +++ b/lib/components/fabro-workflow/src/runtime_store.rs @@ -4,7 +4,7 @@ use anyhow::Result; use async_trait::async_trait; use bytes::Bytes; use fabro_store::{EventEnvelope, RunDatabase, RunProjection}; -use fabro_types::{RunBlobId, RunEvent}; +use fabro_types::{BlobHash, RunEvent}; use crate::event::build_redacted_event_payload; @@ -13,8 +13,8 @@ pub trait RunStoreBackend: Send + Sync { async fn load_state(&self) -> Result; async fn list_events(&self) -> Result>; async fn append_run_event(&self, event: &RunEvent) -> Result<()>; - async fn write_blob(&self, data: &[u8]) -> Result; - async fn read_blob(&self, id: &RunBlobId) -> Result>; + async fn write_blob(&self, data: &[u8]) -> Result; + async fn read_blob(&self, blob_hash: &BlobHash) -> Result>; async fn read_run_log(&self) -> Result>>; } @@ -46,12 +46,12 @@ impl RunStoreHandle { self.backend.append_run_event(event).await } - pub async fn write_blob(&self, data: &[u8]) -> Result { + pub async fn write_blob(&self, data: &[u8]) -> Result { self.backend.write_blob(data).await } - pub async fn read_blob(&self, id: &RunBlobId) -> Result> { - self.backend.read_blob(id).await + pub async fn read_blob(&self, blob_hash: &BlobHash) -> Result> { + self.backend.read_blob(blob_hash).await } pub async fn read_run_log(&self) -> Result>> { @@ -91,16 +91,16 @@ impl RunStoreBackend for LocalRunStoreBackend { .map_err(anyhow::Error::from) } - async fn write_blob(&self, data: &[u8]) -> Result { + async fn write_blob(&self, data: &[u8]) -> Result { self.run_store .write_blob(data) .await .map_err(anyhow::Error::from) } - async fn read_blob(&self, id: &RunBlobId) -> Result> { + async fn read_blob(&self, blob_hash: &BlobHash) -> Result> { self.run_store - .read_blob(id) + .read_blob(blob_hash) .await .map_err(anyhow::Error::from) } @@ -112,15 +112,13 @@ impl RunStoreBackend for LocalRunStoreBackend { #[cfg(test)] mod tests { - use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; use chrono::Utc; - use fabro_graphviz::graph::Graph; use fabro_store::Database; use fabro_types::run_event::RunSubmittedProps; - use fabro_types::{EventBody, RunEvent, WorkflowSettings, fixtures, test_support}; + use fabro_types::{EventBody, RunEvent, fixtures, test_support}; use object_store::memory::InMemory; use super::RunStoreHandle; @@ -139,19 +137,9 @@ mod tests { fn test_run_spec() -> RunSpec { RunSpec { - run_id: fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: Graph::new("test"), - graph_source: None, - workflow_slug: Some("test".to_string()), - automation: None, + workflow_slug: Some("test".to_string()), source_directory: Some("/tmp/test".to_string()), - git: None, - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - fork_source_ref: None, + ..test_support::test_run_spec() } } @@ -217,8 +205,8 @@ mod tests { }; handle.append_run_event(&event).await.unwrap(); - let blob_id = handle.write_blob(br#"{"ok":true}"#).await.unwrap(); - let blob = handle.read_blob(&blob_id).await.unwrap().unwrap(); + let blob_hash = handle.write_blob(br#"{"ok":true}"#).await.unwrap(); + let blob = handle.read_blob(&blob_hash).await.unwrap().unwrap(); let events = handle.list_events().await.unwrap(); assert_eq!(events.len(), 2); diff --git a/lib/components/fabro-workflow/src/static_reference.rs b/lib/components/fabro-workflow/src/static_reference.rs deleted file mode 100644 index af83539eb..000000000 --- a/lib/components/fabro-workflow/src/static_reference.rs +++ /dev/null @@ -1,143 +0,0 @@ -use std::fmt; - -use fabro_template::contains_template_syntax; -use thiserror::Error; - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum ReferenceKind { - FileInline, - Import, - ChildWorkflow, - Dockerfile, - GraphGoalFile, -} - -impl fmt::Display for ReferenceKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let label = match self { - Self::FileInline => "file inline reference", - Self::Import => "import reference", - Self::ChildWorkflow => "child workflow reference", - Self::Dockerfile => "Dockerfile reference", - Self::GraphGoalFile => "graph goal file reference", - }; - f.write_str(label) - } -} - -impl ReferenceKind { - pub fn validate(self, value: &str) -> Result<(), StaticReferenceError> { - validate_static_reference(value, self) - } -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum AttributeScope { - Graph, - Node, - Edge, -} - -#[derive(Debug, Error)] -#[error("templates are not supported in {kind}s: {value}")] -pub struct StaticReferenceError { - kind: ReferenceKind, - value: String, -} - -impl StaticReferenceError { - #[must_use] - pub fn new(kind: ReferenceKind, value: impl Into) -> Self { - Self { - kind, - value: value.into(), - } - } - - #[must_use] - pub fn kind(&self) -> ReferenceKind { - self.kind - } - - #[must_use] - pub fn value(&self) -> &str { - &self.value - } -} - -pub fn validate_static_reference( - value: &str, - kind: ReferenceKind, -) -> Result<(), StaticReferenceError> { - if contains_template_syntax(value) { - return Err(StaticReferenceError::new(kind, value)); - } - Ok(()) -} - -#[must_use] -pub fn reference_kind_for_attribute( - scope: AttributeScope, - key: &str, - value: &str, -) -> Option { - match key { - "import" => Some(ReferenceKind::Import), - "stack.child_workflow" | "stack.child_dotfile" => Some(ReferenceKind::ChildWorkflow), - "goal" if matches!(scope, AttributeScope::Graph) && value.starts_with('@') => { - Some(ReferenceKind::GraphGoalFile) - } - "prompt" | "output_schema" - if matches!(scope, AttributeScope::Node) && value.starts_with('@') => - { - Some(ReferenceKind::FileInline) - } - _ => None, - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn output_schema_at_value_is_file_inline_reference() { - assert_eq!( - reference_kind_for_attribute( - AttributeScope::Node, - "output_schema", - "@schemas/result.schema.json", - ), - Some(ReferenceKind::FileInline), - ); - } - - #[test] - fn output_schema_builtin_keyword_is_not_file_inline_reference() { - assert_eq!( - reference_kind_for_attribute(AttributeScope::Node, "output_schema", "routing"), - None, - ); - } - - #[test] - fn output_schema_reference_rejects_template_syntax() { - let error = reference_kind_for_attribute( - AttributeScope::Node, - "output_schema", - "@schemas/{{ inputs.schema }}.json", - ) - .expect("output_schema @ references should be static references") - .validate("@schemas/{{ inputs.schema }}.json") - .unwrap_err(); - - assert_eq!(error.kind(), ReferenceKind::FileInline); - assert_eq!(error.value(), "@schemas/{{ inputs.schema }}.json"); - assert!( - error - .to_string() - .contains("templates are not supported in file inline references"), - "unexpected error: {error}", - ); - } -} diff --git a/lib/components/fabro-workflow/src/transforms/import.rs b/lib/components/fabro-workflow/src/transforms/import.rs index e0082ba9d..bab7ee1b1 100644 --- a/lib/components/fabro-workflow/src/transforms/import.rs +++ b/lib/components/fabro-workflow/src/transforms/import.rs @@ -4,14 +4,14 @@ use std::sync::Arc; use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node}; use fabro_graphviz::parser; -use fabro_template::TemplateContext; +use fabro_template::{TemplateContext, validate_static_reference}; +use fabro_types::graph::ReferenceKind; use fabro_validate::Diagnostic; use super::file_inlining::template_render_store; use super::{FileInliningTransform, Transform}; use crate::error::Error; use crate::file_resolver::{FileResolver, ResolvedFile}; -use crate::static_reference::{ReferenceKind, validate_static_reference}; use crate::transforms::variable_expansion::{ RenderMode, TemplateRenderTarget, TemplateTransform, render_template_for_target, }; diff --git a/lib/components/fabro-workflow/src/transforms/importable_field.rs b/lib/components/fabro-workflow/src/transforms/importable_field.rs index acfcc52e8..cf4b5c2d1 100644 --- a/lib/components/fabro-workflow/src/transforms/importable_field.rs +++ b/lib/components/fabro-workflow/src/transforms/importable_field.rs @@ -13,8 +13,10 @@ //! [`super::file_inlining`], where the `FileResolver` and current-dir context //! live. +use fabro_template::validate_static_reference; +use fabro_types::graph::ReferenceKind; + use crate::error::Error; -use crate::static_reference::{ReferenceKind, validate_static_reference}; /// A field value that is either inline content or an `@path` file import. /// diff --git a/lib/components/fabro-workflow/src/transforms/variable_expansion.rs b/lib/components/fabro-workflow/src/transforms/variable_expansion.rs index e2c11d169..eb33f250f 100644 --- a/lib/components/fabro-workflow/src/transforms/variable_expansion.rs +++ b/lib/components/fabro-workflow/src/transforms/variable_expansion.rs @@ -6,8 +6,9 @@ use std::sync::Arc; use fabro_graphviz::graph::{AttrValue, Graph, Node}; use fabro_template::{ TemplateContext, TemplateError, TemplateRenderMode, TemplateSource, TemplateSourceOrigin, - TemplateStore, + TemplateStore, validate_static_reference, }; +use fabro_types::graph::{AttributeScope, ReferenceKind, reference_kind_for_attribute}; use fabro_types::settings::interp::Namespace; use fabro_types::settings::{InterpString, ResolveCtx, ResolveError, ResolveErrorKind}; use fabro_util::error::collect_chain; @@ -17,9 +18,6 @@ use fabro_validate::{Diagnostic, Severity}; use super::Transform; use crate::error::Error; use crate::pipeline::types::{GOAL_SELF_REFERENCE_RULE, TEMPLATE_UNDEFINED_VARIABLE_RULE}; -use crate::static_reference::{ - AttributeScope, ReferenceKind, reference_kind_for_attribute, validate_static_reference, -}; /// How the template-expansion pass should treat undefined input variables. /// @@ -521,7 +519,7 @@ impl TemplateTransform { continue; } if let Some(kind) = reference_kind_for_attribute(scope, attr_name, text) { - validate_static_reference(text, kind) + validate_static_reference(text, kind.into()) .map_err(|error| Error::Validation(error.to_string()))?; continue; } diff --git a/lib/components/fabro-workflow/tests/it/daytona_integration.rs b/lib/components/fabro-workflow/tests/it/daytona_integration.rs index 5482f642d..9932f5a52 100644 --- a/lib/components/fabro-workflow/tests/it/daytona_integration.rs +++ b/lib/components/fabro-workflow/tests/it/daytona_integration.rs @@ -27,9 +27,9 @@ use fabro_graphviz::graph::{AttrValue, Edge, Graph, Node}; use fabro_sandbox::daytona::{DaytonaConfig, DaytonaSandbox}; use fabro_static::EnvVars; use fabro_store::{ArtifactKey, ArtifactStore, Database}; -use fabro_types::{RunId, StageId, WorkflowSettings}; +use fabro_types::{RunId, StageId, WorkflowSettings, parse_blob_ref}; use fabro_util::shell; -use fabro_workflow::artifact::sync_artifacts_to_env; +use fabro_workflow::artifact; use fabro_workflow::context::Context; use fabro_workflow::error::Error; use fabro_workflow::event::Emitter; @@ -39,6 +39,7 @@ use fabro_workflow::handler::{Handler, HandlerRegistry}; use fabro_workflow::outcome::{Outcome, StageOutcome}; use fabro_workflow::records::Checkpoint; use fabro_workflow::run_options::{GitCheckpointOptions, RunOptions}; +use fabro_workflow::runtime_store::RunStoreHandle; use fabro_workflow::test_support::{WorkflowRunner, test_store_dir}; use object_store::local::LocalFileSystem; use tokio_util::sync::CancellationToken; @@ -159,6 +160,25 @@ fn load_run_checkpoint(run_dir: &Path) -> Result Result> { + let Some(current) = value.as_str() else { + return Ok(value.to_string()); + }; + if parse_blob_ref(current).is_none() { + return Ok(current.to_string()); + } + + let object_store = Arc::new(LocalFileSystem::new_with_prefix(test_store_dir(run_dir))?); + let store = Database::new(object_store, "", std::time::Duration::from_millis(1), None); + let run = store.open_run_reader(run_id).await?; + let run_store = RunStoreHandle::from(run); + Ok(artifact::resolve_text_or_blob_ref_str(current, &run_store).await?) +} + async fn create_env() -> DaytonaSandbox { let creds = load_github_app_credentials(); create_env_with_github_app(Some(creds)).await @@ -419,7 +439,9 @@ async fn daytona_artifact_sync_uploads_and_rewrites_pointer() { // Sync — the local file doesn't exist in the Daytona sandbox, so it should // upload - sync_artifacts_to_env(&mut updates, &env).await.unwrap(); + artifact::sync_artifacts_to_env(&mut updates, &env) + .await + .unwrap(); // Pointer should be rewritten to the Daytona working directory let new_pointer = updates["response.plan"].as_str().unwrap(); @@ -544,15 +566,18 @@ async fn daytona_pipeline_artifact_offload_and_sync() { .get("response.big_output") .expect("context should have response.big_output"); let pointer_str = pointer_value.as_str().expect("pointer should be a string"); - let expected_blob_id = fabro_types::RunBlobId::new( - &serde_json::to_vec(&serde_json::json!("x".repeat(150 * 1024))) - .expect("large value should serialize"), - ); - assert_eq!( - pointer_str, - fabro_types::format_blob_ref(&expected_blob_id), + assert!( + parse_blob_ref(pointer_str).is_some(), "checkpoint should persist a blob ref" ); + let resolved = resolve_checkpoint_text(dir.path(), &run_options.run_id, pointer_value) + .await + .expect("offloaded value should resolve through the run store"); + assert_eq!( + resolved, + "x".repeat(150 * 1024), + "offloaded value should round-trip through the run store" + ); env.cleanup().await.unwrap(); } diff --git a/lib/components/fabro-workflow/tests/it/integration.rs b/lib/components/fabro-workflow/tests/it/integration.rs index 7ddb72647..42ea14630 100644 --- a/lib/components/fabro-workflow/tests/it/integration.rs +++ b/lib/components/fabro-workflow/tests/it/integration.rs @@ -35,6 +35,7 @@ use fabro_model::{Catalog, ProviderId}; use fabro_store::{ArtifactKey, ArtifactStore, Database}; use fabro_types::{EventBody, RunEvent, RunId, StageId, WorkflowSettings, parse_blob_ref}; use fabro_validate::{Severity, validate, validate_or_raise}; +use fabro_workflow::artifact; use fabro_workflow::context::Context; use fabro_workflow::error::{Error, FailureSignatureExt}; use fabro_workflow::event::{Emitter, Event}; @@ -54,6 +55,7 @@ use fabro_workflow::model_fallback::ModelFallbackPolicy; use fabro_workflow::outcome::{Outcome, OutcomeExt, StageOutcome}; use fabro_workflow::records::{Checkpoint, CheckpointExt}; use fabro_workflow::run_options::{GitCheckpointOptions, RunOptions}; +use fabro_workflow::runtime_store::RunStoreHandle; use fabro_workflow::test_support::{ WorkflowRunner, collect_events, run_graph_with_hooks, test_store_dir, }; @@ -233,10 +235,11 @@ fn resolve_checkpoint_text( let Some(current) = value.as_str() else { return Ok(value.to_string()); }; - let Some(blob_id) = parse_blob_ref(current) else { + if parse_blob_ref(current).is_none() { return Ok(current.to_string()); - }; + } + let current = current.to_string(); let run_dir = run_dir.to_path_buf(); let (store_dir, uses_shared_store) = run_store_dir_and_mode(&run_dir)?; std::thread::spawn( @@ -271,10 +274,8 @@ fn resolve_checkpoint_text( .id }; let run = runtime.block_on(store.open_run_reader(&run_id))?; - let bytes = runtime - .block_on(run.read_blob(&blob_id))? - .ok_or("checkpoint blob should exist")?; - Ok(serde_json::from_slice::(&bytes)?) + let run_store = RunStoreHandle::from(run); + Ok(runtime.block_on(artifact::resolve_text_or_blob_ref_str(¤t, &run_store))?) }, ) .join() @@ -10059,15 +10060,17 @@ async fn large_context_values_are_offloaded_to_artifact_store() { .expect("context should have response.big_output"); let pointer_str = pointer_value.as_str().expect("pointer should be a string"); - let expected_blob_id = fabro_types::RunBlobId::new( - &serde_json::to_vec(&serde_json::json!("x".repeat(150 * 1024))) - .expect("large value should serialize"), - ); - assert_eq!( - pointer_str, - fabro_types::format_blob_ref(&expected_blob_id), + assert!( + parse_blob_ref(pointer_str).is_some(), "value should be a durable blob ref" ); + let resolved = resolve_checkpoint_text(dir.path(), pointer_value) + .expect("offloaded value should resolve through the run store"); + assert_eq!( + resolved, + "x".repeat(150 * 1024), + "offloaded value should round-trip through the run store" + ); // WorkflowRunCompleted artifact_count now tracks captured artifacts, not // offloaded values. @@ -10258,15 +10261,17 @@ async fn artifact_pointers_rewritten_for_remote_sandbox() { .get("response.big_output") .expect("context should have response.big_output"); let pointer_str = pointer_value.as_str().expect("pointer should be a string"); - let expected_blob_id = fabro_types::RunBlobId::new( - &serde_json::to_vec(&serde_json::json!("x".repeat(150 * 1024))) - .expect("large value should serialize"), - ); - assert_eq!( - pointer_str, - fabro_types::format_blob_ref(&expected_blob_id), + assert!( + parse_blob_ref(pointer_str).is_some(), "checkpoint should persist a blob ref" ); + let resolved = resolve_checkpoint_text(dir.path(), pointer_value) + .expect("offloaded value should resolve through the run store"); + assert_eq!( + resolved, + "x".repeat(150 * 1024), + "offloaded value should round-trip through the run store" + ); let written = remote_env.written.lock().unwrap(); assert!( diff --git a/lib/foundation/fabro-api/build.rs b/lib/foundation/fabro-api/build.rs index 38811dd01..0fb3cccd0 100644 --- a/lib/foundation/fabro-api/build.rs +++ b/lib/foundation/fabro-api/build.rs @@ -722,6 +722,10 @@ fn main() { ("CompletionMessage", "fabro_types::Message", &[]), ("CompletionMessageRole", "fabro_types::Role", &[]), ("CompletionContentPart", "fabro_types::ContentPart", &[]), + ("WorkflowVersion", "fabro_types::WorkflowVersion", &[]), + ("WorkflowPath", "fabro_types::WorkflowPath", &[]), + ("WorkflowVersionId", "fabro_types::WorkflowVersionId", &[]), + ("BlobHash", "fabro_types::BlobHash", &[]), ("CostSource", "fabro_model::CostSource", &[]), ]; for (name, path, impls) in replacements { diff --git a/lib/foundation/fabro-api/src/lib.rs b/lib/foundation/fabro-api/src/lib.rs index d9d6aa025..c53e682c7 100644 --- a/lib/foundation/fabro-api/src/lib.rs +++ b/lib/foundation/fabro-api/src/lib.rs @@ -42,7 +42,7 @@ pub mod types { pub use fabro_types::{ ActivatedSkill, AgentControlState, AgentMcpToolSummary, AgentSkillActivationSource, AgentSkillSummary, AgentToolCategory, AgentToolSource, AgentToolSummary, - AgentToolsAvailableProps, AskFabro, AuthMethod, AutomationRef, BilledTokenCounts, + AgentToolsAvailableProps, AskFabro, AuthMethod, AutomationRef, BilledTokenCounts, BlobHash, CommandTermination, Conclusion, ContentPart, CreateVariableRequest, DiffStats, DiffSummary, DirtyStatus, EventEnvelope, ExecOutputTail, FailureCategory, FailureDetail, FailureSignature, GitContext, IdpIdentity, IntegrationConnectionKind, @@ -73,7 +73,8 @@ pub mod types { StageModelUsage, StageOutcome, StageProjection, StageState, StageToolBatchProjection, SubAgentProjection, SubAgentStatus, SystemActorKind, SystemIntegrationStatus, SystemIntegrationsResponse, TodoListProjection, TurnId, UpdateVariableRequest, - UserPrincipal, Variable, VariableListResponse, WorkflowSettings, + UserPrincipal, Variable, VariableListResponse, WorkflowPath, WorkflowSettings, + WorkflowVersion, WorkflowVersionId, }; pub use crate::generated::types::*; diff --git a/lib/foundation/fabro-api/tests/blob_hash_round_trip.rs b/lib/foundation/fabro-api/tests/blob_hash_round_trip.rs new file mode 100644 index 000000000..e67818068 --- /dev/null +++ b/lib/foundation/fabro-api/tests/blob_hash_round_trip.rs @@ -0,0 +1,61 @@ +use std::any::{TypeId, type_name}; + +use fabro_api::types::{BlobHash as ApiBlobHash, WriteBlobResponse}; +use fabro_types::BlobHash; +use serde_json::json; + +const BLOB_HASH: &str = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"; + +#[test] +fn blob_hash_schema_reuses_domain_type() { + assert_same_type::(); +} + +#[test] +fn write_blob_response_round_trips_exact_wire_shape() { + let value = json!({ "hash": BLOB_HASH }); + + let response: WriteBlobResponse = serde_json::from_value(value.clone()).unwrap(); + assert_eq!(serde_json::to_value(&response).unwrap(), value); +} + +#[test] +fn blob_hash_accepts_any_case_and_emits_lowercase() { + for input in [ + BLOB_HASH.to_string(), + BLOB_HASH.to_uppercase(), + alternating_hex_case(BLOB_HASH), + ] { + let hash: ApiBlobHash = serde_json::from_value(json!(input)).unwrap(); + assert_eq!(serde_json::to_value(hash).unwrap(), json!(BLOB_HASH)); + } +} + +#[test] +fn blob_hash_rejects_non_hex_values() { + assert!(serde_json::from_value::(json!("not-a-blob-hash")).is_err()); +} + +fn assert_same_type() { + assert_eq!( + TypeId::of::(), + TypeId::of::(), + "{} must be the domain type {}", + type_name::(), + type_name::() + ); +} + +fn alternating_hex_case(value: &str) -> String { + value + .chars() + .enumerate() + .map(|(index, character)| { + if index % 2 == 0 { + character.to_ascii_uppercase() + } else { + character + } + }) + .collect() +} diff --git a/lib/foundation/fabro-api/tests/run_projection_round_trip.rs b/lib/foundation/fabro-api/tests/run_projection_round_trip.rs index 77d28178b..f1a00a5a5 100644 --- a/lib/foundation/fabro-api/tests/run_projection_round_trip.rs +++ b/lib/foundation/fabro-api/tests/run_projection_round_trip.rs @@ -1,7 +1,7 @@ use std::any::{TypeId, type_name}; use fabro_api::types::RunProjection as ApiRunProjection; -use fabro_types::{Graph, RunProjection, RunSpec, WorkflowSettings, test_support}; +use fabro_types::{RunProjection, RunSpec, test_support}; use serde_json::json; #[test] fn run_projection_reuses_canonical_type() { @@ -129,19 +129,8 @@ fn run_projection_round_trips_with_pending_control_unset() { fn run_spec_json() -> serde_json::Value { serde_json::to_value(RunSpec { - run_id: fabro_types::fixtures::RUN_1, - settings: WorkflowSettings::default(), - graph: Graph::new("test"), - graph_source: Some("digraph test {}".to_string()), - workflow_slug: None, - automation: None, - source_directory: None, - labels: std::collections::HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: None, - fork_source_ref: None, + graph_source: Some("digraph test {}".to_string()), + ..test_support::test_run_spec() }) .unwrap() } diff --git a/lib/foundation/fabro-api/tests/workflow_version_round_trip.rs b/lib/foundation/fabro-api/tests/workflow_version_round_trip.rs new file mode 100644 index 000000000..b478e393e --- /dev/null +++ b/lib/foundation/fabro-api/tests/workflow_version_round_trip.rs @@ -0,0 +1,79 @@ +use std::any::{TypeId, type_name}; + +use fabro_api::types::{ + CreateWorkflowVersionResponse, WorkflowPath as ApiWorkflowPath, + WorkflowVersion as ApiWorkflowVersion, WorkflowVersionId as ApiWorkflowVersionId, +}; +use fabro_types::{WorkflowPath, WorkflowVersion, WorkflowVersionId}; +use serde_json::json; + +const DEPENDENCY_ID: &str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + +#[test] +fn workflow_version_schemas_reuse_domain_types() { + assert_same_type::(); + assert_same_type::(); + assert_same_type::(); +} + +#[test] +fn workflow_version_round_trips_exact_wire_shape() { + let value = json!({ + "entrypoint": "workflow.fabro", + "files": { + "prompts/goal.md": "Ship it", + "workflow.fabro": "digraph W { start [shape=Mdiamond] exit [shape=Msquare] start -> exit }" + }, + "workflow_dependencies": { "children/check.fabro": DEPENDENCY_ID } + }); + + let version: ApiWorkflowVersion = serde_json::from_value(value.clone()).unwrap(); + assert_eq!(serde_json::to_value(version).unwrap(), value); +} + +#[test] +fn create_workflow_version_response_round_trips_exact_wire_shape() { + let value = json!({ "workflow_version_id": DEPENDENCY_ID }); + + let response: CreateWorkflowVersionResponse = serde_json::from_value(value.clone()).unwrap(); + assert_eq!(serde_json::to_value(&response).unwrap(), value); +} + +#[test] +fn workflow_version_id_accepts_any_case_and_emits_lowercase() { + let id = serde_json::from_value::(json!(DEPENDENCY_ID.to_uppercase())) + .unwrap(); + let emitted = serde_json::to_value(id).unwrap(); + assert_eq!(emitted, json!(DEPENDENCY_ID)); + + let text = emitted.as_str().unwrap(); + assert_eq!(text.len(), 64); + assert!( + text.bytes() + .all(|byte| matches!(byte, b'0'..=b'9' | b'a'..=b'f')) + ); +} + +#[test] +fn workflow_version_replacement_rejects_unknown_fields() { + let value = json!({ + "entrypoint": "workflow.fabro", + "files": { + "workflow.fabro": "digraph W {}" + }, + "workflow_dependencies": {}, + "metadata": {} + }); + + assert!(serde_json::from_value::(value).is_err()); +} + +fn assert_same_type() { + assert_eq!( + TypeId::of::(), + TypeId::of::(), + "{} and {} should be the same type", + type_name::(), + type_name::() + ); +} diff --git a/lib/foundation/fabro-client/src/client.rs b/lib/foundation/fabro-client/src/client.rs index a22a2ebf3..9547dddce 100644 --- a/lib/foundation/fabro-client/src/client.rs +++ b/lib/foundation/fabro-client/src/client.rs @@ -13,8 +13,8 @@ use fabro_http::multipart::{Form, Part}; use fabro_model::{Model, ModelTestMode, ProviderId}; use fabro_types::settings::run::MergeStrategy; use fabro_types::{ - ArtifactUpload, EventEnvelope, PairId, PairMessageRecord, PairMessageRequest, PairRecord, - PairStartRequest, PairTranscriptResponse, Run, RunBlobId, RunEvent, RunEventDetailResponse, + ArtifactUpload, BlobHash, EventEnvelope, PairId, PairMessageRecord, PairMessageRequest, + PairRecord, PairStartRequest, PairTranscriptResponse, Run, RunEvent, RunEventDetailResponse, RunId, RunPairStatusResponse, RunProjection, SessionId, SessionRecord, StageId, }; use fabro_util::exit::{ErrorExt, ExitClass}; @@ -1828,7 +1828,7 @@ impl Client { u32::try_from(response.into_inner().seq).context("append_run_event returned invalid seq") } - pub async fn write_run_blob(&self, run_id: &RunId, data: &[u8]) -> Result { + pub async fn write_run_blob(&self, run_id: &RunId, data: &[u8]) -> Result { let response = self .send_api(|client| async move { client @@ -1839,24 +1839,20 @@ impl Client { .await }) .await?; - response - .into_inner() - .id - .parse() - .context("write_run_blob returned invalid blob id") + Ok(response.into_inner().hash) } pub async fn read_run_blob( &self, run_id: &RunId, - blob_id: &RunBlobId, + blob_hash: &BlobHash, ) -> Result> { let response = self .current_state() .client .read_run_blob() .id(run_id.to_string()) - .blob_id(blob_id.to_string()) + .blob_hash(*blob_hash) .send() .await; match response { diff --git a/lib/foundation/fabro-config/src/layers/run.rs b/lib/foundation/fabro-config/src/layers/run.rs index f81b4e0f6..8b020666f 100644 --- a/lib/foundation/fabro-config/src/layers/run.rs +++ b/lib/foundation/fabro-config/src/layers/run.rs @@ -116,10 +116,8 @@ impl Combine for RunIntegrationsGithubLayer { /// /// Relative paths inside the `file` variant are resolved against the /// directory of the config file that declared them at load time (see -/// `fabro_config::resolve_goal_file_paths`). `{{ env.NAME }}` interpolation is -/// supported inside the `file` path; env-tokenized relative paths stay -/// unresolved until consume time and are then resolved against the run's -/// effective working directory. +/// `fabro_config::resolve_goal_file_paths`). Interpolation tokens are not +/// supported inside the `file` path; a tokenized path fails to resolve. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(untagged, deny_unknown_fields)] pub enum RunGoalLayer { diff --git a/lib/foundation/fabro-config/src/layers/settings.rs b/lib/foundation/fabro-config/src/layers/settings.rs index 8c5c362fb..4863c8833 100644 --- a/lib/foundation/fabro-config/src/layers/settings.rs +++ b/lib/foundation/fabro-config/src/layers/settings.rs @@ -10,7 +10,7 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; use super::cli::CliLayer; -use super::environment::EnvironmentLayer; +use super::environment::{EnvironmentImageLayer, EnvironmentLayer}; use super::llm::LlmLayer; use super::maps::MergeMap; use super::project::ProjectLayer; @@ -102,6 +102,40 @@ impl From for SettingsLayer { } } +impl SettingsLayer { + /// Every environment image a settings layer can carry: the image of each + /// named `[environments.*]` entry plus the `[run.environment]` image. + /// + /// This is the single definition of "where images live in a settings + /// layer". The dockerfile walkers (run compilation, manifest bundling, + /// workflow-version validation) all iterate through here so a new + /// image-bearing location only needs to be added once. + pub fn environment_images(&self) -> impl Iterator { + self.environments + .values() + .filter_map(|environment| environment.image.as_ref()) + .chain( + self.run + .as_ref() + .and_then(|run| run.environment.as_ref()) + .and_then(|environment| environment.image.as_ref()), + ) + } + + /// Mutable variant of [`Self::environment_images`]. + pub fn environment_images_mut(&mut self) -> impl Iterator { + self.environments + .values_mut() + .filter_map(|environment| environment.image.as_mut()) + .chain( + self.run + .as_mut() + .and_then(|run| run.environment.as_mut()) + .and_then(|environment| environment.image.as_mut()), + ) + } +} + #[cfg(test)] impl SettingsLayer { /// A default layer that resolves cleanly: populates `server.auth.methods` diff --git a/lib/foundation/fabro-db/migrations/2026081301_blobs.sql b/lib/foundation/fabro-db/migrations/2026081301_blobs.sql new file mode 100644 index 000000000..795e705a4 --- /dev/null +++ b/lib/foundation/fabro-db/migrations/2026081301_blobs.sql @@ -0,0 +1,7 @@ +CREATE TABLE blobs ( + hash TEXT PRIMARY KEY NOT NULL, + data BLOB NOT NULL, + CHECK (length(hash) = 64), + CHECK (hash = lower(hash)), + CHECK (hash NOT GLOB '*[^0-9a-f]*') +); diff --git a/lib/foundation/fabro-db/tests/sqlite.rs b/lib/foundation/fabro-db/tests/sqlite.rs index bc4981b06..bdb1179e4 100644 --- a/lib/foundation/fabro-db/tests/sqlite.rs +++ b/lib/foundation/fabro-db/tests/sqlite.rs @@ -73,6 +73,13 @@ async fn connect_creates_parent_directory_and_migrate_is_idempotent() -> anyhow: .await?; assert_eq!(runs_table_count, 1); + let blobs_table_count: i64 = sqlx::query_scalar( + "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'blobs'", + ) + .fetch_one(database.pool()) + .await?; + assert_eq!(blobs_table_count, 1); + let legacy_import_table_count: i64 = sqlx::query_scalar( "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = 'legacy_imports'", ) @@ -89,6 +96,93 @@ async fn connect_creates_parent_directory_and_migrate_is_idempotent() -> anyhow: Ok(()) } +#[tokio::test] +async fn blobs_schema_enforces_canonical_hashes_and_required_data() -> anyhow::Result<()> { + let dir = tempfile::tempdir()?; + let database = fabro_db::Database::connect(dir.path().join("fabro.sqlite3")).await?; + database.migrate().await?; + + let columns = sqlx::query("PRAGMA table_info(blobs)") + .fetch_all(database.pool()) + .await?; + assert_eq!(columns.len(), 2); + + assert_eq!(columns[0].get::("name"), "hash"); + assert_eq!(columns[0].get::("type"), "TEXT"); + assert_eq!(columns[0].get::("notnull"), 1); + assert_eq!(columns[0].get::("pk"), 1); + assert_eq!(columns[0].get::, _>("dflt_value"), None); + + assert_eq!(columns[1].get::("name"), "data"); + assert_eq!(columns[1].get::("type"), "BLOB"); + assert_eq!(columns[1].get::("notnull"), 1); + assert_eq!(columns[1].get::("pk"), 0); + assert_eq!(columns[1].get::, _>("dflt_value"), None); + + let binary_hash = "0".repeat(64); + let binary_data = vec![0, 0xff, 0x80, b'a']; + sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, ?)") + .bind(&binary_hash) + .bind(&binary_data) + .execute(database.pool()) + .await?; + let stored_binary: Vec = sqlx::query_scalar("SELECT data FROM blobs WHERE hash = ?") + .bind(&binary_hash) + .fetch_one(database.pool()) + .await?; + assert_eq!(stored_binary, binary_data); + + let empty_hash = "1".repeat(64); + sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, ?)") + .bind(&empty_hash) + .bind(Vec::::new()) + .execute(database.pool()) + .await?; + let stored_empty: Vec = sqlx::query_scalar("SELECT data FROM blobs WHERE hash = ?") + .bind(&empty_hash) + .fetch_one(database.pool()) + .await?; + assert!(stored_empty.is_empty()); + + for invalid_hash in [ + "a".repeat(63), + "a".repeat(65), + "A".repeat(64), + "g".repeat(64), + ] { + let result = sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, ?)") + .bind(&invalid_hash) + .bind(Vec::::new()) + .execute(database.pool()) + .await; + assert!( + result.is_err(), + "invalid blob hash should be rejected: {invalid_hash:?}" + ); + } + + let null_hash = sqlx::query("INSERT INTO blobs (hash, data) VALUES (NULL, ?)") + .bind(Vec::::new()) + .execute(database.pool()) + .await; + assert!(null_hash.is_err()); + + let null_data = sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, NULL)") + .bind("2".repeat(64)) + .execute(database.pool()) + .await; + assert!(null_data.is_err()); + + let duplicate_hash = sqlx::query("INSERT INTO blobs (hash, data) VALUES (?, ?)") + .bind(&binary_hash) + .bind(vec![1_u8]) + .execute(database.pool()) + .await; + assert!(duplicate_hash.is_err()); + + Ok(()) +} + #[tokio::test] async fn mcp_servers_schema_rejects_invalid_transport_rows() -> anyhow::Result<()> { let dir = tempfile::tempdir()?; diff --git a/lib/foundation/fabro-model/src/catalog.rs b/lib/foundation/fabro-model/src/catalog.rs index 7ff4b266f..56c0f5b0c 100644 --- a/lib/foundation/fabro-model/src/catalog.rs +++ b/lib/foundation/fabro-model/src/catalog.rs @@ -61,8 +61,8 @@ pub struct ProviderCatalogSettings { pub api_key_url: Option, #[serde(default)] pub base_url: Option, - /// Unresolved interpolation source strings (literal text, `{{ env.NAME }}`, - /// or `{{ secrets.NAME }}` tokens), resolved at the credential boundary in + /// Unresolved interpolation source strings (literal text or + /// `{{ secrets.NAME }}` tokens), resolved at the credential boundary in /// `fabro-auth`. #[serde(default)] pub extra_headers: Option>, @@ -438,8 +438,8 @@ pub struct CatalogProvider { pub billing_policy: BillingPolicy, pub api_key_url: Option, pub base_url: Option, - /// Unresolved interpolation source strings (literal text, `{{ env.NAME }}`, - /// or `{{ secrets.NAME }}` tokens), resolved at the credential boundary in + /// Unresolved interpolation source strings (literal text or + /// `{{ secrets.NAME }}` tokens), resolved at the credential boundary in /// `fabro-auth`. pub extra_headers: HashMap, pub priority: i32, diff --git a/lib/foundation/fabro-template/src/dependency.rs b/lib/foundation/fabro-template/src/dependency.rs index fa9629108..2de5fe560 100644 --- a/lib/foundation/fabro-template/src/dependency.rs +++ b/lib/foundation/fabro-template/src/dependency.rs @@ -32,10 +32,18 @@ pub struct ExtractedTemplateDependencies { #[derive(Debug, Error)] pub enum TemplateDiscoveryError { - #[error(transparent)] - Parse(#[from] TemplateError), - #[error(transparent)] - Load(#[from] TemplateLoadError), + #[error("invalid template `{parent}`")] + Parse { + parent: ManifestPath, + #[source] + source: Box, + }, + #[error("failed to load a template dependency of `{parent}`")] + Load { + parent: ManifestPath, + #[source] + source: TemplateLoadError, + }, #[error("missing template dependency `{reference}` from `{parent}`")] Missing { parent: ManifestPath, @@ -45,6 +53,19 @@ pub enum TemplateDiscoveryError { Dynamic { parent: ManifestPath }, } +impl TemplateDiscoveryError { + /// Path of the template source this error is attributed to. + #[must_use] + pub fn source_path(&self) -> &ManifestPath { + match self { + Self::Parse { parent, .. } + | Self::Load { parent, .. } + | Self::Missing { parent, .. } + | Self::Dynamic { parent } => parent, + } + } +} + #[derive(Clone, Debug, Default)] pub struct TemplateDependencyClosure { pub sources: HashMap, @@ -80,38 +101,55 @@ pub fn discover_static_dependency_closure( store: &dyn TemplateStore, ) -> Result { let mut sources = HashMap::new(); + // A root and a loaded file can collide on `path` while carrying different + // content (an inline prompt is anchored at its graph file's path), so + // traversal dedup keys on the full occurrence rather than the path: a + // path-keyed check would leave the collided occurrence unparsed. The + // result map stays path-keyed, with the last distinct occurrence winning. + let mut parsed = HashSet::new(); let mut queue = VecDeque::new(); - for source in roots { - if sources - .insert(source.path.clone(), source.clone()) - .is_none() - { + let mut enqueue = |source: TemplateSource, + sources: &mut HashMap, + queue: &mut VecDeque| { + let occurrence = ( + source.path.clone(), + source.root.clone(), + source.content.clone(), + ); + if parsed.insert(occurrence) { + sources.insert(source.path.clone(), source.clone()); queue.push_back(source); } + }; + + for source in roots { + enqueue(source, &mut sources, &mut queue); } while let Some(source) = queue.pop_front() { - let dependencies = - extract_template_dependencies(&source.path.to_string(), &source.content)?; + let dependencies = extract_template_dependencies(&source.path.to_string(), &source.content) + .map_err(|error| TemplateDiscoveryError::Parse { + parent: source.path.clone(), + source: Box::new(error), + })?; if !dependencies.dynamic_references.is_empty() { return Err(TemplateDiscoveryError::Dynamic { parent: source.path, }); } for dependency in dependencies.static_references { - let loaded = store.load(&source, &dependency.reference)?.ok_or_else(|| { - TemplateDiscoveryError::Missing { + let loaded = store + .load(&source, &dependency.reference) + .map_err(|error| TemplateDiscoveryError::Load { + parent: source.path.clone(), + source: error, + })? + .ok_or_else(|| TemplateDiscoveryError::Missing { parent: source.path.clone(), reference: dependency.reference.clone(), - } - })?; - if sources - .insert(loaded.path.clone(), loaded.clone()) - .is_none() - { - queue.push_back(loaded); - } + })?; + enqueue(loaded, &mut sources, &mut queue); } } diff --git a/lib/foundation/fabro-template/src/lib.rs b/lib/foundation/fabro-template/src/lib.rs index f312e9416..9fc89697b 100644 --- a/lib/foundation/fabro-template/src/lib.rs +++ b/lib/foundation/fabro-template/src/lib.rs @@ -8,6 +8,7 @@ use minijinja::value::{Object, Value}; use minijinja::{AutoEscape, Environment, ErrorKind, UndefinedBehavior}; mod dependency; +mod static_reference; mod store; pub use dependency::{ @@ -15,6 +16,10 @@ pub use dependency::{ TemplateDependencyKind, TemplateDiscoveryError, discover_static_dependency_closure, extract_template_dependencies, }; +pub use static_reference::{ + GraphReference, GraphReferenceError, StaticReferenceError, validate_static_reference, + visit_graph_references, +}; pub use store::{ BundleTemplateStore, CachedTemplateStore, FilesystemTemplateStore, RecordingTemplateStore, TemplateIncludeResolver, TemplateLoadError, TemplateSource, TemplateSourceOrigin, @@ -1383,6 +1388,123 @@ mod tests { assert!(matches!(err, TemplateDiscoveryError::Dynamic { .. })); } + #[test] + fn static_dependency_closure_visits_colliding_root_occurrences() { + let roots = [ + TemplateSource::new(manifest_path("workflow.fabro"), manifest_path("."), "valid"), + TemplateSource::new( + manifest_path("workflow.fabro"), + manifest_path("."), + r"{% include inputs.partial %}", + ), + ]; + + let error = + discover_static_dependency_closure(roots, bundle_store(&[]).as_ref()).unwrap_err(); + + assert!(matches!( + error, + TemplateDiscoveryError::Dynamic { parent } + if parent == manifest_path("workflow.fabro") + )); + } + + #[test] + fn static_dependency_closure_parses_dependencies_shadowed_by_root_paths() { + // An inline root anchored at its graph file's path must not shadow the + // file itself when another template includes it: the loaded file + // content still gets parsed. + let roots = [ + TemplateSource::new(manifest_path("workflow.fabro"), manifest_path("."), "valid"), + TemplateSource::new( + manifest_path("goal.md"), + manifest_path("."), + r#"{% include "workflow.fabro" %}"#, + ), + ]; + + let error = discover_static_dependency_closure( + roots, + bundle_store(&[("workflow.fabro", r#"{% include "missing.md" %}"#)]).as_ref(), + ) + .unwrap_err(); + + assert!(matches!( + error, + TemplateDiscoveryError::Missing { parent, reference } + if parent == manifest_path("workflow.fabro") && reference == "missing.md" + )); + } + + #[test] + fn static_dependency_closure_parses_identical_root_occurrences_once() { + struct CountingStore { + inner: Arc, + loads: std::sync::atomic::AtomicUsize, + } + + impl TemplateStore for CountingStore { + fn load( + &self, + parent: &TemplateSource, + reference: &str, + ) -> Result, TemplateLoadError> { + self.loads + .fetch_add(1, std::sync::atomic::Ordering::Relaxed); + self.inner.load(parent, reference) + } + } + + let root = TemplateSource::new( + manifest_path("main.md"), + manifest_path("."), + r#"{% include "shared.md" %}"#, + ); + let store = CountingStore { + inner: bundle_store(&[("shared.md", "shared")]), + loads: std::sync::atomic::AtomicUsize::new(0), + }; + + let closure = discover_static_dependency_closure([root.clone(), root], &store).unwrap(); + + assert!(closure.sources.contains_key(&manifest_path("shared.md"))); + assert_eq!(store.loads.load(std::sync::atomic::Ordering::Relaxed), 1); + } + + #[test] + fn static_dependency_closure_deduplicates_loaded_dependencies_across_roots() { + let roots = [ + TemplateSource::new( + manifest_path("first.md"), + manifest_path("."), + r#"{% include "shared.md" %}"#, + ), + TemplateSource::new( + manifest_path("second.md"), + manifest_path("."), + r#"{% include "shared.md" %}"#, + ), + ]; + + let closure = discover_static_dependency_closure( + roots, + bundle_store(&[ + ("shared.md", r#"{% include "nested.md" %}"#), + ("nested.md", "nested"), + ]) + .as_ref(), + ) + .unwrap(); + + assert_eq!( + closure.paths(), + ["first.md", "second.md", "shared.md", "nested.md"] + .into_iter() + .map(manifest_path) + .collect() + ); + } + #[test] fn render_lenient_named_preserves_source_name_for_syntax_errors() { let ctx = TemplateContext::new(); diff --git a/lib/foundation/fabro-template/src/static_reference.rs b/lib/foundation/fabro-template/src/static_reference.rs new file mode 100644 index 000000000..e2678ea65 --- /dev/null +++ b/lib/foundation/fabro-template/src/static_reference.rs @@ -0,0 +1,249 @@ +//! Static file references in workflow graphs. +//! +//! Workflow graphs name other files through a fixed attribute vocabulary +//! (`import`, `stack.child_workflow`, `@`-prefixed `prompt`/`output_schema` +//! values, and the graph `goal`). These references are *static*: they may not +//! contain template syntax, because they are resolved before any template +//! rendering happens. +//! +//! [`visit_graph_references`] is the one walker over that vocabulary. The +//! manifest bundler and workflow-version validation both consume it, so a new +//! reference-bearing attribute is added here once instead of drifting between +//! per-crate walkers. + +use fabro_types::graph::{ + AttributeScope, Graph, GraphReferenceKind, ReferenceKind, reference_kind_for_attribute, +}; + +use crate::contains_template_syntax; + +/// A static file reference that unexpectedly contains template syntax. +#[derive(Debug, thiserror::Error)] +#[error("templates are not supported in {kind}s: {value}")] +pub struct StaticReferenceError { + kind: ReferenceKind, + value: String, +} + +impl StaticReferenceError { + #[must_use] + pub fn new(kind: ReferenceKind, value: impl Into) -> Self { + Self { + kind, + value: value.into(), + } + } + + #[must_use] + pub fn kind(&self) -> ReferenceKind { + self.kind + } + + #[must_use] + pub fn value(&self) -> &str { + &self.value + } +} + +/// Reject static file references (imports, child workflows, `@` file values) +/// that contain template syntax. +pub fn validate_static_reference( + value: &str, + kind: ReferenceKind, +) -> Result<(), StaticReferenceError> { + if contains_template_syntax(value) { + return Err(StaticReferenceError::new(kind, value)); + } + Ok(()) +} + +/// One file reference or inline template discovered in a workflow graph. +/// +/// `@` prefixes are already stripped from file references; inline variants +/// carry template content that the consumer should feed to template-dependency +/// discovery. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum GraphReference<'graph> { + /// `graph [goal="@"]`. + GoalFile { reference: &'graph str }, + /// A non-`@` graph `goal`: inline template content. + GoalInline { content: &'graph str }, + /// `node [import=""]` — another graph file to walk. + Import { reference: &'graph str }, + /// `node [stack.child_workflow=""]`. + ChildWorkflow { reference: &'graph str }, + /// `node [="@"]` for file-inlined attributes + /// (`prompt`, `output_schema`). + FileInline { + key: &'graph str, + reference: &'graph str, + }, + /// A non-`@` node prompt: inline template content. + InlinePrompt { content: &'graph str }, +} + +/// Error from [`visit_graph_references`]. +#[derive(Debug, thiserror::Error)] +pub enum GraphReferenceError { + #[error(transparent)] + StaticReference(StaticReferenceError), + #[error(transparent)] + Visit(E), +} + +/// Walk every static file reference and inline template in one parsed graph, +/// validating that file references are template-free before emitting them. +/// +/// The walker covers a single graph; recursion into `Import` targets and +/// resolution of references against a file source are the consumer's job. +pub fn visit_graph_references<'graph, E>( + graph: &'graph Graph, + mut visit: impl FnMut(GraphReference<'graph>) -> Result<(), E>, +) -> Result<(), GraphReferenceError> { + let goal = graph.goal(); + if !goal.is_empty() { + if let Some(reference) = goal.strip_prefix('@') { + validate_static_reference(reference, ReferenceKind::GraphGoalFile) + .map_err(GraphReferenceError::StaticReference)?; + visit(GraphReference::GoalFile { reference }).map_err(GraphReferenceError::Visit)?; + } else { + visit(GraphReference::GoalInline { content: goal }) + .map_err(GraphReferenceError::Visit)?; + } + } + + for node in graph.nodes.values() { + for (key, value) in &node.attrs { + let Some(value) = value.as_str() else { + continue; + }; + let Some(kind) = reference_kind_for_attribute(AttributeScope::Node, key, value) else { + continue; + }; + let reference = match kind { + GraphReferenceKind::Import | GraphReferenceKind::ChildWorkflow => value, + // Classification only yields these kinds for `@` values. + GraphReferenceKind::FileInline | GraphReferenceKind::GraphGoalFile => value + .strip_prefix('@') + .expect("file reference classification requires a leading '@'"), + }; + validate_static_reference(reference, kind.into()) + .map_err(GraphReferenceError::StaticReference)?; + let event = match kind { + GraphReferenceKind::Import => GraphReference::Import { reference }, + GraphReferenceKind::ChildWorkflow => GraphReference::ChildWorkflow { reference }, + GraphReferenceKind::FileInline => GraphReference::FileInline { key, reference }, + GraphReferenceKind::GraphGoalFile => GraphReference::GoalFile { reference }, + }; + visit(event).map_err(GraphReferenceError::Visit)?; + } + + if let Some(prompt) = node.prompt().filter(|prompt| !prompt.starts_with('@')) { + visit(GraphReference::InlinePrompt { content: prompt }) + .map_err(GraphReferenceError::Visit)?; + } + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeSet; + + use fabro_types::graph::{AttrValue, Graph, Node, ReferenceKind}; + + use super::{GraphReference, GraphReferenceError, validate_static_reference}; + + #[test] + fn static_reference_rejects_template_syntax() { + let error = validate_static_reference( + "@schemas/{{ inputs.schema }}.json", + ReferenceKind::FileInline, + ) + .unwrap_err(); + + assert_eq!(error.kind(), ReferenceKind::FileInline); + assert_eq!(error.value(), "@schemas/{{ inputs.schema }}.json"); + assert!( + error + .to_string() + .contains("templates are not supported in file inline references"), + "unexpected error: {error}", + ); + assert!( + validate_static_reference("@schemas/result.json", ReferenceKind::FileInline).is_ok() + ); + } + + fn node_with(id: &str, attrs: &[(&str, &str)]) -> Node { + let mut node = Node::new(id); + for (key, value) in attrs { + node.attrs + .insert((*key).to_string(), AttrValue::String((*value).to_string())); + } + node + } + + #[test] + fn visits_every_reference_kind_once() { + let mut graph = Graph::new("test"); + graph.attrs.insert( + "goal".to_string(), + AttrValue::String("@goal.md".to_string()), + ); + for node in [ + node_with("imported", &[("import", "graphs/child.fabro")]), + node_with("child", &[("stack.child_workflow", "children/check.fabro")]), + node_with("file_prompt", &[("prompt", "@prompts/task.md")]), + node_with("inline", &[("prompt", "Do the {{ thing }}")]), + ] { + graph.nodes.insert(node.id.clone(), node); + } + + let mut seen = BTreeSet::new(); + super::visit_graph_references( + &graph, + |reference| -> Result<(), std::convert::Infallible> { + seen.insert(match reference { + GraphReference::GoalFile { reference } => format!("goal-file:{reference}"), + GraphReference::GoalInline { content } => format!("goal-inline:{content}"), + GraphReference::Import { reference } => format!("import:{reference}"), + GraphReference::ChildWorkflow { reference } => format!("child:{reference}"), + GraphReference::FileInline { key, reference } => { + format!("file:{key}:{reference}") + } + GraphReference::InlinePrompt { content } => format!("inline:{content}"), + }); + Ok(()) + }, + ) + .unwrap(); + + assert_eq!( + seen, + BTreeSet::from([ + "goal-file:goal.md".to_string(), + "import:graphs/child.fabro".to_string(), + "child:children/check.fabro".to_string(), + "file:prompt:prompts/task.md".to_string(), + "inline:Do the {{ thing }}".to_string(), + ]) + ); + } + + #[test] + fn rejects_template_syntax_in_references_before_visiting() { + let mut graph = Graph::new("test"); + graph.nodes.insert( + "imported".to_string(), + node_with("imported", &[("import", "graphs/{{ name }}.fabro")]), + ); + + let error = + super::visit_graph_references(&graph, |_| -> Result<(), std::convert::Infallible> { + panic!("references with template syntax must not be visited") + }) + .unwrap_err(); + assert!(matches!(error, GraphReferenceError::StaticReference(_))); + } +} diff --git a/lib/foundation/fabro-test/src/lib.rs b/lib/foundation/fabro-test/src/lib.rs index 74a5f6727..00af8bf4c 100644 --- a/lib/foundation/fabro-test/src/lib.rs +++ b/lib/foundation/fabro-test/src/lib.rs @@ -1955,14 +1955,12 @@ pub fn json_snapshot_filters(mut filters: Vec<(String, String)>) -> Vec<(String, r#""id": "[EVENT_ID]""#.to_string(), )); filters = json_elapsed_ms_snapshot_filters(filters); - filters.push(( - r#""manifest_blob":\s*"[0-9a-f]{64}""#.to_string(), - r#""manifest_blob": "[BLOB_ID]""#.to_string(), - )); - filters.push(( - r#""definition_blob":\s*"[0-9a-f]{64}""#.to_string(), - r#""definition_blob": "[BLOB_ID]""#.to_string(), - )); + for field in ["manifest_blob", "definition_blob"] { + filters.push(( + format!(r#""{field}":\s*"[0-9a-f]{{64}}""#), + format!(r#""{field}": "[BLOB_HASH]""#), + )); + } filters.push(( r#""run_dir":\s*"\[STORAGE_DIR\]/scratch/\d{8}-\[ULID\]""#.to_string(), r#""run_dir": "[RUN_DIR]""#.to_string(), @@ -2562,8 +2560,8 @@ mod tests { "inference_time_ms": "[INFERENCE_TIME_MS]", "tool_time_ms": "[TOOL_TIME_MS]", "active_time_ms": "[ACTIVE_TIME_MS]", - "manifest_blob": "[BLOB_ID]", - "definition_blob": "[BLOB_ID]", + "manifest_blob": "[BLOB_HASH]", + "definition_blob": "[BLOB_HASH]", "run_dir": "[RUN_DIR]", "message": "[CUSTOM]" }"# diff --git a/lib/foundation/fabro-types/src/blob_hash.rs b/lib/foundation/fabro-types/src/blob_hash.rs new file mode 100644 index 000000000..45f9de0ad --- /dev/null +++ b/lib/foundation/fabro-types/src/blob_hash.rs @@ -0,0 +1,131 @@ +use std::fmt; +use std::str::FromStr; + +use hex::FromHexError; +use serde::de::Error as _; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use sha2::{Digest, Sha256}; + +/// SHA-256 content identity. +/// +/// Parsing accepts exactly 64 hexadecimal digits case-insensitively. Display +/// and serialization emit the canonical lowercase form. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct BlobHash([u8; 32]); + +impl BlobHash { + pub fn new(content: &[u8]) -> Self { + let hash = Sha256::digest(content); + let mut bytes = [0_u8; 32]; + bytes.copy_from_slice(&hash); + Self(bytes) + } +} + +impl fmt::Display for BlobHash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&hex::encode(self.0)) + } +} + +impl FromStr for BlobHash { + type Err = FromHexError; + + fn from_str(s: &str) -> Result { + let mut bytes = [0_u8; 32]; + hex::decode_to_slice(s, &mut bytes)?; + Ok(Self(bytes)) + } +} + +impl Serialize for BlobHash { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl<'de> Deserialize<'de> for BlobHash { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let value = String::deserialize(deserializer)?; + value.parse().map_err(D::Error::custom) + } +} + +#[cfg(test)] +mod tests { + use crate::BlobHash; + + #[test] + fn same_content_produces_same_blob_hash() { + assert_eq!(BlobHash::new(b"hello"), BlobHash::new(b"hello")); + } + + #[test] + fn display_is_lowercase_sha256_hex() { + assert_eq!( + BlobHash::new(b"hello").to_string(), + "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" + ); + } + + #[test] + fn different_content_produces_different_blob_hashes() { + assert_ne!(BlobHash::new(b"hello"), BlobHash::new(b"world")); + } + + #[test] + fn parse_accepts_any_case_and_display_normalizes_to_lowercase() { + let blob_hash = BlobHash::new(b"hello"); + let lowercase = blob_hash.to_string(); + let uppercase = lowercase.to_uppercase(); + let mixed_case = alternating_hex_case(&lowercase); + + for value in [&lowercase, &uppercase, &mixed_case] { + let parsed: BlobHash = value.parse().unwrap(); + assert_eq!(parsed, blob_hash); + assert_eq!(parsed.to_string(), lowercase); + } + } + + #[test] + fn serde_round_trip() { + let blob_hash = BlobHash::new(b"hello"); + let value = serde_json::to_value(blob_hash).unwrap(); + let parsed: BlobHash = serde_json::from_value(value).unwrap(); + assert_eq!(parsed, blob_hash); + } + + #[test] + fn parse_rejects_invalid_shapes() { + for value in [ + String::new(), + "0".repeat(63), + "0".repeat(65), + "g".repeat(64), + format!("0x{}", "0".repeat(64)), + format!(" {}", "0".repeat(64)), + ] { + assert!(value.parse::().is_err(), "accepted {value:?}"); + } + } + + fn alternating_hex_case(value: &str) -> String { + value + .chars() + .enumerate() + .map(|(index, character)| { + if index % 2 == 0 { + character.to_ascii_uppercase() + } else { + character + } + }) + .collect() + } +} diff --git a/lib/foundation/fabro-types/src/blob_ref.rs b/lib/foundation/fabro-types/src/blob_ref.rs index 3db7c719a..f413cd6ff 100644 --- a/lib/foundation/fabro-types/src/blob_ref.rs +++ b/lib/foundation/fabro-types/src/blob_ref.rs @@ -1,35 +1,35 @@ use std::path::Path; -use crate::RunBlobId; +use crate::BlobHash; const BLOB_REF_PREFIX: &str = "blob://sha256/"; #[must_use] -pub fn format_blob_ref(blob_id: &RunBlobId) -> String { - format!("{BLOB_REF_PREFIX}{blob_id}") +pub fn format_blob_ref(blob_hash: &BlobHash) -> String { + format!("{BLOB_REF_PREFIX}{blob_hash}") } #[must_use] -pub fn parse_blob_ref(value: &str) -> Option { +pub fn parse_blob_ref(value: &str) -> Option { value.strip_prefix(BLOB_REF_PREFIX)?.parse().ok() } #[must_use] -pub fn parse_managed_blob_file_ref(value: &str) -> Option { +pub fn parse_managed_blob_file_ref(value: &str) -> Option { let path = value.strip_prefix("file://")?; - let blob_id = parse_blob_file_name(path)?; + let blob_hash = parse_blob_file_name(path)?; if has_path_suffix(path, &["runtime", "blobs"]) || has_path_suffix(path, &[".fabro", "blobs"]) { - Some(blob_id) + Some(blob_hash) } else { None } } -fn parse_blob_file_name(path: &str) -> Option { +fn parse_blob_file_name(path: &str) -> Option { let file_name = Path::new(path).file_name()?.to_str()?; - let blob_id = file_name.strip_suffix(".json")?; - blob_id.parse().ok() + let blob_hash = file_name.strip_suffix(".json")?; + blob_hash.parse().ok() } fn has_path_suffix(path: &str, suffix: &[&str]) -> bool { @@ -46,30 +46,30 @@ fn has_path_suffix(path: &str, suffix: &[&str]) -> bool { #[cfg(test)] mod tests { use super::{format_blob_ref, parse_blob_ref, parse_managed_blob_file_ref}; - use crate::RunBlobId; + use crate::BlobHash; #[test] fn blob_ref_round_trips() { - let blob_id = RunBlobId::new(br#"{"kind":"summary"}"#); - let formatted = format_blob_ref(&blob_id); + let blob_hash = BlobHash::new(br#"{"kind":"summary"}"#); + let formatted = format_blob_ref(&blob_hash); - assert_eq!(parse_blob_ref(&formatted), Some(blob_id)); + assert_eq!(parse_blob_ref(&formatted), Some(blob_hash)); } #[test] fn managed_local_blob_file_ref_is_recognized() { - let blob_id = RunBlobId::new(b"hello"); - let value = format!("file:///tmp/run/runtime/blobs/{blob_id}.json"); + let blob_hash = BlobHash::new(b"hello"); + let value = format!("file:///tmp/run/runtime/blobs/{blob_hash}.json"); - assert_eq!(parse_managed_blob_file_ref(&value), Some(blob_id)); + assert_eq!(parse_managed_blob_file_ref(&value), Some(blob_hash)); } #[test] fn managed_remote_blob_file_ref_is_recognized() { - let blob_id = RunBlobId::new(b"hello"); - let value = format!("file:///sandbox/.fabro/blobs/{blob_id}.json"); + let blob_hash = BlobHash::new(b"hello"); + let value = format!("file:///sandbox/.fabro/blobs/{blob_hash}.json"); - assert_eq!(parse_managed_blob_file_ref(&value), Some(blob_id)); + assert_eq!(parse_managed_blob_file_ref(&value), Some(blob_hash)); } #[test] diff --git a/lib/foundation/fabro-types/src/graph.rs b/lib/foundation/fabro-types/src/graph.rs index e2ed3fab4..ded69954d 100644 --- a/lib/foundation/fabro-types/src/graph.rs +++ b/lib/foundation/fabro-types/src/graph.rs @@ -590,6 +590,78 @@ impl Graph { } } +/// Where an attribute appears in a workflow graph. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum AttributeScope { + Graph, + Node, + Edge, +} + +/// Kinds of static (non-templated) workflow-owned file references. +#[derive(Clone, Copy, Debug, Eq, PartialEq, strum::Display)] +pub enum ReferenceKind { + #[strum(to_string = "file inline reference")] + FileInline, + #[strum(to_string = "import reference")] + Import, + #[strum(to_string = "child workflow reference")] + ChildWorkflow, + #[strum(to_string = "Dockerfile reference")] + Dockerfile, + #[strum(to_string = "graph goal file reference")] + GraphGoalFile, + #[strum(to_string = "run goal file reference")] + RunGoalFile, +} + +/// Kinds of static file references that graph attributes can carry: the +/// subset of [`ReferenceKind`] that [`reference_kind_for_attribute`] can +/// classify. Config-sourced kinds (Dockerfiles, run goal files) are +/// unrepresentable here by construction. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum GraphReferenceKind { + FileInline, + Import, + ChildWorkflow, + GraphGoalFile, +} + +impl From for ReferenceKind { + fn from(kind: GraphReferenceKind) -> Self { + match kind { + GraphReferenceKind::FileInline => Self::FileInline, + GraphReferenceKind::Import => Self::Import, + GraphReferenceKind::ChildWorkflow => Self::ChildWorkflow, + GraphReferenceKind::GraphGoalFile => Self::GraphGoalFile, + } + } +} + +/// Classify a graph attribute as a static file reference, if it is one. +#[must_use] +pub fn reference_kind_for_attribute( + scope: AttributeScope, + key: &str, + value: &str, +) -> Option { + match key { + "import" if matches!(scope, AttributeScope::Node) => Some(GraphReferenceKind::Import), + "stack.child_workflow" if matches!(scope, AttributeScope::Node) => { + Some(GraphReferenceKind::ChildWorkflow) + } + "goal" if matches!(scope, AttributeScope::Graph) && value.starts_with('@') => { + Some(GraphReferenceKind::GraphGoalFile) + } + "prompt" | "output_schema" + if matches!(scope, AttributeScope::Node) && value.starts_with('@') => + { + Some(GraphReferenceKind::FileInline) + } + _ => None, + } +} + #[cfg(test)] mod tests { use super::*; @@ -1111,4 +1183,24 @@ mod tests { ); assert_eq!(g.loop_restart_signature_limit(), 3); } + + #[test] + fn output_schema_at_value_is_file_inline_reference() { + assert_eq!( + reference_kind_for_attribute( + AttributeScope::Node, + "output_schema", + "@schemas/result.schema.json", + ), + Some(GraphReferenceKind::FileInline), + ); + } + + #[test] + fn output_schema_builtin_keyword_is_not_file_inline_reference() { + assert_eq!( + reference_kind_for_attribute(AttributeScope::Node, "output_schema", "routing"), + None, + ); + } } diff --git a/lib/foundation/fabro-types/src/lib.rs b/lib/foundation/fabro-types/src/lib.rs index 9dba7fae6..bb3c86620 100644 --- a/lib/foundation/fabro-types/src/lib.rs +++ b/lib/foundation/fabro-types/src/lib.rs @@ -3,6 +3,7 @@ extern crate self as fabro_types; pub mod artifact; pub mod auth; pub mod billing; +pub mod blob_hash; pub mod blob_ref; pub mod checkpoint; pub mod command_output; @@ -26,7 +27,6 @@ pub mod pull_request; pub mod reasoning; pub mod repository; pub mod run; -pub mod run_blob_id; pub mod run_event; pub mod run_failure; pub mod run_id; @@ -54,6 +54,9 @@ pub mod timing; pub mod todo; pub mod transcript; pub mod variable; +pub mod workflow_path; +pub mod workflow_version; +pub mod workflow_version_id; pub use artifact::ArtifactUpload; pub use auth::{IdpIdentity, IdpIdentityError}; @@ -63,6 +66,7 @@ pub use billing::{ ModelBillingFacts, ModelBillingInput, ModelPricing, ModelPricingPolicy, ModelRef, ModelUsage, OpenAiBillingFacts, OpenAiModelPricing, PricePerMTok, Speed, TokenCounts, UsdMicros, }; +pub use blob_hash::BlobHash; pub use blob_ref::{format_blob_ref, parse_blob_ref, parse_managed_blob_file_ref}; pub use checkpoint::Checkpoint; pub use command_output::{CommandOutputStream, CommandTermination}; @@ -113,7 +117,6 @@ pub use run::{ DirtyStatus, ForkSourceRef, GitContext, RunClientProvenance, RunProvenance, RunServerProvenance, RunSpec, }; -pub use run_blob_id::RunBlobId; pub use run_event::{ AgentMcpToolSummary, AgentMemoryFileProps, AgentSkillActivationSource, AgentSkillSummary, AgentToolCategory, AgentToolSource, AgentToolSummary, AgentToolsAvailableProps, EventBody, @@ -183,3 +186,11 @@ pub use transcript::{ pub use variable::{ CreateVariableRequest, UpdateVariableRequest, Variable, VariableListResponse, is_env_style_name, }; +pub use workflow_path::{ + MAX_WORKFLOW_PATH_BYTES, MAX_WORKFLOW_PATH_COMPONENTS, WorkflowPath, WorkflowPathParseError, +}; +pub use workflow_version::{ + MAX_WORKFLOW_VERSION_BYTES, MAX_WORKFLOW_VERSION_DEPENDENCIES, MAX_WORKFLOW_VERSION_FILE_BYTES, + MAX_WORKFLOW_VERSION_FILES, WorkflowVersion, WorkflowVersionShapeError, +}; +pub use workflow_version_id::{WorkflowVersionId, WorkflowVersionIdParseError}; diff --git a/lib/foundation/fabro-types/src/run.rs b/lib/foundation/fabro-types/src/run.rs index cf0fbe1ff..287f5b85f 100644 --- a/lib/foundation/fabro-types/src/run.rs +++ b/lib/foundation/fabro-types/src/run.rs @@ -3,9 +3,9 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; use crate::WorkflowSettings; +use crate::blob_hash::BlobHash; use crate::graph::Graph; use crate::principal::Principal; -use crate::run_blob_id::RunBlobId; use crate::run_id::RunId; use crate::run_summary::AutomationRef; @@ -73,9 +73,9 @@ pub struct RunSpec { pub labels: HashMap, pub provenance: RunProvenance, #[serde(default, skip_serializing_if = "Option::is_none")] - pub manifest_blob: Option, + pub manifest_blob: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub definition_blob: Option, + pub definition_blob: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub git: Option, #[serde(default, skip_serializing_if = "Option::is_none")] diff --git a/lib/foundation/fabro-types/src/run_blob_id.rs b/lib/foundation/fabro-types/src/run_blob_id.rs deleted file mode 100644 index b7c43d708..000000000 --- a/lib/foundation/fabro-types/src/run_blob_id.rs +++ /dev/null @@ -1,98 +0,0 @@ -use std::fmt; -use std::str::FromStr; - -use hex::FromHexError; -use serde::de::Error as _; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use sha2::{Digest, Sha256}; - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct RunBlobId([u8; 32]); - -impl RunBlobId { - pub fn new(content: &[u8]) -> Self { - let hash = Sha256::digest(content); - let mut bytes = [0_u8; 32]; - bytes.copy_from_slice(&hash); - Self(bytes) - } -} - -impl fmt::Display for RunBlobId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&hex::encode(self.0)) - } -} - -impl FromStr for RunBlobId { - type Err = FromHexError; - - fn from_str(s: &str) -> Result { - let mut bytes = [0_u8; 32]; - hex::decode_to_slice(s, &mut bytes)?; - Ok(Self(bytes)) - } -} - -impl Serialize for RunBlobId { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.to_string()) - } -} - -impl<'de> Deserialize<'de> for RunBlobId { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let value = String::deserialize(deserializer)?; - value.parse().map_err(D::Error::custom) - } -} - -#[cfg(test)] -mod tests { - use crate::RunBlobId; - - #[test] - fn same_content_produces_same_blob_id() { - assert_eq!(RunBlobId::new(b"hello"), RunBlobId::new(b"hello")); - } - - #[test] - fn display_is_lowercase_sha256_hex() { - assert_eq!( - RunBlobId::new(b"hello").to_string(), - "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" - ); - } - - #[test] - fn different_content_produces_different_blob_ids() { - assert_ne!(RunBlobId::new(b"hello"), RunBlobId::new(b"world")); - } - - #[test] - fn display_and_parse_round_trip() { - let blob_id = RunBlobId::new(b"hello"); - let parsed: RunBlobId = blob_id.to_string().parse().unwrap(); - assert_eq!(parsed, blob_id); - } - - #[test] - fn serde_round_trip() { - let blob_id = RunBlobId::new(b"hello"); - let value = serde_json::to_value(blob_id).unwrap(); - let parsed: RunBlobId = serde_json::from_value(value).unwrap(); - assert_eq!(parsed, blob_id); - } - - #[test] - fn parse_rejects_non_hex_blob_ids() { - let parsed = "not-a-blob-id".parse::(); - assert!(parsed.is_err()); - } -} diff --git a/lib/foundation/fabro-types/src/run_event/mod.rs b/lib/foundation/fabro-types/src/run_event/mod.rs index d3fa5c330..99c9c4aa5 100644 --- a/lib/foundation/fabro-types/src/run_event/mod.rs +++ b/lib/foundation/fabro-types/src/run_event/mod.rs @@ -937,7 +937,7 @@ mod tests { use super::*; use crate::{ - AuthMethod, CommandTermination, Edge, Graph, IdpIdentity, Node, PendingReason, RunBlobId, + AuthMethod, BlobHash, CommandTermination, Edge, Graph, IdpIdentity, Node, PendingReason, WorkflowSettings, fixtures, test_support, }; @@ -1059,7 +1059,7 @@ mod tests { "labels": {}, "source_directory": "/tmp/run", "provenance": test_support::test_run_provenance(), - "manifest_blob": RunBlobId::new(br#"{"version":1}"#).to_string() + "manifest_blob": BlobHash::new(br#"{"version":1}"#).to_string() } }); @@ -1337,7 +1337,7 @@ mod tests { "run_id": fixtures::RUN_1, "event": "run.submitted", "properties": { - "definition_blob": RunBlobId::new(br#"{"workflow_path":"workflow.fabro"}"#).to_string() + "definition_blob": BlobHash::new(br#"{"workflow_path":"workflow.fabro"}"#).to_string() } }); diff --git a/lib/foundation/fabro-types/src/run_event/run.rs b/lib/foundation/fabro-types/src/run_event/run.rs index d070d8aef..68a994dc9 100644 --- a/lib/foundation/fabro-types/src/run_event/run.rs +++ b/lib/foundation/fabro-types/src/run_event/run.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use super::{BilledTokenCounts, ExecOutputTail, RunNoticeLevel}; use crate::status::{BlockedReason, PendingReason, SuccessReason}; use crate::{ - AutomationRef, DiffSummary, ForkSourceRef, GitContext, Graph, PairId, PairTarget, RunBlobId, + AutomationRef, BlobHash, DiffSummary, ForkSourceRef, GitContext, Graph, PairId, PairTarget, RunControlAction, RunFailure, RunId, RunProvenance, RunTiming, WorkflowSettings, }; @@ -27,7 +27,7 @@ pub struct RunCreatedProps { pub automation: Option, pub provenance: RunProvenance, #[serde(default, skip_serializing_if = "Option::is_none")] - pub manifest_blob: Option, + pub manifest_blob: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub git: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -132,7 +132,7 @@ pub struct RunPairFailedProps { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct RunSubmittedProps { #[serde(default, skip_serializing_if = "Option::is_none")] - pub definition_blob: Option, + pub definition_blob: Option, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] diff --git a/lib/foundation/fabro-types/src/run_projection.rs b/lib/foundation/fabro-types/src/run_projection.rs index 3a6be70d4..d41258298 100644 --- a/lib/foundation/fabro-types/src/run_projection.rs +++ b/lib/foundation/fabro-types/src/run_projection.rs @@ -1061,11 +1061,9 @@ impl RunProjection { #[cfg(test)] mod title_tests { - use std::collections::HashMap; - use chrono::Utc; - use crate::{AttrValue, Graph, RunId, RunProjection, RunSpec, WorkflowSettings, test_support}; + use crate::{AttrValue, Graph, RunProjection, RunSpec, test_support}; fn projection_with_goal(goal: Option<&str>) -> RunProjection { let mut graph = Graph::new("test"); @@ -1076,19 +1074,8 @@ mod title_tests { } let spec = RunSpec { - run_id: RunId::new(), - settings: WorkflowSettings::default(), graph, - graph_source: None, - workflow_slug: None, - automation: None, - source_directory: None, - labels: HashMap::new(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: None, - fork_source_ref: None, + ..test_support::test_run_spec() }; RunProjection::new(String::new(), spec, Utc::now()) } @@ -1129,7 +1116,6 @@ mod title_tests { #[cfg(test)] mod iter_stages_tests { - use std::collections::HashMap; use std::num::NonZeroU32; use chrono::Utc; @@ -1137,10 +1123,7 @@ mod iter_stages_tests { use serde_json::json; use super::RunProjection; - use crate::{ - AgentControlState, BilledTokenCounts, Graph, RunId, RunSpec, StageProjection, - WorkflowSettings, test_support, - }; + use crate::{AgentControlState, BilledTokenCounts, StageProjection, test_support}; fn seq(n: u32) -> NonZeroU32 { NonZeroU32::new(n).unwrap() @@ -1149,21 +1132,7 @@ mod iter_stages_tests { fn projection() -> RunProjection { RunProjection::new( "Test run".to_string(), - RunSpec { - run_id: RunId::new(), - settings: WorkflowSettings::default(), - graph: Graph::new("test"), - graph_source: None, - workflow_slug: None, - automation: None, - source_directory: None, - labels: HashMap::default(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: None, - fork_source_ref: None, - }, + test_support::test_run_spec(), Utc::now(), ) } @@ -1336,14 +1305,12 @@ mod iter_stages_tests { #[cfg(test)] mod live_timing_tests { - use std::collections::HashMap; - use chrono::{DateTime, TimeZone, Utc}; use super::{RunProjection, StageToolBatchProjection}; use crate::{ - Graph, ModelRef, RunId, RunSpec, StageHandler, StageInferenceProjection, StageProjection, - StageState, StageTiming, StartRecord, WorkflowSettings, first_event_seq, test_support, + ModelRef, StageHandler, StageInferenceProjection, StageProjection, StageState, StageTiming, + StartRecord, first_event_seq, test_support, }; fn at(seconds: i64) -> DateTime { @@ -1351,25 +1318,7 @@ mod live_timing_tests { } fn projection() -> RunProjection { - RunProjection::new( - "Test run".to_string(), - RunSpec { - run_id: RunId::new(), - settings: WorkflowSettings::default(), - graph: Graph::new("test"), - graph_source: None, - workflow_slug: None, - automation: None, - source_directory: None, - labels: HashMap::default(), - provenance: test_support::test_run_provenance(), - manifest_blob: None, - definition_blob: None, - git: None, - fork_source_ref: None, - }, - at(0), - ) + RunProjection::new("Test run".to_string(), test_support::test_run_spec(), at(0)) } /// In-flight stage that started at `at(0)`. diff --git a/lib/foundation/fabro-types/src/test_support.rs b/lib/foundation/fabro-types/src/test_support.rs index 994813974..b00e792b8 100644 --- a/lib/foundation/fabro-types/src/test_support.rs +++ b/lib/foundation/fabro-types/src/test_support.rs @@ -1,4 +1,8 @@ -use crate::{AuthMethod, IdpIdentity, Principal, RunProvenance}; +use std::collections::HashMap; + +use crate::{ + AuthMethod, Graph, IdpIdentity, Principal, RunProvenance, RunSpec, WorkflowSettings, fixtures, +}; #[must_use] pub fn test_principal() -> Principal { @@ -17,3 +21,35 @@ pub fn test_run_provenance() -> RunProvenance { subject: test_principal(), } } + +/// Neutral [`RunSpec`] for tests: a fixed run id, default settings, a minimal +/// `test` graph, and every optional field unset. +/// +/// Spread it so a test only spells out the fields it actually asserts on: +/// +/// ``` +/// # use fabro_types::{RunSpec, test_support}; +/// let spec = RunSpec { +/// workflow_slug: Some("release-flow".to_string()), +/// ..test_support::test_run_spec() +/// }; +/// # assert_eq!(spec.workflow_slug.as_deref(), Some("release-flow")); +/// ``` +#[must_use] +pub fn test_run_spec() -> RunSpec { + RunSpec { + run_id: fixtures::RUN_1, + settings: WorkflowSettings::default(), + graph: Graph::new("test"), + graph_source: None, + workflow_slug: None, + automation: None, + source_directory: None, + labels: HashMap::new(), + provenance: test_run_provenance(), + manifest_blob: None, + definition_blob: None, + git: None, + fork_source_ref: None, + } +} diff --git a/lib/foundation/fabro-types/src/workflow_path.rs b/lib/foundation/fabro-types/src/workflow_path.rs new file mode 100644 index 000000000..a489153a9 --- /dev/null +++ b/lib/foundation/fabro-types/src/workflow_path.rs @@ -0,0 +1,280 @@ +use std::fmt; +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +pub const MAX_WORKFLOW_PATH_BYTES: usize = 240; +pub const MAX_WORKFLOW_PATH_COMPONENTS: usize = 16; + +#[derive(Clone, Debug, PartialEq, Eq, Error)] +#[error("invalid workflow path `{value}`: {reason}")] +pub struct WorkflowPathParseError { + value: String, + reason: &'static str, +} + +impl WorkflowPathParseError { + fn new(value: &str, reason: &'static str) -> Self { + Self { + value: value.to_owned(), + reason, + } + } + + #[must_use] + pub fn value(&self) -> &str { + &self.value + } + + #[must_use] + pub fn reason(&self) -> &'static str { + self.reason + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[serde(into = "String", try_from = "String")] +pub struct WorkflowPath(String); + +impl WorkflowPath { + pub fn new(value: impl Into) -> Result { + let value = value.into(); + validate(&value)?; + Ok(Self(value)) + } + + #[must_use] + pub fn as_str(&self) -> &str { + &self.0 + } + + pub fn resolve_reference(&self, reference: &str) -> Result { + validate_reference_shape(reference)?; + let mut components = self + .0 + .rsplit_once('/') + .map_or_else(Vec::new, |(parent, _)| { + parent.split('/').collect::>() + }); + + for component in reference.split('/') { + match component { + "" | "." => {} + ".." => { + if components.pop().is_none() { + return Err(WorkflowPathParseError::new( + reference, + "reference escapes the workflow root", + )); + } + } + value => components.push(value), + } + } + + Self::new(components.join("/")) + } +} + +impl FromStr for WorkflowPath { + type Err = WorkflowPathParseError; + + fn from_str(value: &str) -> Result { + Self::new(value) + } +} + +impl TryFrom for WorkflowPath { + type Error = WorkflowPathParseError; + + fn try_from(value: String) -> Result { + Self::new(value) + } +} + +impl From for String { + fn from(value: WorkflowPath) -> Self { + value.0 + } +} + +impl fmt::Display for WorkflowPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&self.0) + } +} + +fn validate(value: &str) -> Result<(), WorkflowPathParseError> { + validate_reference_shape(value)?; + if value + .split('/') + .any(|component| matches!(component, "." | "..")) + { + return Err(WorkflowPathParseError::new( + value, + "dot segments are not allowed in stored paths", + )); + } + if value.split('/').count() > MAX_WORKFLOW_PATH_COMPONENTS { + return Err(WorkflowPathParseError::new( + value, + "path has too many components", + )); + } + if value.len() > MAX_WORKFLOW_PATH_BYTES { + return Err(WorkflowPathParseError::new(value, "path is too long")); + } + Ok(()) +} + +fn validate_reference_shape(value: &str) -> Result<(), WorkflowPathParseError> { + if value.is_empty() { + return Err(WorkflowPathParseError::new(value, "path is empty")); + } + if value.starts_with('/') { + return Err(WorkflowPathParseError::new( + value, + "absolute paths are not allowed", + )); + } + if value.starts_with('~') { + return Err(WorkflowPathParseError::new( + value, + "tilde-prefixed paths are not allowed", + )); + } + if value.contains('\\') { + return Err(WorkflowPathParseError::new( + value, + "backslashes are not allowed", + )); + } + if value.ends_with('/') { + return Err(WorkflowPathParseError::new( + value, + "trailing slashes are not allowed", + )); + } + if value.contains("//") { + return Err(WorkflowPathParseError::new( + value, + "repeated slashes are not allowed", + )); + } + let bytes = value.as_bytes(); + if bytes.len() >= 2 && bytes[0].is_ascii_alphabetic() && bytes[1] == b':' { + return Err(WorkflowPathParseError::new( + value, + "Windows drive paths are not allowed", + )); + } + if value.bytes().any(|byte| byte.is_ascii_control()) { + return Err(WorkflowPathParseError::new( + value, + "control characters are not allowed", + )); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + + use serde_json::json; + + use super::{MAX_WORKFLOW_PATH_BYTES, MAX_WORKFLOW_PATH_COMPONENTS, WorkflowPath}; + + #[test] + fn accepts_canonical_portable_paths() { + for value in ["workflow.fabro", "graphs/main.fabro", "prompts/日本語.md"] { + let path: WorkflowPath = value.parse().expect("path should parse"); + assert_eq!(path.as_str(), value); + } + } + + #[test] + fn rejects_non_canonical_or_unsafe_paths() { + for value in [ + "", "/root", "root/", "a//b", "a\\b", "~/a", "C:/a", ".", "..", "a/./b", "a/../b", + "a\nb", + ] { + assert!(value.parse::().is_err(), "accepted {value:?}"); + } + } + + #[test] + fn enforces_byte_and_component_limits() { + assert!( + "a".repeat(MAX_WORKFLOW_PATH_BYTES) + .parse::() + .is_ok() + ); + assert!( + "a".repeat(MAX_WORKFLOW_PATH_BYTES + 1) + .parse::() + .is_err() + ); + assert!( + vec!["a"; MAX_WORKFLOW_PATH_COMPONENTS] + .join("/") + .parse::() + .is_ok() + ); + assert!( + vec!["a"; MAX_WORKFLOW_PATH_COMPONENTS + 1] + .join("/") + .parse::() + .is_err() + ); + } + + #[test] + fn resolves_references_without_escaping_root() { + let graph: WorkflowPath = "graphs/nested/main.fabro".parse().unwrap(); + assert_eq!( + graph.resolve_reference("../prompts/plan.md").unwrap(), + "graphs/prompts/plan.md".parse().unwrap() + ); + assert!(graph.resolve_reference("../../../outside.md").is_err()); + assert!(graph.resolve_reference("prompts//plan.md").is_err()); + assert!(graph.resolve_reference("prompts/").is_err()); + } + + #[test] + fn serde_and_ordered_map_keys_preserve_canonical_text() { + let paths = BTreeMap::from([ + ("z/last.md".parse::().unwrap(), 2), + ("a/first.md".parse::().unwrap(), 1), + ]); + + assert_eq!( + serde_json::to_value(&paths).unwrap(), + json!({"a/first.md": 1, "z/last.md": 2}) + ); + assert_eq!( + serde_json::from_value::>(json!({ + "a/first.md": 1, + "z/last.md": 2 + })) + .unwrap(), + paths + ); + } + + #[test] + fn byte_limit_counts_utf8_bytes() { + assert!( + "é".repeat(MAX_WORKFLOW_PATH_BYTES / 2) + .parse::() + .is_ok() + ); + assert!( + "é".repeat(MAX_WORKFLOW_PATH_BYTES / 2 + 1) + .parse::() + .is_err() + ); + assert!("notes/\u{85}.md".parse::().is_ok()); + } +} diff --git a/lib/foundation/fabro-types/src/workflow_version.rs b/lib/foundation/fabro-types/src/workflow_version.rs new file mode 100644 index 000000000..cba3a04c1 --- /dev/null +++ b/lib/foundation/fabro-types/src/workflow_version.rs @@ -0,0 +1,495 @@ +use std::collections::{BTreeMap, HashMap}; +use std::fmt; +use std::marker::PhantomData; + +use serde::de::{Error as _, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use thiserror::Error; + +use crate::{WorkflowPath, WorkflowVersionId}; + +pub const MAX_WORKFLOW_VERSION_FILES: usize = 512; +pub const MAX_WORKFLOW_VERSION_DEPENDENCIES: usize = 512; +pub const MAX_WORKFLOW_VERSION_FILE_BYTES: usize = 512 * 1024; +pub const MAX_WORKFLOW_VERSION_BYTES: usize = 2 * 1024 * 1024; + +#[derive(Debug, Error)] +pub enum WorkflowVersionShapeError { + #[error("workflow version has {actual} files; maximum is {maximum}")] + TooManyFiles { actual: usize, maximum: usize }, + #[error("workflow version has {actual} workflow dependencies; maximum is {maximum}")] + TooManyWorkflowDependencies { actual: usize, maximum: usize }, + #[error("workflow file `{path}` is {actual} bytes; maximum is {maximum}")] + FileTooLarge { + path: WorkflowPath, + actual: usize, + maximum: usize, + }, + #[error("workflow version is {actual} canonical bytes; maximum is {maximum}")] + VersionTooLarge { actual: usize, maximum: usize }, + #[error("entrypoint `{path}` is not present in workflow files")] + MissingEntrypoint { path: WorkflowPath }, + #[error("workflow paths collide: `{first}` and `{second}`")] + PathCollision { + first: WorkflowPath, + second: WorkflowPath, + }, + #[error("failed to serialize canonical workflow version")] + Serialization { + #[source] + source: serde_json::Error, + }, +} + +/// Canonical wire form of an immutable workflow version. +/// +/// Construction (and therefore deserialization) enforces the structural +/// invariants: file-count and byte-size limits, entrypoint presence, unique +/// map keys, and collision-free paths. Semantic validation of graph, config, +/// and template content is a separate concern owned by +/// `fabro-workflow-version`. +#[derive(Clone, Debug, PartialEq, Eq, Serialize)] +pub struct WorkflowVersion { + entrypoint: WorkflowPath, + files: BTreeMap, + workflow_dependencies: BTreeMap, +} + +impl WorkflowVersion { + pub fn new( + entrypoint: WorkflowPath, + files: BTreeMap, + workflow_dependencies: BTreeMap, + ) -> Result { + let version = Self { + entrypoint, + files, + workflow_dependencies, + }; + version.validate_shape()?; + version.canonical_bytes()?; + Ok(version) + } + + #[must_use] + pub fn entrypoint(&self) -> &WorkflowPath { + &self.entrypoint + } + + #[must_use] + pub fn files(&self) -> &BTreeMap { + &self.files + } + + #[must_use] + pub fn workflow_dependencies(&self) -> &BTreeMap { + &self.workflow_dependencies + } + + /// Serialize to the canonical wire form. + /// + /// Structural validity is guaranteed by construction, so this only + /// serializes and enforces the canonical size limit. + pub fn canonical_bytes(&self) -> Result, WorkflowVersionShapeError> { + let bytes = serde_json::to_vec(self) + .map_err(|source| WorkflowVersionShapeError::Serialization { source })?; + if bytes.len() > MAX_WORKFLOW_VERSION_BYTES { + return Err(WorkflowVersionShapeError::VersionTooLarge { + actual: bytes.len(), + maximum: MAX_WORKFLOW_VERSION_BYTES, + }); + } + Ok(bytes) + } + + fn validate_shape(&self) -> Result<(), WorkflowVersionShapeError> { + if self.files.len() > MAX_WORKFLOW_VERSION_FILES { + return Err(WorkflowVersionShapeError::TooManyFiles { + actual: self.files.len(), + maximum: MAX_WORKFLOW_VERSION_FILES, + }); + } + if self.workflow_dependencies.len() > MAX_WORKFLOW_VERSION_DEPENDENCIES { + return Err(WorkflowVersionShapeError::TooManyWorkflowDependencies { + actual: self.workflow_dependencies.len(), + maximum: MAX_WORKFLOW_VERSION_DEPENDENCIES, + }); + } + for (path, content) in &self.files { + if content.len() > MAX_WORKFLOW_VERSION_FILE_BYTES { + return Err(WorkflowVersionShapeError::FileTooLarge { + path: path.clone(), + actual: content.len(), + maximum: MAX_WORKFLOW_VERSION_FILE_BYTES, + }); + } + } + if !self.files.contains_key(&self.entrypoint) { + return Err(WorkflowVersionShapeError::MissingEntrypoint { + path: self.entrypoint.clone(), + }); + } + self.validate_path_collisions() + } + + fn validate_path_collisions(&self) -> Result<(), WorkflowVersionShapeError> { + // Keys are unique within each map, so equality can only collide + // across files and workflow dependencies. + let mut by_text = + HashMap::with_capacity(self.files.len() + self.workflow_dependencies.len()); + for path in self.files.keys().chain(self.workflow_dependencies.keys()) { + if let Some(existing) = by_text.insert(path.as_str(), path) { + return Err(WorkflowVersionShapeError::PathCollision { + first: existing.clone(), + second: path.clone(), + }); + } + } + for path in self.files.keys().chain(self.workflow_dependencies.keys()) { + let text = path.as_str(); + for (index, _) in text.match_indices('/') { + if let Some(ancestor) = by_text.get(&text[..index]) { + return Err(WorkflowVersionShapeError::PathCollision { + first: (*ancestor).clone(), + second: path.clone(), + }); + } + } + } + Ok(()) + } +} + +impl<'de> Deserialize<'de> for WorkflowVersion { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(deny_unknown_fields)] + struct Wire { + entrypoint: WorkflowPath, + files: UniqueBTreeMap, + workflow_dependencies: UniqueBTreeMap, + } + + let wire = Wire::deserialize(deserializer)?; + Self::new(wire.entrypoint, wire.files.0, wire.workflow_dependencies.0) + .map_err(D::Error::custom) + } +} + +struct UniqueBTreeMap(BTreeMap); + +impl<'de, K, V> Deserialize<'de> for UniqueBTreeMap +where + K: Deserialize<'de> + Ord + fmt::Display, + V: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct MapVisitor(PhantomData<(K, V)>); + + impl<'de, K, V> Visitor<'de> for MapVisitor + where + K: Deserialize<'de> + Ord + fmt::Display, + V: Deserialize<'de>, + { + type Value = UniqueBTreeMap; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a map with unique keys") + } + + fn visit_map(self, mut access: A) -> Result + where + A: MapAccess<'de>, + { + let mut values = BTreeMap::new(); + while let Some((key, value)) = access.next_entry::()? { + if values.insert(key, value).is_some() { + return Err(A::Error::custom("duplicate workflow map key")); + } + } + Ok(UniqueBTreeMap(values)) + } + } + + deserializer.deserialize_map(MapVisitor(PhantomData)) + } +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + + use super::{ + MAX_WORKFLOW_VERSION_BYTES, MAX_WORKFLOW_VERSION_DEPENDENCIES, + MAX_WORKFLOW_VERSION_FILE_BYTES, MAX_WORKFLOW_VERSION_FILES, WorkflowVersion, + WorkflowVersionShapeError, + }; + use crate::{BlobHash, WorkflowPath, WorkflowVersionId}; + + fn path(value: &str) -> WorkflowPath { + value.parse().unwrap() + } + + #[test] + fn canonical_bytes_have_fixed_field_and_map_order() { + let version = WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([ + (path("z.txt"), "Z".to_string()), + (path("workflow.fabro"), "digraph W {}".to_string()), + (path("a.txt"), "A".to_string()), + ]), + BTreeMap::new(), + ) + .unwrap(); + + assert_eq!( + String::from_utf8(version.canonical_bytes().unwrap()).unwrap(), + r#"{"entrypoint":"workflow.fabro","files":{"a.txt":"A","workflow.fabro":"digraph W {}","z.txt":"Z"},"workflow_dependencies":{}}"# + ); + } + + #[test] + fn rejects_missing_entrypoint() { + let error = WorkflowVersion::new( + path("missing.fabro"), + BTreeMap::from([(path("workflow.fabro"), "digraph W {}".to_string())]), + BTreeMap::new(), + ) + .unwrap_err(); + assert!(matches!( + error, + WorkflowVersionShapeError::MissingEntrypoint { .. } + )); + } + + #[test] + fn rejects_path_collisions_and_large_files() { + let collision = WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([ + (path("workflow.fabro"), "digraph W {}".to_string()), + (path("assets"), "file".to_string()), + (path("assets/item.txt"), "nested".to_string()), + ]), + BTreeMap::new(), + ) + .unwrap_err(); + assert!(matches!( + collision, + WorkflowVersionShapeError::PathCollision { .. } + )); + + let mut files = BTreeMap::from([(path("workflow.fabro"), "digraph W {}".to_string())]); + files.insert( + path("large.txt"), + "x".repeat(MAX_WORKFLOW_VERSION_FILE_BYTES + 1), + ); + let large = + WorkflowVersion::new(path("workflow.fabro"), files, BTreeMap::new()).unwrap_err(); + assert!(matches!( + large, + WorkflowVersionShapeError::FileTooLarge { .. } + )); + } + + #[test] + fn rejects_ancestor_collisions_hidden_by_sort_order() { + // `assets.txt` sorts between `assets` and `assets/item.txt` because + // '.' precedes '/', so an adjacent-pair scan over the sorted list + // would miss this collision. + let error = WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([ + (path("workflow.fabro"), "digraph W {}".to_string()), + (path("assets"), "file".to_string()), + (path("assets.txt"), "sibling".to_string()), + (path("assets/item.txt"), "nested".to_string()), + ]), + BTreeMap::new(), + ) + .unwrap_err(); + assert!(matches!( + error, + WorkflowVersionShapeError::PathCollision { first, second } + if first.as_str() == "assets" && second.as_str() == "assets/item.txt" + )); + + assert!( + WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([ + (path("workflow.fabro"), "digraph W {}".to_string()), + (path("assets.txt"), "sibling".to_string()), + (path("assets/item.txt"), "nested".to_string()), + ]), + BTreeMap::new(), + ) + .is_ok() + ); + } + + #[test] + fn rejects_collisions_across_files_and_workflow_dependencies() { + let dependency_id = WorkflowVersionId::from(BlobHash::new(b"child")); + + let equal = WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([ + (path("workflow.fabro"), "digraph W {}".to_string()), + (path("child.fabro"), "digraph C {}".to_string()), + ]), + BTreeMap::from([(path("child.fabro"), dependency_id)]), + ) + .unwrap_err(); + assert!(matches!( + equal, + WorkflowVersionShapeError::PathCollision { first, second } + if first == second && first.as_str() == "child.fabro" + )); + + let ancestor = WorkflowVersion::new( + path("workflow.fabro"), + BTreeMap::from([ + (path("workflow.fabro"), "digraph W {}".to_string()), + (path("libs"), "file".to_string()), + (path("libs.md"), "sibling".to_string()), + ]), + BTreeMap::from([(path("libs/child.fabro"), dependency_id)]), + ) + .unwrap_err(); + assert!(matches!( + ancestor, + WorkflowVersionShapeError::PathCollision { first, second } + if first.as_str() == "libs" && second.as_str() == "libs/child.fabro" + )); + } + + #[test] + fn enforces_file_count_file_size_and_canonical_size_boundaries() { + let mut files = BTreeMap::from([(path("workflow.fabro"), "digraph W {}".to_string())]); + for index in 0..MAX_WORKFLOW_VERSION_FILES - 1 { + files.insert(path(&format!("file-{index:03}.txt")), String::new()); + } + assert!( + WorkflowVersion::new(path("workflow.fabro"), files.clone(), BTreeMap::new()).is_ok() + ); + files.insert(path("too-many.txt"), String::new()); + assert!(matches!( + WorkflowVersion::new(path("workflow.fabro"), files, BTreeMap::new()).unwrap_err(), + WorkflowVersionShapeError::TooManyFiles { .. } + )); + + let exact_file = BTreeMap::from([ + (path("workflow.fabro"), "digraph W {}".to_string()), + ( + path("payload.txt"), + "x".repeat(MAX_WORKFLOW_VERSION_FILE_BYTES), + ), + ]); + assert!( + WorkflowVersion::new(path("workflow.fabro"), exact_file.clone(), BTreeMap::new()) + .is_ok() + ); + let mut oversized_file = exact_file; + oversized_file + .get_mut(&path("payload.txt")) + .unwrap() + .push('x'); + assert!(matches!( + WorkflowVersion::new(path("workflow.fabro"), oversized_file, BTreeMap::new()) + .unwrap_err(), + WorkflowVersionShapeError::FileTooLarge { .. } + )); + + let mut exact_version_files = + BTreeMap::from([(path("workflow.fabro"), "digraph W {}".to_string())]); + for index in 0..4 { + exact_version_files.insert(path(&format!("payload-{index}.txt")), String::new()); + } + let empty = WorkflowVersion::new( + path("workflow.fabro"), + exact_version_files.clone(), + BTreeMap::new(), + ) + .unwrap(); + let remaining = MAX_WORKFLOW_VERSION_BYTES - empty.canonical_bytes().unwrap().len(); + let per_file = remaining / 4; + let remainder = remaining % 4; + for index in 0..4 { + let length = per_file + usize::from(index < remainder); + assert!(length <= MAX_WORKFLOW_VERSION_FILE_BYTES); + exact_version_files.insert(path(&format!("payload-{index}.txt")), "x".repeat(length)); + } + let exact_version = WorkflowVersion::new( + path("workflow.fabro"), + exact_version_files.clone(), + BTreeMap::new(), + ) + .unwrap(); + assert_eq!( + exact_version.canonical_bytes().unwrap().len(), + MAX_WORKFLOW_VERSION_BYTES + ); + exact_version_files + .get_mut(&path("payload-0.txt")) + .unwrap() + .push('x'); + assert!(matches!( + WorkflowVersion::new(path("workflow.fabro"), exact_version_files, BTreeMap::new()) + .unwrap_err(), + WorkflowVersionShapeError::VersionTooLarge { .. } + )); + } + + #[test] + fn enforces_workflow_dependency_count_boundary() { + let dependencies = (0..MAX_WORKFLOW_VERSION_DEPENDENCIES) + .map(|index| { + ( + path(&format!("dependency-{index:03}.fabro")), + WorkflowVersionId::from(BlobHash::new(index.to_string().as_bytes())), + ) + }) + .collect::>(); + let files = BTreeMap::from([(path("workflow.fabro"), "digraph W {}".to_owned())]); + assert!( + WorkflowVersion::new(path("workflow.fabro"), files.clone(), dependencies.clone()) + .is_ok() + ); + + let mut oversized = dependencies; + oversized.insert( + path("too-many.fabro"), + WorkflowVersionId::from(BlobHash::new(b"too many")), + ); + assert!(matches!( + WorkflowVersion::new(path("workflow.fabro"), files, oversized).unwrap_err(), + WorkflowVersionShapeError::TooManyWorkflowDependencies { .. } + )); + } + + #[test] + fn deserialize_rejects_unknown_fields_and_duplicate_keys() { + let unknown = r#"{ + "entrypoint":"workflow.fabro", + "files":{"workflow.fabro":"digraph W {}"}, + "workflow_dependencies":{}, + "metadata":{} + }"#; + assert!(serde_json::from_str::(unknown).is_err()); + + let duplicate = r#"{ + "entrypoint":"workflow.fabro", + "files":{"workflow.fabro":"digraph W {}","workflow.fabro":"digraph X {}"}, + "workflow_dependencies":{} + }"#; + assert!(serde_json::from_str::(duplicate).is_err()); + } +} diff --git a/lib/foundation/fabro-types/src/workflow_version_id.rs b/lib/foundation/fabro-types/src/workflow_version_id.rs new file mode 100644 index 000000000..7e19f5333 --- /dev/null +++ b/lib/foundation/fabro-types/src/workflow_version_id.rs @@ -0,0 +1,96 @@ +use std::fmt; +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use crate::BlobHash; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[serde(into = "String", try_from = "String")] +pub struct WorkflowVersionId(BlobHash); + +impl From for WorkflowVersionId { + fn from(value: BlobHash) -> Self { + Self(value) + } +} + +impl From for BlobHash { + fn from(value: WorkflowVersionId) -> Self { + value.0 + } +} + +impl fmt::Display for WorkflowVersionId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.0, f) + } +} + +impl From for String { + fn from(value: WorkflowVersionId) -> Self { + value.to_string() + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Error)] +#[error("workflow version ID must be exactly 64 hexadecimal characters")] +pub struct WorkflowVersionIdParseError; + +impl FromStr for WorkflowVersionId { + type Err = WorkflowVersionIdParseError; + + fn from_str(value: &str) -> Result { + value + .parse::() + .map(Self) + .map_err(|_| WorkflowVersionIdParseError) + } +} + +impl TryFrom for WorkflowVersionId { + type Error = WorkflowVersionIdParseError; + + fn try_from(value: String) -> Result { + value.parse() + } +} + +#[cfg(test)] +mod tests { + use crate::{BlobHash, WorkflowVersionId}; + + #[test] + fn conversion_preserves_digest_and_display() { + let blob_hash = BlobHash::new(b"workflow"); + let version_id = WorkflowVersionId::from(blob_hash); + assert_eq!(version_id.to_string(), blob_hash.to_string()); + assert_eq!(BlobHash::from(version_id), blob_hash); + } + + #[test] + fn parse_accepts_any_case_and_serializes_lowercase() { + let value = BlobHash::new(b"workflow").to_string(); + let id: WorkflowVersionId = value.parse().unwrap(); + assert_eq!(serde_json::to_value(id).unwrap(), value); + assert_eq!( + value.to_uppercase().parse::().unwrap(), + id + ); + for invalid in [ + String::new(), + "0".repeat(63), + "0".repeat(65), + "g".repeat(64), + ] { + assert!(invalid.parse::().is_err()); + } + assert_eq!( + serde_json::from_value::(serde_json::json!(value.to_uppercase())) + .unwrap() + .to_string(), + value + ); + } +} diff --git a/lib/foundation/fabro-types/tests/run_spec_methods.rs b/lib/foundation/fabro-types/tests/run_spec_methods.rs index f6f76fecf..6f6aefaaf 100644 --- a/lib/foundation/fabro-types/tests/run_spec_methods.rs +++ b/lib/foundation/fabro-types/tests/run_spec_methods.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use fabro_types::graph::Graph; use fabro_types::run::{DirtyStatus, GitContext, RunSpec}; use fabro_types::settings::{ProjectNamespace, WorkflowNamespace}; -use fabro_types::test_support::test_run_provenance; +use fabro_types::test_support::test_run_spec; use fabro_types::{WorkflowSettings, fixtures}; fn sample_run_spec() -> RunSpec { @@ -20,24 +20,18 @@ fn sample_run_spec() -> RunSpec { }; RunSpec { - run_id: fixtures::RUN_1, settings, graph: Graph::new("ship"), - graph_source: None, workflow_slug: Some("demo".to_string()), - automation: None, source_directory: Some("/Users/client/project".to_string()), labels: HashMap::from([("team".to_string(), "platform".to_string())]), - provenance: test_run_provenance(), - manifest_blob: None, - definition_blob: None, git: Some(GitContext { origin_url: "https://github.com/fabro-sh/fabro.git".to_string(), branch: "main".to_string(), sha: Some("abc123".to_string()), dirty: DirtyStatus::Dirty, }), - fork_source_ref: None, + ..test_run_spec() } } diff --git a/lib/packages/fabro-api-client/src/.openapi-generator/FILES b/lib/packages/fabro-api-client/src/.openapi-generator/FILES index 4f99a6d3d..4f8d5f871 100644 --- a/lib/packages/fabro-api-client/src/.openapi-generator/FILES +++ b/lib/packages/fabro-api-client/src/.openapi-generator/FILES @@ -22,6 +22,7 @@ api/sessions-api.ts api/settings-api.ts api/system-api.ts api/variables-api.ts +api/workflow-versions-api.ts api/workflows-api.ts base.ts common.ts @@ -105,6 +106,7 @@ models/create-run-pull-request-request.ts models/create-run-session-request.ts models/create-secret-request.ts models/create-variable-request.ts +models/create-workflow-version-response.ts models/delete-run-response.ts models/delete-run-sandbox.ts models/delete-secret-request.ts @@ -541,4 +543,5 @@ models/workflow-ref.ts models/workflow-reference.ts models/workflow-schedule-summary.ts models/workflow-settings.ts +models/workflow-version.ts models/write-blob-response.ts diff --git a/lib/packages/fabro-api-client/src/api.ts b/lib/packages/fabro-api-client/src/api.ts index 02fa11e7b..b7f58f486 100644 --- a/lib/packages/fabro-api-client/src/api.ts +++ b/lib/packages/fabro-api-client/src/api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -37,4 +37,5 @@ export * from './api/sessions-api'; export * from './api/settings-api'; export * from './api/system-api'; export * from './api/variables-api'; +export * from './api/workflow-versions-api'; export * from './api/workflows-api'; diff --git a/lib/packages/fabro-api-client/src/api/auth-api.ts b/lib/packages/fabro-api-client/src/api/auth-api.ts index e0bd4a9c7..9cb22e4c9 100644 --- a/lib/packages/fabro-api-client/src/api/auth-api.ts +++ b/lib/packages/fabro-api-client/src/api/auth-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/automations-api.ts b/lib/packages/fabro-api-client/src/api/automations-api.ts index 832fa0665..686aef151 100644 --- a/lib/packages/fabro-api-client/src/api/automations-api.ts +++ b/lib/packages/fabro-api-client/src/api/automations-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/billing-api.ts b/lib/packages/fabro-api-client/src/api/billing-api.ts index 31e957bba..93893cf1e 100644 --- a/lib/packages/fabro-api-client/src/api/billing-api.ts +++ b/lib/packages/fabro-api-client/src/api/billing-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/completions-api.ts b/lib/packages/fabro-api-client/src/api/completions-api.ts index 677344d43..e4cb58fd4 100644 --- a/lib/packages/fabro-api-client/src/api/completions-api.ts +++ b/lib/packages/fabro-api-client/src/api/completions-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/discovery-api.ts b/lib/packages/fabro-api-client/src/api/discovery-api.ts index dab8fa6d9..f14061c06 100644 --- a/lib/packages/fabro-api-client/src/api/discovery-api.ts +++ b/lib/packages/fabro-api-client/src/api/discovery-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/environments-api.ts b/lib/packages/fabro-api-client/src/api/environments-api.ts index 6fbcd086e..b458e7501 100644 --- a/lib/packages/fabro-api-client/src/api/environments-api.ts +++ b/lib/packages/fabro-api-client/src/api/environments-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/human-in-the-loop-api.ts b/lib/packages/fabro-api-client/src/api/human-in-the-loop-api.ts index 189517deb..32b365ac2 100644 --- a/lib/packages/fabro-api-client/src/api/human-in-the-loop-api.ts +++ b/lib/packages/fabro-api-client/src/api/human-in-the-loop-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/insights-api.ts b/lib/packages/fabro-api-client/src/api/insights-api.ts index 0361ca0f6..a4ef749dd 100644 --- a/lib/packages/fabro-api-client/src/api/insights-api.ts +++ b/lib/packages/fabro-api-client/src/api/insights-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/install-api.ts b/lib/packages/fabro-api-client/src/api/install-api.ts index 3ba0e29cb..6f1fb0d3a 100644 --- a/lib/packages/fabro-api-client/src/api/install-api.ts +++ b/lib/packages/fabro-api-client/src/api/install-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/integrations-api.ts b/lib/packages/fabro-api-client/src/api/integrations-api.ts index 311da8593..13421515a 100644 --- a/lib/packages/fabro-api-client/src/api/integrations-api.ts +++ b/lib/packages/fabro-api-client/src/api/integrations-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/mcpservers-api.ts b/lib/packages/fabro-api-client/src/api/mcpservers-api.ts index f72066148..23cb3d716 100644 --- a/lib/packages/fabro-api-client/src/api/mcpservers-api.ts +++ b/lib/packages/fabro-api-client/src/api/mcpservers-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/models-api.ts b/lib/packages/fabro-api-client/src/api/models-api.ts index 03a90fac4..f2662fe2b 100644 --- a/lib/packages/fabro-api-client/src/api/models-api.ts +++ b/lib/packages/fabro-api-client/src/api/models-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/playground-api.ts b/lib/packages/fabro-api-client/src/api/playground-api.ts index c6843ab4f..acd6dfb6b 100644 --- a/lib/packages/fabro-api-client/src/api/playground-api.ts +++ b/lib/packages/fabro-api-client/src/api/playground-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/repos-api.ts b/lib/packages/fabro-api-client/src/api/repos-api.ts index f56f69caf..2b95ee7e0 100644 --- a/lib/packages/fabro-api-client/src/api/repos-api.ts +++ b/lib/packages/fabro-api-client/src/api/repos-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/run-internals-api.ts b/lib/packages/fabro-api-client/src/api/run-internals-api.ts index 403e2eb05..771501839 100644 --- a/lib/packages/fabro-api-client/src/api/run-internals-api.ts +++ b/lib/packages/fabro-api-client/src/api/run-internals-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -781,21 +781,21 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config }; }, /** - * Reads a previously stored blob by identifier. + * Reads a previously stored blob by hash. * @summary Read Run Blob * @param {string} id Unique run identifier (ULID). - * @param {string} blobId Content-addressed blob identifier. + * @param {string} blobHash Content-addressed blob hash. * @param {*} [options] Override http request option. * @throws {RequiredError} */ - readRunBlob: async (id: string, blobId: string, options: RawAxiosRequestConfig = {}): Promise => { + readRunBlob: async (id: string, blobHash: string, options: RawAxiosRequestConfig = {}): Promise => { // verify required parameter 'id' is not null or undefined assertParamExists('readRunBlob', 'id', id) - // verify required parameter 'blobId' is not null or undefined - assertParamExists('readRunBlob', 'blobId', blobId) - const localVarPath = `/api/v1/runs/{id}/blobs/{blobId}` + // verify required parameter 'blobHash' is not null or undefined + assertParamExists('readRunBlob', 'blobHash', blobHash) + const localVarPath = `/api/v1/runs/{id}/blobs/{blobHash}` .replace(`{${"id"}}`, encodeURIComponent(String(id))) - .replace(`{${"blobId"}}`, encodeURIComponent(String(blobId))); + .replace(`{${"blobHash"}}`, encodeURIComponent(String(blobHash))); // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); let baseOptions; @@ -905,7 +905,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config }; }, /** - * Writes an opaque binary blob and returns its content-addressed blob identifier. + * Writes an opaque binary blob and returns its content-addressed blob hash. * @summary Write Run Blob * @param {string} id Unique run identifier (ULID). * @param {File} body @@ -1179,15 +1179,15 @@ export const RunInternalsApiFp = function(configuration?: Configuration) { return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, /** - * Reads a previously stored blob by identifier. + * Reads a previously stored blob by hash. * @summary Read Run Blob * @param {string} id Unique run identifier (ULID). - * @param {string} blobId Content-addressed blob identifier. + * @param {string} blobHash Content-addressed blob hash. * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async readRunBlob(id: string, blobId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.readRunBlob(id, blobId, options); + async readRunBlob(id: string, blobHash: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.readRunBlob(id, blobHash, options); const localVarOperationServerIndex = configuration?.serverIndex ?? 0; const localVarOperationServerBasePath = operationServerMap['RunInternalsApi.readRunBlob']?.[localVarOperationServerIndex]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); @@ -1219,7 +1219,7 @@ export const RunInternalsApiFp = function(configuration?: Configuration) { return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, /** - * Writes an opaque binary blob and returns its content-addressed blob identifier. + * Writes an opaque binary blob and returns its content-addressed blob hash. * @summary Write Run Blob * @param {string} id Unique run identifier (ULID). * @param {File} body @@ -1417,15 +1417,15 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b return localVarFp.putStageArtifact(id, stageId, retry, body, filename, options).then((request) => request(axios, basePath)); }, /** - * Reads a previously stored blob by identifier. + * Reads a previously stored blob by hash. * @summary Read Run Blob * @param {string} id Unique run identifier (ULID). - * @param {string} blobId Content-addressed blob identifier. + * @param {string} blobHash Content-addressed blob hash. * @param {*} [options] Override http request option. * @throws {RequiredError} */ - readRunBlob(id: string, blobId: string, options?: RawAxiosRequestConfig): AxiosPromise { - return localVarFp.readRunBlob(id, blobId, options).then((request) => request(axios, basePath)); + readRunBlob(id: string, blobHash: string, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.readRunBlob(id, blobHash, options).then((request) => request(axios, basePath)); }, /** * Returns the latest checkpoint data for a run, or null if no checkpoint has been recorded yet. @@ -1448,7 +1448,7 @@ export const RunInternalsApiFactory = function (configuration?: Configuration, b return localVarFp.retrieveRunSettings(id, options).then((request) => request(axios, basePath)); }, /** - * Writes an opaque binary blob and returns its content-addressed blob identifier. + * Writes an opaque binary blob and returns its content-addressed blob hash. * @summary Write Run Blob * @param {string} id Unique run identifier (ULID). * @param {File} body @@ -1656,15 +1656,15 @@ export class RunInternalsApi extends BaseAPI { } /** - * Reads a previously stored blob by identifier. + * Reads a previously stored blob by hash. * @summary Read Run Blob * @param {string} id Unique run identifier (ULID). - * @param {string} blobId Content-addressed blob identifier. + * @param {string} blobHash Content-addressed blob hash. * @param {*} [options] Override http request option. * @throws {RequiredError} */ - public readRunBlob(id: string, blobId: string, options?: RawAxiosRequestConfig) { - return RunInternalsApiFp(this.configuration).readRunBlob(id, blobId, options).then((request) => request(this.axios, this.basePath)); + public readRunBlob(id: string, blobHash: string, options?: RawAxiosRequestConfig) { + return RunInternalsApiFp(this.configuration).readRunBlob(id, blobHash, options).then((request) => request(this.axios, this.basePath)); } /** @@ -1690,7 +1690,7 @@ export class RunInternalsApi extends BaseAPI { } /** - * Writes an opaque binary blob and returns its content-addressed blob identifier. + * Writes an opaque binary blob and returns its content-addressed blob hash. * @summary Write Run Blob * @param {string} id Unique run identifier (ULID). * @param {File} body diff --git a/lib/packages/fabro-api-client/src/api/run-outputs-api.ts b/lib/packages/fabro-api-client/src/api/run-outputs-api.ts index ca9c328db..65014bf61 100644 --- a/lib/packages/fabro-api-client/src/api/run-outputs-api.ts +++ b/lib/packages/fabro-api-client/src/api/run-outputs-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/runs-api.ts b/lib/packages/fabro-api-client/src/api/runs-api.ts index e3d936afe..f61c0fe8f 100644 --- a/lib/packages/fabro-api-client/src/api/runs-api.ts +++ b/lib/packages/fabro-api-client/src/api/runs-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/sandboxes-api.ts b/lib/packages/fabro-api-client/src/api/sandboxes-api.ts index 87ddcd56a..35dd77d55 100644 --- a/lib/packages/fabro-api-client/src/api/sandboxes-api.ts +++ b/lib/packages/fabro-api-client/src/api/sandboxes-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/secrets-api.ts b/lib/packages/fabro-api-client/src/api/secrets-api.ts index a22887e1a..56df87983 100644 --- a/lib/packages/fabro-api-client/src/api/secrets-api.ts +++ b/lib/packages/fabro-api-client/src/api/secrets-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/sessions-api.ts b/lib/packages/fabro-api-client/src/api/sessions-api.ts index 904647177..8cf90dddc 100644 --- a/lib/packages/fabro-api-client/src/api/sessions-api.ts +++ b/lib/packages/fabro-api-client/src/api/sessions-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/settings-api.ts b/lib/packages/fabro-api-client/src/api/settings-api.ts index 90d83487f..de280fc1a 100644 --- a/lib/packages/fabro-api-client/src/api/settings-api.ts +++ b/lib/packages/fabro-api-client/src/api/settings-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/system-api.ts b/lib/packages/fabro-api-client/src/api/system-api.ts index 4b9efebd8..e6a51a4a1 100644 --- a/lib/packages/fabro-api-client/src/api/system-api.ts +++ b/lib/packages/fabro-api-client/src/api/system-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/variables-api.ts b/lib/packages/fabro-api-client/src/api/variables-api.ts index 0542e1110..319c75436 100644 --- a/lib/packages/fabro-api-client/src/api/variables-api.ts +++ b/lib/packages/fabro-api-client/src/api/variables-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/api/workflow-versions-api.ts b/lib/packages/fabro-api-client/src/api/workflow-versions-api.ts new file mode 100644 index 000000000..4285c1849 --- /dev/null +++ b/lib/packages/fabro-api-client/src/api/workflow-versions-api.ts @@ -0,0 +1,134 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.2.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from '../configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction, replaceWithSerializableTypeIfNeeded } from '../common'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base'; +// @ts-ignore +import type { CreateWorkflowVersionResponse } from '../models'; +// @ts-ignore +import type { ErrorResponse } from '../models'; +// @ts-ignore +import type { WorkflowVersion } from '../models'; +/** + * WorkflowVersionsApi - axios parameter creator + */ +export const WorkflowVersionsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Validates and stores an immutable workflow package in content-addressed storage. Repeating the same canonical content returns the same identifier. + * @summary Create Workflow Version + * @param {WorkflowVersion} workflowVersion + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createWorkflowVersion: async (workflowVersion: WorkflowVersion, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'workflowVersion' is not null or undefined + assertParamExists('createWorkflowVersion', 'workflowVersion', workflowVersion) + const localVarPath = `/api/v1/workflow-versions`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication SessionCookie required + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(workflowVersion, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * WorkflowVersionsApi - functional programming interface + */ +export const WorkflowVersionsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = WorkflowVersionsApiAxiosParamCreator(configuration) + return { + /** + * Validates and stores an immutable workflow package in content-addressed storage. Repeating the same canonical content returns the same identifier. + * @summary Create Workflow Version + * @param {WorkflowVersion} workflowVersion + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createWorkflowVersion(workflowVersion: WorkflowVersion, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createWorkflowVersion(workflowVersion, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['WorkflowVersionsApi.createWorkflowVersion']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * WorkflowVersionsApi - factory interface + */ +export const WorkflowVersionsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = WorkflowVersionsApiFp(configuration) + return { + /** + * Validates and stores an immutable workflow package in content-addressed storage. Repeating the same canonical content returns the same identifier. + * @summary Create Workflow Version + * @param {WorkflowVersion} workflowVersion + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createWorkflowVersion(workflowVersion: WorkflowVersion, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.createWorkflowVersion(workflowVersion, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * WorkflowVersionsApi - object-oriented interface + */ +export class WorkflowVersionsApi extends BaseAPI { + /** + * Validates and stores an immutable workflow package in content-addressed storage. Repeating the same canonical content returns the same identifier. + * @summary Create Workflow Version + * @param {WorkflowVersion} workflowVersion + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public createWorkflowVersion(workflowVersion: WorkflowVersion, options?: RawAxiosRequestConfig) { + return WorkflowVersionsApiFp(this.configuration).createWorkflowVersion(workflowVersion, options).then((request) => request(this.axios, this.basePath)); + } +} diff --git a/lib/packages/fabro-api-client/src/api/workflows-api.ts b/lib/packages/fabro-api-client/src/api/workflows-api.ts index 2b68507b4..0638ee85a 100644 --- a/lib/packages/fabro-api-client/src/api/workflows-api.ts +++ b/lib/packages/fabro-api-client/src/api/workflows-api.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/base.ts b/lib/packages/fabro-api-client/src/base.ts index f486d5de2..25e65dfe7 100644 --- a/lib/packages/fabro-api-client/src/base.ts +++ b/lib/packages/fabro-api-client/src/base.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/common.ts b/lib/packages/fabro-api-client/src/common.ts index 0a2fab196..2b5be404c 100644 --- a/lib/packages/fabro-api-client/src/common.ts +++ b/lib/packages/fabro-api-client/src/common.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/configuration.ts b/lib/packages/fabro-api-client/src/configuration.ts index b62a5fb52..07b7ae9d0 100644 --- a/lib/packages/fabro-api-client/src/configuration.ts +++ b/lib/packages/fabro-api-client/src/configuration.ts @@ -3,7 +3,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/index.ts b/lib/packages/fabro-api-client/src/index.ts index 64e64478e..c0adbf056 100644 --- a/lib/packages/fabro-api-client/src/index.ts +++ b/lib/packages/fabro-api-client/src/index.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/activated-skill.ts b/lib/packages/fabro-api-client/src/models/activated-skill.ts index 2a8cd0a07..5bc9d5c57 100644 --- a/lib/packages/fabro-api-client/src/models/activated-skill.ts +++ b/lib/packages/fabro-api-client/src/models/activated-skill.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-control-state.ts b/lib/packages/fabro-api-client/src/models/agent-control-state.ts index 821dc97af..91966dbd3 100644 --- a/lib/packages/fabro-api-client/src/models/agent-control-state.ts +++ b/lib/packages/fabro-api-client/src/models/agent-control-state.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-mcp-tool-summary.ts b/lib/packages/fabro-api-client/src/models/agent-mcp-tool-summary.ts index 294ed6e81..e5510ca18 100644 --- a/lib/packages/fabro-api-client/src/models/agent-mcp-tool-summary.ts +++ b/lib/packages/fabro-api-client/src/models/agent-mcp-tool-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-message-props.ts b/lib/packages/fabro-api-client/src/models/agent-message-props.ts index bb98aeeeb..2e93de6e4 100644 --- a/lib/packages/fabro-api-client/src/models/agent-message-props.ts +++ b/lib/packages/fabro-api-client/src/models/agent-message-props.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-session-activated-props.ts b/lib/packages/fabro-api-client/src/models/agent-session-activated-props.ts index 77a3d829f..e187d0f78 100644 --- a/lib/packages/fabro-api-client/src/models/agent-session-activated-props.ts +++ b/lib/packages/fabro-api-client/src/models/agent-session-activated-props.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-skill-activation-source.ts b/lib/packages/fabro-api-client/src/models/agent-skill-activation-source.ts index 334638e4c..99da82a62 100644 --- a/lib/packages/fabro-api-client/src/models/agent-skill-activation-source.ts +++ b/lib/packages/fabro-api-client/src/models/agent-skill-activation-source.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-skill-summary.ts b/lib/packages/fabro-api-client/src/models/agent-skill-summary.ts index c9a3f101c..ff1db8811 100644 --- a/lib/packages/fabro-api-client/src/models/agent-skill-summary.ts +++ b/lib/packages/fabro-api-client/src/models/agent-skill-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tool-category.ts b/lib/packages/fabro-api-client/src/models/agent-tool-category.ts index 8e1eda4b0..c5cd0f4b3 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tool-category.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tool-category.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tool-source-mcp.ts b/lib/packages/fabro-api-client/src/models/agent-tool-source-mcp.ts index 3f8089a92..0ca524dd3 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tool-source-mcp.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tool-source-mcp.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tool-source-native.ts b/lib/packages/fabro-api-client/src/models/agent-tool-source-native.ts index 4ea94bead..6f8c4909f 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tool-source-native.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tool-source-native.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tool-source-skill.ts b/lib/packages/fabro-api-client/src/models/agent-tool-source-skill.ts index e150e8591..e01673606 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tool-source-skill.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tool-source-skill.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tool-source.ts b/lib/packages/fabro-api-client/src/models/agent-tool-source.ts index 391f72fd5..0e664b6cf 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tool-source.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tool-source.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tool-summary.ts b/lib/packages/fabro-api-client/src/models/agent-tool-summary.ts index b52e220c0..9a234f340 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tool-summary.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tool-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/agent-tools-available-props.ts b/lib/packages/fabro-api-client/src/models/agent-tools-available-props.ts index 1231a8aa8..71125a016 100644 --- a/lib/packages/fabro-api-client/src/models/agent-tools-available-props.ts +++ b/lib/packages/fabro-api-client/src/models/agent-tools-available-props.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 505bdf57a..7616b4a60 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/aggregate-billing.ts b/lib/packages/fabro-api-client/src/models/aggregate-billing.ts index 140eed45a..efce18df8 100644 --- a/lib/packages/fabro-api-client/src/models/aggregate-billing.ts +++ b/lib/packages/fabro-api-client/src/models/aggregate-billing.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 8b0330475..1894720e4 100644 --- a/lib/packages/fabro-api-client/src/models/api-question.ts +++ b/lib/packages/fabro-api-client/src/models/api-question.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/append-event-response.ts b/lib/packages/fabro-api-client/src/models/append-event-response.ts index 66412ef29..dc5f95688 100644 --- a/lib/packages/fabro-api-client/src/models/append-event-response.ts +++ b/lib/packages/fabro-api-client/src/models/append-event-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/approval-mode.ts b/lib/packages/fabro-api-client/src/models/approval-mode.ts index 7684e7600..9d7f3beec 100644 --- a/lib/packages/fabro-api-client/src/models/approval-mode.ts +++ b/lib/packages/fabro-api-client/src/models/approval-mode.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 c4dfe1825..160e12f90 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -27,7 +27,7 @@ export interface ArtifactBatchUploadEntry { */ 'path': string; /** - * Optional lowercase hex SHA-256 checksum for the file contents. + * Optional SHA-256 checksum for the file contents; hex input is case-insensitive. */ 'sha256'?: string | null; /** diff --git a/lib/packages/fabro-api-client/src/models/artifact-batch-upload-manifest.ts b/lib/packages/fabro-api-client/src/models/artifact-batch-upload-manifest.ts index ad483a824..080a3e575 100644 --- a/lib/packages/fabro-api-client/src/models/artifact-batch-upload-manifest.ts +++ b/lib/packages/fabro-api-client/src/models/artifact-batch-upload-manifest.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/artifact-entry.ts b/lib/packages/fabro-api-client/src/models/artifact-entry.ts index cee73730c..2bec55376 100644 --- a/lib/packages/fabro-api-client/src/models/artifact-entry.ts +++ b/lib/packages/fabro-api-client/src/models/artifact-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/artifact-list-response.ts b/lib/packages/fabro-api-client/src/models/artifact-list-response.ts index a57ba2d10..f30aade3e 100644 --- a/lib/packages/fabro-api-client/src/models/artifact-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/artifact-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/artifacts-settings.ts b/lib/packages/fabro-api-client/src/models/artifacts-settings.ts index d9e7798db..9d2ab9b02 100644 --- a/lib/packages/fabro-api-client/src/models/artifacts-settings.ts +++ b/lib/packages/fabro-api-client/src/models/artifacts-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/ask-fabro.ts b/lib/packages/fabro-api-client/src/models/ask-fabro.ts index 8d9c47e76..d99f6e9c8 100644 --- a/lib/packages/fabro-api-client/src/models/ask-fabro.ts +++ b/lib/packages/fabro-api-client/src/models/ask-fabro.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/auth-config-response.ts b/lib/packages/fabro-api-client/src/models/auth-config-response.ts index c6a219185..d28517e9e 100644 --- a/lib/packages/fabro-api-client/src/models/auth-config-response.ts +++ b/lib/packages/fabro-api-client/src/models/auth-config-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/auth-me-response.ts b/lib/packages/fabro-api-client/src/models/auth-me-response.ts index c04b83e4f..e64ec8ba0 100644 --- a/lib/packages/fabro-api-client/src/models/auth-me-response.ts +++ b/lib/packages/fabro-api-client/src/models/auth-me-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/auth-method.ts b/lib/packages/fabro-api-client/src/models/auth-method.ts index 80b643fef..8ba1ecc9b 100644 --- a/lib/packages/fabro-api-client/src/models/auth-method.ts +++ b/lib/packages/fabro-api-client/src/models/auth-method.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/auth-session-user.ts b/lib/packages/fabro-api-client/src/models/auth-session-user.ts index 6afa92a88..065cacfba 100644 --- a/lib/packages/fabro-api-client/src/models/auth-session-user.ts +++ b/lib/packages/fabro-api-client/src/models/auth-session-user.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/auth-session.ts b/lib/packages/fabro-api-client/src/models/auth-session.ts index d57f6df59..088879153 100644 --- a/lib/packages/fabro-api-client/src/models/auth-session.ts +++ b/lib/packages/fabro-api-client/src/models/auth-session.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/auth-sessions-response.ts b/lib/packages/fabro-api-client/src/models/auth-sessions-response.ts index 82c01fb1d..3d0685eef 100644 --- a/lib/packages/fabro-api-client/src/models/auth-sessions-response.ts +++ b/lib/packages/fabro-api-client/src/models/auth-sessions-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-api-trigger.ts b/lib/packages/fabro-api-client/src/models/automation-api-trigger.ts index 12a830945..b0bf14572 100644 --- a/lib/packages/fabro-api-client/src/models/automation-api-trigger.ts +++ b/lib/packages/fabro-api-client/src/models/automation-api-trigger.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-list-meta.ts b/lib/packages/fabro-api-client/src/models/automation-list-meta.ts index 12524dba9..b2a9fb140 100644 --- a/lib/packages/fabro-api-client/src/models/automation-list-meta.ts +++ b/lib/packages/fabro-api-client/src/models/automation-list-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-list-response.ts b/lib/packages/fabro-api-client/src/models/automation-list-response.ts index 58258b67d..b194db4a1 100644 --- a/lib/packages/fabro-api-client/src/models/automation-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/automation-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-ref.ts b/lib/packages/fabro-api-client/src/models/automation-ref.ts index d8055703b..a22d99199 100644 --- a/lib/packages/fabro-api-client/src/models/automation-ref.ts +++ b/lib/packages/fabro-api-client/src/models/automation-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-schedule-trigger.ts b/lib/packages/fabro-api-client/src/models/automation-schedule-trigger.ts index 85b9631b2..d44d209d9 100644 --- a/lib/packages/fabro-api-client/src/models/automation-schedule-trigger.ts +++ b/lib/packages/fabro-api-client/src/models/automation-schedule-trigger.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-target.ts b/lib/packages/fabro-api-client/src/models/automation-target.ts index 6eb3daa75..74e94c989 100644 --- a/lib/packages/fabro-api-client/src/models/automation-target.ts +++ b/lib/packages/fabro-api-client/src/models/automation-target.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation-trigger.ts b/lib/packages/fabro-api-client/src/models/automation-trigger.ts index 30e73dc81..ed204177b 100644 --- a/lib/packages/fabro-api-client/src/models/automation-trigger.ts +++ b/lib/packages/fabro-api-client/src/models/automation-trigger.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/automation.ts b/lib/packages/fabro-api-client/src/models/automation.ts index 5c1c20bb1..92cf402e2 100644 --- a/lib/packages/fabro-api-client/src/models/automation.ts +++ b/lib/packages/fabro-api-client/src/models/automation.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-delete-runs-request.ts b/lib/packages/fabro-api-client/src/models/batch-delete-runs-request.ts index 039b5ffbc..38fa3b995 100644 --- a/lib/packages/fabro-api-client/src/models/batch-delete-runs-request.ts +++ b/lib/packages/fabro-api-client/src/models/batch-delete-runs-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-delete-runs-response.ts b/lib/packages/fabro-api-client/src/models/batch-delete-runs-response.ts index cdc96e05f..1d9d3173e 100644 --- a/lib/packages/fabro-api-client/src/models/batch-delete-runs-response.ts +++ b/lib/packages/fabro-api-client/src/models/batch-delete-runs-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-delete-runs-result.ts b/lib/packages/fabro-api-client/src/models/batch-delete-runs-result.ts index e55be5fe5..764c19013 100644 --- a/lib/packages/fabro-api-client/src/models/batch-delete-runs-result.ts +++ b/lib/packages/fabro-api-client/src/models/batch-delete-runs-result.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-delete-runs-summary.ts b/lib/packages/fabro-api-client/src/models/batch-delete-runs-summary.ts index a335230b2..849dc7a29 100644 --- a/lib/packages/fabro-api-client/src/models/batch-delete-runs-summary.ts +++ b/lib/packages/fabro-api-client/src/models/batch-delete-runs-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-request.ts b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-request.ts index d93be0250..86a8b5ac9 100644 --- a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-request.ts +++ b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-response.ts b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-response.ts index 8dc5a80dd..b2bca1f44 100644 --- a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-response.ts +++ b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-result.ts b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-result.ts index d3559109f..851e4e7f3 100644 --- a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-result.ts +++ b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-result.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-summary.ts b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-summary.ts index e01f9815d..f5bf9cd2a 100644 --- a/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-summary.ts +++ b/lib/packages/fabro-api-client/src/models/batch-run-lifecycle-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 1c945f4d3..19413b7c0 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/billing-by-model.ts b/lib/packages/fabro-api-client/src/models/billing-by-model.ts index 0678eae9e..9c2bf6153 100644 --- a/lib/packages/fabro-api-client/src/models/billing-by-model.ts +++ b/lib/packages/fabro-api-client/src/models/billing-by-model.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/billing-model-ref.ts b/lib/packages/fabro-api-client/src/models/billing-model-ref.ts index 5b12fa237..b7f812bb1 100644 --- a/lib/packages/fabro-api-client/src/models/billing-model-ref.ts +++ b/lib/packages/fabro-api-client/src/models/billing-model-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/billing-speed.ts b/lib/packages/fabro-api-client/src/models/billing-speed.ts index 3cad0e643..80e070d52 100644 --- a/lib/packages/fabro-api-client/src/models/billing-speed.ts +++ b/lib/packages/fabro-api-client/src/models/billing-speed.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/billing-stage-ref.ts b/lib/packages/fabro-api-client/src/models/billing-stage-ref.ts index 8db422a67..ca95cb907 100644 --- a/lib/packages/fabro-api-client/src/models/billing-stage-ref.ts +++ b/lib/packages/fabro-api-client/src/models/billing-stage-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/blocked-reason.ts b/lib/packages/fabro-api-client/src/models/blocked-reason.ts index dda10abec..7567ffe5a 100644 --- a/lib/packages/fabro-api-client/src/models/blocked-reason.ts +++ b/lib/packages/fabro-api-client/src/models/blocked-reason.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/board-column.ts b/lib/packages/fabro-api-client/src/models/board-column.ts index 8dcd91a7f..ef67b0119 100644 --- a/lib/packages/fabro-api-client/src/models/board-column.ts +++ b/lib/packages/fabro-api-client/src/models/board-column.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/check-run-status.ts b/lib/packages/fabro-api-client/src/models/check-run-status.ts index c82703c8d..d3fbe1d5e 100644 --- a/lib/packages/fabro-api-client/src/models/check-run-status.ts +++ b/lib/packages/fabro-api-client/src/models/check-run-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/check-run.ts b/lib/packages/fabro-api-client/src/models/check-run.ts index b94d2b9e5..f00a1afa3 100644 --- a/lib/packages/fabro-api-client/src/models/check-run.ts +++ b/lib/packages/fabro-api-client/src/models/check-run.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/checkpoint-record.ts b/lib/packages/fabro-api-client/src/models/checkpoint-record.ts index 9177008eb..d3f7f4e34 100644 --- a/lib/packages/fabro-api-client/src/models/checkpoint-record.ts +++ b/lib/packages/fabro-api-client/src/models/checkpoint-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/close-run-pull-request-response.ts b/lib/packages/fabro-api-client/src/models/close-run-pull-request-response.ts index ba522a231..521e27156 100644 --- a/lib/packages/fabro-api-client/src/models/close-run-pull-request-response.ts +++ b/lib/packages/fabro-api-client/src/models/close-run-pull-request-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/code-location.ts b/lib/packages/fabro-api-client/src/models/code-location.ts index 42a1a3f82..52e29b6e4 100644 --- a/lib/packages/fabro-api-client/src/models/code-location.ts +++ b/lib/packages/fabro-api-client/src/models/code-location.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/command-log-response.ts b/lib/packages/fabro-api-client/src/models/command-log-response.ts index 6e475131c..b28515f6c 100644 --- a/lib/packages/fabro-api-client/src/models/command-log-response.ts +++ b/lib/packages/fabro-api-client/src/models/command-log-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/command-termination.ts b/lib/packages/fabro-api-client/src/models/command-termination.ts index 11323d767..30eb79b6f 100644 --- a/lib/packages/fabro-api-client/src/models/command-termination.ts +++ b/lib/packages/fabro-api-client/src/models/command-termination.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/completion-content-part.ts b/lib/packages/fabro-api-client/src/models/completion-content-part.ts index def5398f4..0f0d2d7e0 100644 --- a/lib/packages/fabro-api-client/src/models/completion-content-part.ts +++ b/lib/packages/fabro-api-client/src/models/completion-content-part.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/completion-message.ts b/lib/packages/fabro-api-client/src/models/completion-message.ts index da81f2603..60f264761 100644 --- a/lib/packages/fabro-api-client/src/models/completion-message.ts +++ b/lib/packages/fabro-api-client/src/models/completion-message.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/completion-response.ts b/lib/packages/fabro-api-client/src/models/completion-response.ts index 5b3d34e4b..555907f9c 100644 --- a/lib/packages/fabro-api-client/src/models/completion-response.ts +++ b/lib/packages/fabro-api-client/src/models/completion-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/completion-tool-choice.ts b/lib/packages/fabro-api-client/src/models/completion-tool-choice.ts index 97196c2e1..87b4ffdb2 100644 --- a/lib/packages/fabro-api-client/src/models/completion-tool-choice.ts +++ b/lib/packages/fabro-api-client/src/models/completion-tool-choice.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/completion-tool-definition.ts b/lib/packages/fabro-api-client/src/models/completion-tool-definition.ts index ba2b91b38..2cdfa60e7 100644 --- a/lib/packages/fabro-api-client/src/models/completion-tool-definition.ts +++ b/lib/packages/fabro-api-client/src/models/completion-tool-definition.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/completion-usage.ts b/lib/packages/fabro-api-client/src/models/completion-usage.ts index 056007b1b..6d2e8892d 100644 --- a/lib/packages/fabro-api-client/src/models/completion-usage.ts +++ b/lib/packages/fabro-api-client/src/models/completion-usage.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/conclusion.ts b/lib/packages/fabro-api-client/src/models/conclusion.ts index f687ddf24..e7a3c8da4 100644 --- a/lib/packages/fabro-api-client/src/models/conclusion.ts +++ b/lib/packages/fabro-api-client/src/models/conclusion.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/cost-source.ts b/lib/packages/fabro-api-client/src/models/cost-source.ts index 172115254..9e91b3d6f 100644 --- a/lib/packages/fabro-api-client/src/models/cost-source.ts +++ b/lib/packages/fabro-api-client/src/models/cost-source.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-automation-request.ts b/lib/packages/fabro-api-client/src/models/create-automation-request.ts index ce99d34db..47669ad5d 100644 --- a/lib/packages/fabro-api-client/src/models/create-automation-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-automation-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-completion-request.ts b/lib/packages/fabro-api-client/src/models/create-completion-request.ts index 836e20c0d..c59f7869d 100644 --- a/lib/packages/fabro-api-client/src/models/create-completion-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-completion-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-environment-request.ts b/lib/packages/fabro-api-client/src/models/create-environment-request.ts index fd4d48006..8ae7a1dd9 100644 --- a/lib/packages/fabro-api-client/src/models/create-environment-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-environment-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-mcp-server-request.ts b/lib/packages/fabro-api-client/src/models/create-mcp-server-request.ts index 058a3f7e3..bf8af246c 100644 --- a/lib/packages/fabro-api-client/src/models/create-mcp-server-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-mcp-server-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-playground-chat-request.ts b/lib/packages/fabro-api-client/src/models/create-playground-chat-request.ts index 1d1ddc216..7c17866ec 100644 --- a/lib/packages/fabro-api-client/src/models/create-playground-chat-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-playground-chat-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-run-pull-request-request.ts b/lib/packages/fabro-api-client/src/models/create-run-pull-request-request.ts index 7ec1a3020..5c0473b53 100644 --- a/lib/packages/fabro-api-client/src/models/create-run-pull-request-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-run-pull-request-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-run-session-request.ts b/lib/packages/fabro-api-client/src/models/create-run-session-request.ts index f079d1b01..2c2d7a939 100644 --- a/lib/packages/fabro-api-client/src/models/create-run-session-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-run-session-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-secret-request.ts b/lib/packages/fabro-api-client/src/models/create-secret-request.ts index 5061fd4a7..856e826a3 100644 --- a/lib/packages/fabro-api-client/src/models/create-secret-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-secret-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-variable-request.ts b/lib/packages/fabro-api-client/src/models/create-variable-request.ts index f33de18d1..5f5cef14d 100644 --- a/lib/packages/fabro-api-client/src/models/create-variable-request.ts +++ b/lib/packages/fabro-api-client/src/models/create-variable-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/create-workflow-version-response.ts b/lib/packages/fabro-api-client/src/models/create-workflow-version-response.ts new file mode 100644 index 000000000..de58626b1 --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/create-workflow-version-response.ts @@ -0,0 +1,25 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.2.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * Identity of the stored immutable workflow version. + */ +export interface CreateWorkflowVersionResponse { + /** + * SHA-256 identity of validated canonical workflow-version bytes. Hex input is case-insensitive; Fabro emits the canonical lowercase form. + */ + 'workflow_version_id': string; +} diff --git a/lib/packages/fabro-api-client/src/models/delete-run-response.ts b/lib/packages/fabro-api-client/src/models/delete-run-response.ts index 696f161ca..587f58ecf 100644 --- a/lib/packages/fabro-api-client/src/models/delete-run-response.ts +++ b/lib/packages/fabro-api-client/src/models/delete-run-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/delete-run-sandbox.ts b/lib/packages/fabro-api-client/src/models/delete-run-sandbox.ts index 349ce716d..bdcf34a0c 100644 --- a/lib/packages/fabro-api-client/src/models/delete-run-sandbox.ts +++ b/lib/packages/fabro-api-client/src/models/delete-run-sandbox.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/delete-secret-request.ts b/lib/packages/fabro-api-client/src/models/delete-secret-request.ts index 34e00310b..e7282b932 100644 --- a/lib/packages/fabro-api-client/src/models/delete-secret-request.ts +++ b/lib/packages/fabro-api-client/src/models/delete-secret-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/deny-run-request.ts b/lib/packages/fabro-api-client/src/models/deny-run-request.ts index b7ae55fb0..00055cdda 100644 --- a/lib/packages/fabro-api-client/src/models/deny-run-request.ts +++ b/lib/packages/fabro-api-client/src/models/deny-run-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/dev-token-login-request.ts b/lib/packages/fabro-api-client/src/models/dev-token-login-request.ts index 8dd541b95..2ca322d2c 100644 --- a/lib/packages/fabro-api-client/src/models/dev-token-login-request.ts +++ b/lib/packages/fabro-api-client/src/models/dev-token-login-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/dev-token-login-response.ts b/lib/packages/fabro-api-client/src/models/dev-token-login-response.ts index 8492cc69c..7ffa09c89 100644 --- a/lib/packages/fabro-api-client/src/models/dev-token-login-response.ts +++ b/lib/packages/fabro-api-client/src/models/dev-token-login-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 efa40dc67..d9887001f 100644 --- a/lib/packages/fabro-api-client/src/models/diagnostics-check.ts +++ b/lib/packages/fabro-api-client/src/models/diagnostics-check.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/diagnostics-detail.ts b/lib/packages/fabro-api-client/src/models/diagnostics-detail.ts index 538f48eb8..6b8812eb4 100644 --- a/lib/packages/fabro-api-client/src/models/diagnostics-detail.ts +++ b/lib/packages/fabro-api-client/src/models/diagnostics-detail.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/diagnostics-report.ts b/lib/packages/fabro-api-client/src/models/diagnostics-report.ts index 55d32af76..36684c310 100644 --- a/lib/packages/fabro-api-client/src/models/diagnostics-report.ts +++ b/lib/packages/fabro-api-client/src/models/diagnostics-report.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/diagnostics-section.ts b/lib/packages/fabro-api-client/src/models/diagnostics-section.ts index d21f0c3ca..a0bba8977 100644 --- a/lib/packages/fabro-api-client/src/models/diagnostics-section.ts +++ b/lib/packages/fabro-api-client/src/models/diagnostics-section.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/diff-file.ts b/lib/packages/fabro-api-client/src/models/diff-file.ts index ca7126713..4bce821f6 100644 --- a/lib/packages/fabro-api-client/src/models/diff-file.ts +++ b/lib/packages/fabro-api-client/src/models/diff-file.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/diff-stats.ts b/lib/packages/fabro-api-client/src/models/diff-stats.ts index b86968c04..3c55280a9 100644 --- a/lib/packages/fabro-api-client/src/models/diff-stats.ts +++ b/lib/packages/fabro-api-client/src/models/diff-stats.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/diff-summary.ts b/lib/packages/fabro-api-client/src/models/diff-summary.ts index f5dbcea5e..fdbf5b6d3 100644 --- a/lib/packages/fabro-api-client/src/models/diff-summary.ts +++ b/lib/packages/fabro-api-client/src/models/diff-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/dirty-status.ts b/lib/packages/fabro-api-client/src/models/dirty-status.ts index 2a89a3c2a..9857b7061 100644 --- a/lib/packages/fabro-api-client/src/models/dirty-status.ts +++ b/lib/packages/fabro-api-client/src/models/dirty-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 f9573e986..4410fe07c 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/disk-usage-run-row.ts b/lib/packages/fabro-api-client/src/models/disk-usage-run-row.ts index 13392839f..84697b185 100644 --- a/lib/packages/fabro-api-client/src/models/disk-usage-run-row.ts +++ b/lib/packages/fabro-api-client/src/models/disk-usage-run-row.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 3fe75b0fd..d99cda3c6 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/dockerfile-source-inline.ts b/lib/packages/fabro-api-client/src/models/dockerfile-source-inline.ts index 296eb3d94..7bc18793c 100644 --- a/lib/packages/fabro-api-client/src/models/dockerfile-source-inline.ts +++ b/lib/packages/fabro-api-client/src/models/dockerfile-source-inline.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/dockerfile-source-path.ts b/lib/packages/fabro-api-client/src/models/dockerfile-source-path.ts index 2510b3634..888514e9c 100644 --- a/lib/packages/fabro-api-client/src/models/dockerfile-source-path.ts +++ b/lib/packages/fabro-api-client/src/models/dockerfile-source-path.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/dockerfile-source.ts b/lib/packages/fabro-api-client/src/models/dockerfile-source.ts index dfb2ef280..4a397e53b 100644 --- a/lib/packages/fabro-api-client/src/models/dockerfile-source.ts +++ b/lib/packages/fabro-api-client/src/models/dockerfile-source.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-api-dockerfile-source-inline.ts b/lib/packages/fabro-api-client/src/models/environment-api-dockerfile-source-inline.ts index 35180b10a..83b3a1dbc 100644 --- a/lib/packages/fabro-api-client/src/models/environment-api-dockerfile-source-inline.ts +++ b/lib/packages/fabro-api-client/src/models/environment-api-dockerfile-source-inline.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-api-image-settings.ts b/lib/packages/fabro-api-client/src/models/environment-api-image-settings.ts index 54578b0cd..c41e8d3c0 100644 --- a/lib/packages/fabro-api-client/src/models/environment-api-image-settings.ts +++ b/lib/packages/fabro-api-client/src/models/environment-api-image-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-image-settings.ts b/lib/packages/fabro-api-client/src/models/environment-image-settings.ts index 997f1d64c..e2b4f60e6 100644 --- a/lib/packages/fabro-api-client/src/models/environment-image-settings.ts +++ b/lib/packages/fabro-api-client/src/models/environment-image-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-lifecycle-settings.ts b/lib/packages/fabro-api-client/src/models/environment-lifecycle-settings.ts index f9a2426a9..018fff3ff 100644 --- a/lib/packages/fabro-api-client/src/models/environment-lifecycle-settings.ts +++ b/lib/packages/fabro-api-client/src/models/environment-lifecycle-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-list-meta.ts b/lib/packages/fabro-api-client/src/models/environment-list-meta.ts index aa92bad87..d198d6a46 100644 --- a/lib/packages/fabro-api-client/src/models/environment-list-meta.ts +++ b/lib/packages/fabro-api-client/src/models/environment-list-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-list-response.ts b/lib/packages/fabro-api-client/src/models/environment-list-response.ts index cf25725b1..f4ef942cf 100644 --- a/lib/packages/fabro-api-client/src/models/environment-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/environment-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-network-mode.ts b/lib/packages/fabro-api-client/src/models/environment-network-mode.ts index ab4772098..6da5fec7c 100644 --- a/lib/packages/fabro-api-client/src/models/environment-network-mode.ts +++ b/lib/packages/fabro-api-client/src/models/environment-network-mode.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-network-settings.ts b/lib/packages/fabro-api-client/src/models/environment-network-settings.ts index 8bdf99fb6..50eff443d 100644 --- a/lib/packages/fabro-api-client/src/models/environment-network-settings.ts +++ b/lib/packages/fabro-api-client/src/models/environment-network-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-provider.ts b/lib/packages/fabro-api-client/src/models/environment-provider.ts index 0761c4b4c..bee7f45e0 100644 --- a/lib/packages/fabro-api-client/src/models/environment-provider.ts +++ b/lib/packages/fabro-api-client/src/models/environment-provider.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-resources-settings.ts b/lib/packages/fabro-api-client/src/models/environment-resources-settings.ts index c17caaf36..e83fbc46f 100644 --- a/lib/packages/fabro-api-client/src/models/environment-resources-settings.ts +++ b/lib/packages/fabro-api-client/src/models/environment-resources-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment-settings.ts b/lib/packages/fabro-api-client/src/models/environment-settings.ts index 7f5f9f007..01e501724 100644 --- a/lib/packages/fabro-api-client/src/models/environment-settings.ts +++ b/lib/packages/fabro-api-client/src/models/environment-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/environment.ts b/lib/packages/fabro-api-client/src/models/environment.ts index 28037d144..38b8847c0 100644 --- a/lib/packages/fabro-api-client/src/models/environment.ts +++ b/lib/packages/fabro-api-client/src/models/environment.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/error-response-entry.ts b/lib/packages/fabro-api-client/src/models/error-response-entry.ts index 8d2095c92..081416711 100644 --- a/lib/packages/fabro-api-client/src/models/error-response-entry.ts +++ b/lib/packages/fabro-api-client/src/models/error-response-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/error-response.ts b/lib/packages/fabro-api-client/src/models/error-response.ts index 95c8ef4d3..d66e866b5 100644 --- a/lib/packages/fabro-api-client/src/models/error-response.ts +++ b/lib/packages/fabro-api-client/src/models/error-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/event-envelope.ts b/lib/packages/fabro-api-client/src/models/event-envelope.ts index 8ed673472..1ff9fe51d 100644 --- a/lib/packages/fabro-api-client/src/models/event-envelope.ts +++ b/lib/packages/fabro-api-client/src/models/event-envelope.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/event-seq.ts b/lib/packages/fabro-api-client/src/models/event-seq.ts index d336fddf6..948345b27 100644 --- a/lib/packages/fabro-api-client/src/models/event-seq.ts +++ b/lib/packages/fabro-api-client/src/models/event-seq.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/exec-output-tail.ts b/lib/packages/fabro-api-client/src/models/exec-output-tail.ts index 1405c08c2..9ea534709 100644 --- a/lib/packages/fabro-api-client/src/models/exec-output-tail.ts +++ b/lib/packages/fabro-api-client/src/models/exec-output-tail.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/execute-query-request.ts b/lib/packages/fabro-api-client/src/models/execute-query-request.ts index f1c8041ec..3b0ceeba8 100644 --- a/lib/packages/fabro-api-client/src/models/execute-query-request.ts +++ b/lib/packages/fabro-api-client/src/models/execute-query-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/execute-query-response-rows-inner-inner.ts b/lib/packages/fabro-api-client/src/models/execute-query-response-rows-inner-inner.ts index 8201a9181..ab3f4b323 100644 --- a/lib/packages/fabro-api-client/src/models/execute-query-response-rows-inner-inner.ts +++ b/lib/packages/fabro-api-client/src/models/execute-query-response-rows-inner-inner.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/execute-query-response.ts b/lib/packages/fabro-api-client/src/models/execute-query-response.ts index d3bb5d984..eaf2aea4f 100644 --- a/lib/packages/fabro-api-client/src/models/execute-query-response.ts +++ b/lib/packages/fabro-api-client/src/models/execute-query-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/failure-category.ts b/lib/packages/fabro-api-client/src/models/failure-category.ts index c9460754e..cedcc3c27 100644 --- a/lib/packages/fabro-api-client/src/models/failure-category.ts +++ b/lib/packages/fabro-api-client/src/models/failure-category.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/failure-detail.ts b/lib/packages/fabro-api-client/src/models/failure-detail.ts index c50c2441a..f8c6beb33 100644 --- a/lib/packages/fabro-api-client/src/models/failure-detail.ts +++ b/lib/packages/fabro-api-client/src/models/failure-detail.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/failure-reason.ts b/lib/packages/fabro-api-client/src/models/failure-reason.ts index 79172e887..1f0e787e1 100644 --- a/lib/packages/fabro-api-client/src/models/failure-reason.ts +++ b/lib/packages/fabro-api-client/src/models/failure-reason.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/file-checkpoint.ts b/lib/packages/fabro-api-client/src/models/file-checkpoint.ts index b1c41271c..4d670d20a 100644 --- a/lib/packages/fabro-api-client/src/models/file-checkpoint.ts +++ b/lib/packages/fabro-api-client/src/models/file-checkpoint.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/file-diff.ts b/lib/packages/fabro-api-client/src/models/file-diff.ts index 1e16e718c..320a22c54 100644 --- a/lib/packages/fabro-api-client/src/models/file-diff.ts +++ b/lib/packages/fabro-api-client/src/models/file-diff.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/fork-request.ts b/lib/packages/fabro-api-client/src/models/fork-request.ts index 6b5e4fce8..4f68ca46f 100644 --- a/lib/packages/fabro-api-client/src/models/fork-request.ts +++ b/lib/packages/fabro-api-client/src/models/fork-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/fork-response.ts b/lib/packages/fabro-api-client/src/models/fork-response.ts index 3099927c0..c3cef2801 100644 --- a/lib/packages/fabro-api-client/src/models/fork-response.ts +++ b/lib/packages/fabro-api-client/src/models/fork-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/fork-source-ref.ts b/lib/packages/fabro-api-client/src/models/fork-source-ref.ts index 8ee8e63f2..7f03a2f3f 100644 --- a/lib/packages/fabro-api-client/src/models/fork-source-ref.ts +++ b/lib/packages/fabro-api-client/src/models/fork-source-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/git-author-settings.ts b/lib/packages/fabro-api-client/src/models/git-author-settings.ts index 619c72dda..55aa32893 100644 --- a/lib/packages/fabro-api-client/src/models/git-author-settings.ts +++ b/lib/packages/fabro-api-client/src/models/git-author-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/git-context.ts b/lib/packages/fabro-api-client/src/models/git-context.ts index 20c205643..61e8a94f2 100644 --- a/lib/packages/fabro-api-client/src/models/git-context.ts +++ b/lib/packages/fabro-api-client/src/models/git-context.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/github-integration-settings.ts b/lib/packages/fabro-api-client/src/models/github-integration-settings.ts index 6289d6143..fa6bdfcac 100644 --- a/lib/packages/fabro-api-client/src/models/github-integration-settings.ts +++ b/lib/packages/fabro-api-client/src/models/github-integration-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/github-integration-strategy.ts b/lib/packages/fabro-api-client/src/models/github-integration-strategy.ts index 9b1e1aa37..37e8d8134 100644 --- a/lib/packages/fabro-api-client/src/models/github-integration-strategy.ts +++ b/lib/packages/fabro-api-client/src/models/github-integration-strategy.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/health-response.ts b/lib/packages/fabro-api-client/src/models/health-response.ts index 8dce26d2c..2dc9014b0 100644 --- a/lib/packages/fabro-api-client/src/models/health-response.ts +++ b/lib/packages/fabro-api-client/src/models/health-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/history-entry.ts b/lib/packages/fabro-api-client/src/models/history-entry.ts index 2c491cc36..fab843c64 100644 --- a/lib/packages/fabro-api-client/src/models/history-entry.ts +++ b/lib/packages/fabro-api-client/src/models/history-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/hook-definition.ts b/lib/packages/fabro-api-client/src/models/hook-definition.ts index a8b2100e8..83a009767 100644 --- a/lib/packages/fabro-api-client/src/models/hook-definition.ts +++ b/lib/packages/fabro-api-client/src/models/hook-definition.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/hook-event.ts b/lib/packages/fabro-api-client/src/models/hook-event.ts index aabc20ecd..ab3196dd4 100644 --- a/lib/packages/fabro-api-client/src/models/hook-event.ts +++ b/lib/packages/fabro-api-client/src/models/hook-event.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/idp-identity.ts b/lib/packages/fabro-api-client/src/models/idp-identity.ts index 6eb4dd167..6aefab89a 100644 --- a/lib/packages/fabro-api-client/src/models/idp-identity.ts +++ b/lib/packages/fabro-api-client/src/models/idp-identity.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/index.ts b/lib/packages/fabro-api-client/src/models/index.ts index 2fdd2e9fe..04df237be 100644 --- a/lib/packages/fabro-api-client/src/models/index.ts +++ b/lib/packages/fabro-api-client/src/models/index.ts @@ -76,6 +76,7 @@ export * from './create-run-pull-request-request'; export * from './create-run-session-request'; export * from './create-secret-request'; export * from './create-variable-request'; +export * from './create-workflow-version-response'; export * from './delete-run-response'; export * from './delete-run-sandbox'; export * from './delete-secret-request'; @@ -511,4 +512,5 @@ export * from './workflow-ref'; export * from './workflow-reference'; export * from './workflow-schedule-summary'; export * from './workflow-settings'; +export * from './workflow-version'; export * from './write-blob-response'; diff --git a/lib/packages/fabro-api-client/src/models/install-finish-response.ts b/lib/packages/fabro-api-client/src/models/install-finish-response.ts index 32fd470d9..3686a9175 100644 --- a/lib/packages/fabro-api-client/src/models/install-finish-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-finish-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-app-manifest-input.ts b/lib/packages/fabro-api-client/src/models/install-github-app-manifest-input.ts index aaeddfb88..75d2d40f6 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-app-manifest-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-app-manifest-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-app-manifest-response.ts b/lib/packages/fabro-api-client/src/models/install-github-app-manifest-response.ts index 12e1b8d64..92de33a62 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-app-manifest-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-app-manifest-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-app-owner.ts b/lib/packages/fabro-api-client/src/models/install-github-app-owner.ts index 93afa2404..d2b1ab048 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-app-owner.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-app-owner.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-summary.ts b/lib/packages/fabro-api-client/src/models/install-github-summary.ts index c9cc30b79..13b5ae416 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-summary.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-token-input.ts b/lib/packages/fabro-api-client/src/models/install-github-token-input.ts index c1dab44a5..bbc488c60 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-token-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-token-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-token-test-input.ts b/lib/packages/fabro-api-client/src/models/install-github-token-test-input.ts index d147b0f5d..e970fe2c8 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-token-test-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-token-test-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-github-token-test-response.ts b/lib/packages/fabro-api-client/src/models/install-github-token-test-response.ts index 1d8d74406..9f7b1b86b 100644 --- a/lib/packages/fabro-api-client/src/models/install-github-token-test-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-github-token-test-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-llm-provider-input.ts b/lib/packages/fabro-api-client/src/models/install-llm-provider-input.ts index 3f192e9e6..79bc37e38 100644 --- a/lib/packages/fabro-api-client/src/models/install-llm-provider-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-llm-provider-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-llm-providers-input.ts b/lib/packages/fabro-api-client/src/models/install-llm-providers-input.ts index 7e83d5a13..6ea5a58f0 100644 --- a/lib/packages/fabro-api-client/src/models/install-llm-providers-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-llm-providers-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-llm-summary-providers-inner.ts b/lib/packages/fabro-api-client/src/models/install-llm-summary-providers-inner.ts index ff4eaffe7..001f84689 100644 --- a/lib/packages/fabro-api-client/src/models/install-llm-summary-providers-inner.ts +++ b/lib/packages/fabro-api-client/src/models/install-llm-summary-providers-inner.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-llm-summary.ts b/lib/packages/fabro-api-client/src/models/install-llm-summary.ts index 04042cd75..cee52f3bb 100644 --- a/lib/packages/fabro-api-client/src/models/install-llm-summary.ts +++ b/lib/packages/fabro-api-client/src/models/install-llm-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-llm-test-input.ts b/lib/packages/fabro-api-client/src/models/install-llm-test-input.ts index 45377472f..b0d33fe73 100644 --- a/lib/packages/fabro-api-client/src/models/install-llm-test-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-llm-test-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-llm-validation-response.ts b/lib/packages/fabro-api-client/src/models/install-llm-validation-response.ts index 22e904afd..bd4a4afce 100644 --- a/lib/packages/fabro-api-client/src/models/install-llm-validation-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-llm-validation-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-object-store-input.ts b/lib/packages/fabro-api-client/src/models/install-object-store-input.ts index 8dd8f497d..7b611b8a9 100644 --- a/lib/packages/fabro-api-client/src/models/install-object-store-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-object-store-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-object-store-summary.ts b/lib/packages/fabro-api-client/src/models/install-object-store-summary.ts index 47c32b0ba..2dee0735f 100644 --- a/lib/packages/fabro-api-client/src/models/install-object-store-summary.ts +++ b/lib/packages/fabro-api-client/src/models/install-object-store-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-object-store-validation-response.ts b/lib/packages/fabro-api-client/src/models/install-object-store-validation-response.ts index 6785e09b3..d0d83b92f 100644 --- a/lib/packages/fabro-api-client/src/models/install-object-store-validation-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-object-store-validation-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-prefill.ts b/lib/packages/fabro-api-client/src/models/install-prefill.ts index 1c20eb029..6ddc45ff7 100644 --- a/lib/packages/fabro-api-client/src/models/install-prefill.ts +++ b/lib/packages/fabro-api-client/src/models/install-prefill.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-sandbox-input.ts b/lib/packages/fabro-api-client/src/models/install-sandbox-input.ts index b29a427f9..b806a7ac2 100644 --- a/lib/packages/fabro-api-client/src/models/install-sandbox-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-sandbox-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-sandbox-summary.ts b/lib/packages/fabro-api-client/src/models/install-sandbox-summary.ts index 6eb3a2422..4ed968718 100644 --- a/lib/packages/fabro-api-client/src/models/install-sandbox-summary.ts +++ b/lib/packages/fabro-api-client/src/models/install-sandbox-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-sandbox-validation-response.ts b/lib/packages/fabro-api-client/src/models/install-sandbox-validation-response.ts index 863e179a3..d8592b1f7 100644 --- a/lib/packages/fabro-api-client/src/models/install-sandbox-validation-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-sandbox-validation-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-server-config-input.ts b/lib/packages/fabro-api-client/src/models/install-server-config-input.ts index 7e9c30a73..1418f78f2 100644 --- a/lib/packages/fabro-api-client/src/models/install-server-config-input.ts +++ b/lib/packages/fabro-api-client/src/models/install-server-config-input.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/install-session-response.ts b/lib/packages/fabro-api-client/src/models/install-session-response.ts index 9eecbb3b0..6ae325b1e 100644 --- a/lib/packages/fabro-api-client/src/models/install-session-response.ts +++ b/lib/packages/fabro-api-client/src/models/install-session-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/integration-connection-kind.ts b/lib/packages/fabro-api-client/src/models/integration-connection-kind.ts index 6d3b6fcfe..7d213d953 100644 --- a/lib/packages/fabro-api-client/src/models/integration-connection-kind.ts +++ b/lib/packages/fabro-api-client/src/models/integration-connection-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/integration-connection-state.ts b/lib/packages/fabro-api-client/src/models/integration-connection-state.ts index ff9696c5e..d88ce1bbc 100644 --- a/lib/packages/fabro-api-client/src/models/integration-connection-state.ts +++ b/lib/packages/fabro-api-client/src/models/integration-connection-state.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/integration-connection-status.ts b/lib/packages/fabro-api-client/src/models/integration-connection-status.ts index 6916f4e79..985f05421 100644 --- a/lib/packages/fabro-api-client/src/models/integration-connection-status.ts +++ b/lib/packages/fabro-api-client/src/models/integration-connection-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/integration-provider.ts b/lib/packages/fabro-api-client/src/models/integration-provider.ts index 2c98029ba..ddffa9b53 100644 --- a/lib/packages/fabro-api-client/src/models/integration-provider.ts +++ b/lib/packages/fabro-api-client/src/models/integration-provider.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/integration-status.ts b/lib/packages/fabro-api-client/src/models/integration-status.ts index 680dd34eb..c7687b17b 100644 --- a/lib/packages/fabro-api-client/src/models/integration-status.ts +++ b/lib/packages/fabro-api-client/src/models/integration-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/integration-webhooks-settings.ts b/lib/packages/fabro-api-client/src/models/integration-webhooks-settings.ts index 367922a74..41833bf0b 100644 --- a/lib/packages/fabro-api-client/src/models/integration-webhooks-settings.ts +++ b/lib/packages/fabro-api-client/src/models/integration-webhooks-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/interview-option.ts b/lib/packages/fabro-api-client/src/models/interview-option.ts index 16c536f80..40d83144e 100644 --- a/lib/packages/fabro-api-client/src/models/interview-option.ts +++ b/lib/packages/fabro-api-client/src/models/interview-option.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/interview-provider-settings.ts b/lib/packages/fabro-api-client/src/models/interview-provider-settings.ts index 34d8d5c0e..84afb95df 100644 --- a/lib/packages/fabro-api-client/src/models/interview-provider-settings.ts +++ b/lib/packages/fabro-api-client/src/models/interview-provider-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/interview-question-record.ts b/lib/packages/fabro-api-client/src/models/interview-question-record.ts index 2f2ecd2b8..1a7883615 100644 --- a/lib/packages/fabro-api-client/src/models/interview-question-record.ts +++ b/lib/packages/fabro-api-client/src/models/interview-question-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/link-run-pull-request-request.ts b/lib/packages/fabro-api-client/src/models/link-run-pull-request-request.ts index ad2f7e508..ff4ec1d89 100644 --- a/lib/packages/fabro-api-client/src/models/link-run-pull-request-request.ts +++ b/lib/packages/fabro-api-client/src/models/link-run-pull-request-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/llm-output-kind.ts b/lib/packages/fabro-api-client/src/models/llm-output-kind.ts index 1c9663257..4dee9f9ff 100644 --- a/lib/packages/fabro-api-client/src/models/llm-output-kind.ts +++ b/lib/packages/fabro-api-client/src/models/llm-output-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/log-destination.ts b/lib/packages/fabro-api-client/src/models/log-destination.ts index 6e7caf66f..22ab4f10d 100644 --- a/lib/packages/fabro-api-client/src/models/log-destination.ts +++ b/lib/packages/fabro-api-client/src/models/log-destination.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/manifest-args.ts b/lib/packages/fabro-api-client/src/models/manifest-args.ts index c0ae3985e..1430fc35c 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-args.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-args.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 c501c3094..e1493fb49 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-config.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-config.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/manifest-file-entry.ts b/lib/packages/fabro-api-client/src/models/manifest-file-entry.ts index 8f2cfe38f..1a6edae4d 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-file-entry.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-file-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 e0a476878..5a966f00b 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 377b6e3ac..4b0182f72 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-goal.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-goal.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/manifest-target.ts b/lib/packages/fabro-api-client/src/models/manifest-target.ts index c78249f32..527b51e3b 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-target.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-target.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/manifest-workflow-config.ts b/lib/packages/fabro-api-client/src/models/manifest-workflow-config.ts index 960745f81..9f1e4692b 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-workflow-config.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-workflow-config.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/manifest-workflow.ts b/lib/packages/fabro-api-client/src/models/manifest-workflow.ts index 222092b7a..db9db35bb 100644 --- a/lib/packages/fabro-api-client/src/models/manifest-workflow.ts +++ b/lib/packages/fabro-api-client/src/models/manifest-workflow.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-http-protocol.ts b/lib/packages/fabro-api-client/src/models/mcp-http-protocol.ts index c03287667..b927e2418 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-http-protocol.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-http-protocol.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-list-meta.ts b/lib/packages/fabro-api-client/src/models/mcp-server-list-meta.ts index a90b708eb..8d1a82cbd 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-list-meta.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-list-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-list-response.ts b/lib/packages/fabro-api-client/src/models/mcp-server-list-response.ts index f1a6ffe39..85839b509 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-projection.ts b/lib/packages/fabro-api-client/src/models/mcp-server-projection.ts index 8b9f0e19e..6d6f01393 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-projection.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-settings.ts b/lib/packages/fabro-api-client/src/models/mcp-server-settings.ts index b84ea5675..e4f8ed723 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-settings.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-status-failed.ts b/lib/packages/fabro-api-client/src/models/mcp-server-status-failed.ts index acee4291f..c644eba1d 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-status-failed.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-status-failed.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-status-ready.ts b/lib/packages/fabro-api-client/src/models/mcp-server-status-ready.ts index ab82276ed..58dbbd421 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-status-ready.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-status-ready.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server-status.ts b/lib/packages/fabro-api-client/src/models/mcp-server-status.ts index 50af943f0..eb898822a 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server-status.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-server.ts b/lib/packages/fabro-api-client/src/models/mcp-server.ts index e791b7feb..163010400 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-server.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-server.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-http.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-http.ts index af9b8991c..61fafcc16 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-http.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-http.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-sandbox.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-sandbox.ts index e534632b9..e8f789f10 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-sandbox.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-sandbox.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-stdio.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-stdio.ts index 27a3d7270..6acdf9dde 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-stdio.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-stdio.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-view-http.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-view-http.ts index 724f99612..77739ba5d 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-view-http.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-view-http.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-view-sandbox.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-view-sandbox.ts index ea01a6cab..d0be5f749 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-view-sandbox.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-view-sandbox.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-view-stdio.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-view-stdio.ts index 03fd5665f..b48fb8e6d 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-view-stdio.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-view-stdio.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport-view.ts b/lib/packages/fabro-api-client/src/models/mcp-transport-view.ts index f9761b5a8..30dbd8ad7 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport-view.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport-view.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/mcp-transport.ts b/lib/packages/fabro-api-client/src/models/mcp-transport.ts index 611215bdd..cea33b117 100644 --- a/lib/packages/fabro-api-client/src/models/mcp-transport.ts +++ b/lib/packages/fabro-api-client/src/models/mcp-transport.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/merge-method.ts b/lib/packages/fabro-api-client/src/models/merge-method.ts index a5f0a71d7..425baf91e 100644 --- a/lib/packages/fabro-api-client/src/models/merge-method.ts +++ b/lib/packages/fabro-api-client/src/models/merge-method.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/merge-run-pull-request-request.ts b/lib/packages/fabro-api-client/src/models/merge-run-pull-request-request.ts index f86dea1ea..ac9f7d148 100644 --- a/lib/packages/fabro-api-client/src/models/merge-run-pull-request-request.ts +++ b/lib/packages/fabro-api-client/src/models/merge-run-pull-request-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/merge-run-pull-request-response.ts b/lib/packages/fabro-api-client/src/models/merge-run-pull-request-response.ts index 9dd748a21..eb473b1df 100644 --- a/lib/packages/fabro-api-client/src/models/merge-run-pull-request-response.ts +++ b/lib/packages/fabro-api-client/src/models/merge-run-pull-request-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/model-controls.ts b/lib/packages/fabro-api-client/src/models/model-controls.ts index 59f22ce2a..55babaee6 100644 --- a/lib/packages/fabro-api-client/src/models/model-controls.ts +++ b/lib/packages/fabro-api-client/src/models/model-controls.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 97ab64e48..511ee967f 100644 --- a/lib/packages/fabro-api-client/src/models/model-costs.ts +++ b/lib/packages/fabro-api-client/src/models/model-costs.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/model-features.ts b/lib/packages/fabro-api-client/src/models/model-features.ts index 5f23381b3..42fcae9d6 100644 --- a/lib/packages/fabro-api-client/src/models/model-features.ts +++ b/lib/packages/fabro-api-client/src/models/model-features.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 c915d36b5..ed22b4b40 100644 --- a/lib/packages/fabro-api-client/src/models/model-limits.ts +++ b/lib/packages/fabro-api-client/src/models/model-limits.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/model-reference.ts b/lib/packages/fabro-api-client/src/models/model-reference.ts index a8013e1e9..30a8eed69 100644 --- a/lib/packages/fabro-api-client/src/models/model-reference.ts +++ b/lib/packages/fabro-api-client/src/models/model-reference.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/model-test-mode.ts b/lib/packages/fabro-api-client/src/models/model-test-mode.ts index 2aca92dda..4e83d41dd 100644 --- a/lib/packages/fabro-api-client/src/models/model-test-mode.ts +++ b/lib/packages/fabro-api-client/src/models/model-test-mode.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 cba04c056..8d6bbe596 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/model.ts b/lib/packages/fabro-api-client/src/models/model.ts index 0bf86bee5..0de1f0971 100644 --- a/lib/packages/fabro-api-client/src/models/model.ts +++ b/lib/packages/fabro-api-client/src/models/model.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/notification-provider-settings.ts b/lib/packages/fabro-api-client/src/models/notification-provider-settings.ts index 9149b9342..d430995d7 100644 --- a/lib/packages/fabro-api-client/src/models/notification-provider-settings.ts +++ b/lib/packages/fabro-api-client/src/models/notification-provider-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/notification-route-settings.ts b/lib/packages/fabro-api-client/src/models/notification-route-settings.ts index 3e80ebd8c..1312f85e1 100644 --- a/lib/packages/fabro-api-client/src/models/notification-route-settings.ts +++ b/lib/packages/fabro-api-client/src/models/notification-route-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/object-store-local-settings.ts b/lib/packages/fabro-api-client/src/models/object-store-local-settings.ts index b16c42346..c0f138e6b 100644 --- a/lib/packages/fabro-api-client/src/models/object-store-local-settings.ts +++ b/lib/packages/fabro-api-client/src/models/object-store-local-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/object-store-s3-settings.ts b/lib/packages/fabro-api-client/src/models/object-store-s3-settings.ts index fb0550698..f82da9357 100644 --- a/lib/packages/fabro-api-client/src/models/object-store-s3-settings.ts +++ b/lib/packages/fabro-api-client/src/models/object-store-s3-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/object-store-settings.ts b/lib/packages/fabro-api-client/src/models/object-store-settings.ts index 2099b6752..c33939d8c 100644 --- a/lib/packages/fabro-api-client/src/models/object-store-settings.ts +++ b/lib/packages/fabro-api-client/src/models/object-store-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-api-question-list.ts b/lib/packages/fabro-api-client/src/models/paginated-api-question-list.ts index 8f5cb1a03..a246b2aa0 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-api-question-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-api-question-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-event-list.ts b/lib/packages/fabro-api-client/src/models/paginated-event-list.ts index cf2934f56..1d1dddd14 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-event-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-event-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-history-entry-list.ts b/lib/packages/fabro-api-client/src/models/paginated-history-entry-list.ts index c8c2661e7..3e1af07d1 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-history-entry-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-history-entry-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-model-list.ts b/lib/packages/fabro-api-client/src/models/paginated-model-list.ts index 2760f8335..abac7b698 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-model-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-model-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-run-commit-list.ts b/lib/packages/fabro-api-client/src/models/paginated-run-commit-list.ts index 1290d80d2..2ffb7f6d5 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-run-commit-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-run-commit-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-run-file-list.ts b/lib/packages/fabro-api-client/src/models/paginated-run-file-list.ts index 1d84791af..8c27bf6db 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-run-file-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-run-file-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-run-list.ts b/lib/packages/fabro-api-client/src/models/paginated-run-list.ts index 5aa510d61..df9965b8d 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-run-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-run-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-run-stage-list.ts b/lib/packages/fabro-api-client/src/models/paginated-run-stage-list.ts index 14862230b..4b6d2ff68 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-run-stage-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-run-stage-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-saved-query-list.ts b/lib/packages/fabro-api-client/src/models/paginated-saved-query-list.ts index 9af8533df..5d2df675a 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-saved-query-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-saved-query-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-session-list.ts b/lib/packages/fabro-api-client/src/models/paginated-session-list.ts index 25dc0cf9a..db90f4e6f 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-session-list.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-session-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/paginated-workflow-list-response.ts b/lib/packages/fabro-api-client/src/models/paginated-workflow-list-response.ts index 59e1a99c8..074575a22 100644 --- a/lib/packages/fabro-api-client/src/models/paginated-workflow-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/paginated-workflow-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pagination-meta.ts b/lib/packages/fabro-api-client/src/models/pagination-meta.ts index 963f781a4..c91ae9bb2 100644 --- a/lib/packages/fabro-api-client/src/models/pagination-meta.ts +++ b/lib/packages/fabro-api-client/src/models/pagination-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-message-record.ts b/lib/packages/fabro-api-client/src/models/pair-message-record.ts index d8d413209..1754e078f 100644 --- a/lib/packages/fabro-api-client/src/models/pair-message-record.ts +++ b/lib/packages/fabro-api-client/src/models/pair-message-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-message-request.ts b/lib/packages/fabro-api-client/src/models/pair-message-request.ts index 2a6607d94..435ec6dbf 100644 --- a/lib/packages/fabro-api-client/src/models/pair-message-request.ts +++ b/lib/packages/fabro-api-client/src/models/pair-message-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-record.ts b/lib/packages/fabro-api-client/src/models/pair-record.ts index 34b029029..aa34088d6 100644 --- a/lib/packages/fabro-api-client/src/models/pair-record.ts +++ b/lib/packages/fabro-api-client/src/models/pair-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-start-request.ts b/lib/packages/fabro-api-client/src/models/pair-start-request.ts index 73853b374..d5857d0c6 100644 --- a/lib/packages/fabro-api-client/src/models/pair-start-request.ts +++ b/lib/packages/fabro-api-client/src/models/pair-start-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-status.ts b/lib/packages/fabro-api-client/src/models/pair-status.ts index 8b64c2256..7b41c0481 100644 --- a/lib/packages/fabro-api-client/src/models/pair-status.ts +++ b/lib/packages/fabro-api-client/src/models/pair-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-target.ts b/lib/packages/fabro-api-client/src/models/pair-target.ts index 40513b26d..0ed0a7fa7 100644 --- a/lib/packages/fabro-api-client/src/models/pair-target.ts +++ b/lib/packages/fabro-api-client/src/models/pair-target.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-assistant-message.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-assistant-message.ts index b3d603fa4..ecb97f5b3 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-assistant-message.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-assistant-message.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-detail-ref.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-detail-ref.ts index 7c168a332..87ce0be57 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-detail-ref.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-detail-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-entry.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-entry.ts index a6e3b8aa2..9ff0f4cf6 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-entry.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-error.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-error.ts index ccab55770..f89f5f4ee 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-error.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-error.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-response-meta.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-response-meta.ts index 6638978f6..6669da69d 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-response-meta.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-response-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-response.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-response.ts index dfd8b6168..b12476ccd 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-response.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-system-message.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-system-message.ts index 674db665a..fa861fedd 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-system-message.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-system-message.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-tool-call.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-tool-call.ts index 3c37513f1..69eca69f0 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-tool-call.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-tool-call.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-user-message.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-user-message.ts index 756bd0617..eb1050b5c 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-user-message.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-user-message.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pair-transcript-warning.ts b/lib/packages/fabro-api-client/src/models/pair-transcript-warning.ts index 7c8cfb8b1..a746927f8 100644 --- a/lib/packages/fabro-api-client/src/models/pair-transcript-warning.ts +++ b/lib/packages/fabro-api-client/src/models/pair-transcript-warning.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/parallel-branch-result.ts b/lib/packages/fabro-api-client/src/models/parallel-branch-result.ts index c3177f58a..7ac5e797f 100644 --- a/lib/packages/fabro-api-client/src/models/parallel-branch-result.ts +++ b/lib/packages/fabro-api-client/src/models/parallel-branch-result.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pending-interview-record.ts b/lib/packages/fabro-api-client/src/models/pending-interview-record.ts index 8d98b95b8..91af37120 100644 --- a/lib/packages/fabro-api-client/src/models/pending-interview-record.ts +++ b/lib/packages/fabro-api-client/src/models/pending-interview-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pending-reason.ts b/lib/packages/fabro-api-client/src/models/pending-reason.ts index 50fbc7c07..dd973b250 100644 --- a/lib/packages/fabro-api-client/src/models/pending-reason.ts +++ b/lib/packages/fabro-api-client/src/models/pending-reason.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/permission-level.ts b/lib/packages/fabro-api-client/src/models/permission-level.ts index e006d64f8..b42f3f188 100644 --- a/lib/packages/fabro-api-client/src/models/permission-level.ts +++ b/lib/packages/fabro-api-client/src/models/permission-level.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/preflight-check-detail.ts b/lib/packages/fabro-api-client/src/models/preflight-check-detail.ts index 3d829c5f2..f4009ac51 100644 --- a/lib/packages/fabro-api-client/src/models/preflight-check-detail.ts +++ b/lib/packages/fabro-api-client/src/models/preflight-check-detail.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/preflight-check-report.ts b/lib/packages/fabro-api-client/src/models/preflight-check-report.ts index 081285402..bb5183a4e 100644 --- a/lib/packages/fabro-api-client/src/models/preflight-check-report.ts +++ b/lib/packages/fabro-api-client/src/models/preflight-check-report.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 a359c849e..2fc996da8 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/preflight-check-section.ts b/lib/packages/fabro-api-client/src/models/preflight-check-section.ts index db144176a..f071fd0de 100644 --- a/lib/packages/fabro-api-client/src/models/preflight-check-section.ts +++ b/lib/packages/fabro-api-client/src/models/preflight-check-section.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/preflight-response.ts b/lib/packages/fabro-api-client/src/models/preflight-response.ts index 2819d5dcd..4a57a488f 100644 --- a/lib/packages/fabro-api-client/src/models/preflight-response.ts +++ b/lib/packages/fabro-api-client/src/models/preflight-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 a840541ea..73323eeaf 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/prepared-command-step.ts b/lib/packages/fabro-api-client/src/models/prepared-command-step.ts index a707858dc..7ab394bbb 100644 --- a/lib/packages/fabro-api-client/src/models/prepared-command-step.ts +++ b/lib/packages/fabro-api-client/src/models/prepared-command-step.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/prepared-script-step.ts b/lib/packages/fabro-api-client/src/models/prepared-script-step.ts index 16a88d436..4c20de3be 100644 --- a/lib/packages/fabro-api-client/src/models/prepared-script-step.ts +++ b/lib/packages/fabro-api-client/src/models/prepared-script-step.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/prepared-step.ts b/lib/packages/fabro-api-client/src/models/prepared-step.ts index 21e5c57ec..a6e2b4572 100644 --- a/lib/packages/fabro-api-client/src/models/prepared-step.ts +++ b/lib/packages/fabro-api-client/src/models/prepared-step.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/preview-url-request.ts b/lib/packages/fabro-api-client/src/models/preview-url-request.ts index 1f6f4a934..777822744 100644 --- a/lib/packages/fabro-api-client/src/models/preview-url-request.ts +++ b/lib/packages/fabro-api-client/src/models/preview-url-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/preview-url-response.ts b/lib/packages/fabro-api-client/src/models/preview-url-response.ts index 904f29090..79f4955ed 100644 --- a/lib/packages/fabro-api-client/src/models/preview-url-response.ts +++ b/lib/packages/fabro-api-client/src/models/preview-url-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal-agent.ts b/lib/packages/fabro-api-client/src/models/principal-agent.ts index 61264b88d..7798084a1 100644 --- a/lib/packages/fabro-api-client/src/models/principal-agent.ts +++ b/lib/packages/fabro-api-client/src/models/principal-agent.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal-slack.ts b/lib/packages/fabro-api-client/src/models/principal-slack.ts index 61ab4c2d3..400111544 100644 --- a/lib/packages/fabro-api-client/src/models/principal-slack.ts +++ b/lib/packages/fabro-api-client/src/models/principal-slack.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal-system.ts b/lib/packages/fabro-api-client/src/models/principal-system.ts index ec4e5562d..674d02929 100644 --- a/lib/packages/fabro-api-client/src/models/principal-system.ts +++ b/lib/packages/fabro-api-client/src/models/principal-system.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal-user.ts b/lib/packages/fabro-api-client/src/models/principal-user.ts index c92be9530..46f948ea9 100644 --- a/lib/packages/fabro-api-client/src/models/principal-user.ts +++ b/lib/packages/fabro-api-client/src/models/principal-user.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal-webhook.ts b/lib/packages/fabro-api-client/src/models/principal-webhook.ts index a2aae6f71..6f4203890 100644 --- a/lib/packages/fabro-api-client/src/models/principal-webhook.ts +++ b/lib/packages/fabro-api-client/src/models/principal-webhook.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal-worker.ts b/lib/packages/fabro-api-client/src/models/principal-worker.ts index feece9215..fd00c0792 100644 --- a/lib/packages/fabro-api-client/src/models/principal-worker.ts +++ b/lib/packages/fabro-api-client/src/models/principal-worker.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/principal.ts b/lib/packages/fabro-api-client/src/models/principal.ts index 08b5422df..cb55cb486 100644 --- a/lib/packages/fabro-api-client/src/models/principal.ts +++ b/lib/packages/fabro-api-client/src/models/principal.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/project-namespace.ts b/lib/packages/fabro-api-client/src/models/project-namespace.ts index 80081d94e..cd3de0053 100644 --- a/lib/packages/fabro-api-client/src/models/project-namespace.ts +++ b/lib/packages/fabro-api-client/src/models/project-namespace.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-credential-test-request.ts b/lib/packages/fabro-api-client/src/models/provider-credential-test-request.ts index 390b00848..687a2afd7 100644 --- a/lib/packages/fabro-api-client/src/models/provider-credential-test-request.ts +++ b/lib/packages/fabro-api-client/src/models/provider-credential-test-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-credential-test-response.ts b/lib/packages/fabro-api-client/src/models/provider-credential-test-response.ts index b74a688eb..48973ece1 100644 --- a/lib/packages/fabro-api-client/src/models/provider-credential-test-response.ts +++ b/lib/packages/fabro-api-client/src/models/provider-credential-test-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-list.ts b/lib/packages/fabro-api-client/src/models/provider-list.ts index dd58863c5..335e7dc55 100644 --- a/lib/packages/fabro-api-client/src/models/provider-list.ts +++ b/lib/packages/fabro-api-client/src/models/provider-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-test-list.ts b/lib/packages/fabro-api-client/src/models/provider-test-list.ts index 6235bbd5d..257a40ec7 100644 --- a/lib/packages/fabro-api-client/src/models/provider-test-list.ts +++ b/lib/packages/fabro-api-client/src/models/provider-test-list.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-test-result.ts b/lib/packages/fabro-api-client/src/models/provider-test-result.ts index 0a34c894b..afe8b63a8 100644 --- a/lib/packages/fabro-api-client/src/models/provider-test-result.ts +++ b/lib/packages/fabro-api-client/src/models/provider-test-result.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-test-status.ts b/lib/packages/fabro-api-client/src/models/provider-test-status.ts index fce18e021..866c2c509 100644 --- a/lib/packages/fabro-api-client/src/models/provider-test-status.ts +++ b/lib/packages/fabro-api-client/src/models/provider-test-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider-test-summary.ts b/lib/packages/fabro-api-client/src/models/provider-test-summary.ts index 0c3622fa5..93f635260 100644 --- a/lib/packages/fabro-api-client/src/models/provider-test-summary.ts +++ b/lib/packages/fabro-api-client/src/models/provider-test-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/provider.ts b/lib/packages/fabro-api-client/src/models/provider.ts index 901f1ca37..ae5be76c3 100644 --- a/lib/packages/fabro-api-client/src/models/provider.ts +++ b/lib/packages/fabro-api-client/src/models/provider.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/prune-run-entry.ts b/lib/packages/fabro-api-client/src/models/prune-run-entry.ts index ddcf261b9..c184b6267 100644 --- a/lib/packages/fabro-api-client/src/models/prune-run-entry.ts +++ b/lib/packages/fabro-api-client/src/models/prune-run-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/prune-runs-request.ts b/lib/packages/fabro-api-client/src/models/prune-runs-request.ts index 1d1a8f058..237af45eb 100644 --- a/lib/packages/fabro-api-client/src/models/prune-runs-request.ts +++ b/lib/packages/fabro-api-client/src/models/prune-runs-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 ca62198ba..c8c9df486 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-creation-status.ts b/lib/packages/fabro-api-client/src/models/pull-request-creation-status.ts index f6e5a3941..3be08ee5e 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-creation-status.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-creation-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-creation.ts b/lib/packages/fabro-api-client/src/models/pull-request-creation.ts index fd1db4d0e..f36ddf38d 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-creation.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-creation.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-details-status.ts b/lib/packages/fabro-api-client/src/models/pull-request-details-status.ts index 03f4c1cdc..fc713327e 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-details-status.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-details-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-details-timestamps.ts b/lib/packages/fabro-api-client/src/models/pull-request-details-timestamps.ts index 79a699d36..19d6b9329 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-details-timestamps.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-details-timestamps.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-details-unavailable-reason.ts b/lib/packages/fabro-api-client/src/models/pull-request-details-unavailable-reason.ts index 8bb87c59e..166550715 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-details-unavailable-reason.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-details-unavailable-reason.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-details.ts b/lib/packages/fabro-api-client/src/models/pull-request-details.ts index e871d9563..f12541381 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-details.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-details.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-link.ts b/lib/packages/fabro-api-client/src/models/pull-request-link.ts index 8cf17711f..5fa46bcd5 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-link.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-link.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-meta.ts b/lib/packages/fabro-api-client/src/models/pull-request-meta.ts index 84bcf981f..8914d163a 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-meta.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-ref.ts b/lib/packages/fabro-api-client/src/models/pull-request-ref.ts index c96b40d42..976abe21f 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-ref.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-response.ts b/lib/packages/fabro-api-client/src/models/pull-request-response.ts index 9f6eff305..a710d1070 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-response.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-settings.ts b/lib/packages/fabro-api-client/src/models/pull-request-settings.ts index 55a41c8ba..279068caa 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-settings.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request-user.ts b/lib/packages/fabro-api-client/src/models/pull-request-user.ts index e50e4a631..460a268de 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request-user.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request-user.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/pull-request.ts b/lib/packages/fabro-api-client/src/models/pull-request.ts index a67061450..38dc8f0ad 100644 --- a/lib/packages/fabro-api-client/src/models/pull-request.ts +++ b/lib/packages/fabro-api-client/src/models/pull-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/question-type.ts b/lib/packages/fabro-api-client/src/models/question-type.ts index a40eda259..fc7caeedf 100644 --- a/lib/packages/fabro-api-client/src/models/question-type.ts +++ b/lib/packages/fabro-api-client/src/models/question-type.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/reasoning-effort-feature.ts b/lib/packages/fabro-api-client/src/models/reasoning-effort-feature.ts index 1aa9d6734..f7de9a438 100644 --- a/lib/packages/fabro-api-client/src/models/reasoning-effort-feature.ts +++ b/lib/packages/fabro-api-client/src/models/reasoning-effort-feature.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/reasoning-effort.ts b/lib/packages/fabro-api-client/src/models/reasoning-effort.ts index 66644a073..adb8c1398 100644 --- a/lib/packages/fabro-api-client/src/models/reasoning-effort.ts +++ b/lib/packages/fabro-api-client/src/models/reasoning-effort.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/reasoning-output-trace-only.ts b/lib/packages/fabro-api-client/src/models/reasoning-output-trace-only.ts index 8f757fddf..6199fc17a 100644 --- a/lib/packages/fabro-api-client/src/models/reasoning-output-trace-only.ts +++ b/lib/packages/fabro-api-client/src/models/reasoning-output-trace-only.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/reasoning-output-with-summary.ts b/lib/packages/fabro-api-client/src/models/reasoning-output-with-summary.ts index c93d38405..92f212bdd 100644 --- a/lib/packages/fabro-api-client/src/models/reasoning-output-with-summary.ts +++ b/lib/packages/fabro-api-client/src/models/reasoning-output-with-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/reasoning-output.ts b/lib/packages/fabro-api-client/src/models/reasoning-output.ts index b2c60fb2c..118a66d72 100644 --- a/lib/packages/fabro-api-client/src/models/reasoning-output.ts +++ b/lib/packages/fabro-api-client/src/models/reasoning-output.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/related-workflow-diagnostic.ts b/lib/packages/fabro-api-client/src/models/related-workflow-diagnostic.ts index 5e80bfb6b..dd4e79204 100644 --- a/lib/packages/fabro-api-client/src/models/related-workflow-diagnostic.ts +++ b/lib/packages/fabro-api-client/src/models/related-workflow-diagnostic.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/render-workflow-graph-direction.ts b/lib/packages/fabro-api-client/src/models/render-workflow-graph-direction.ts index 097c833ad..564a8fe17 100644 --- a/lib/packages/fabro-api-client/src/models/render-workflow-graph-direction.ts +++ b/lib/packages/fabro-api-client/src/models/render-workflow-graph-direction.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/render-workflow-graph-format.ts b/lib/packages/fabro-api-client/src/models/render-workflow-graph-format.ts index fffd9ab43..65f98e596 100644 --- a/lib/packages/fabro-api-client/src/models/render-workflow-graph-format.ts +++ b/lib/packages/fabro-api-client/src/models/render-workflow-graph-format.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/render-workflow-graph-request.ts b/lib/packages/fabro-api-client/src/models/render-workflow-graph-request.ts index f2064b906..5f16ac057 100644 --- a/lib/packages/fabro-api-client/src/models/render-workflow-graph-request.ts +++ b/lib/packages/fabro-api-client/src/models/render-workflow-graph-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/replace-automation-request.ts b/lib/packages/fabro-api-client/src/models/replace-automation-request.ts index 49a5533f4..4b3b02555 100644 --- a/lib/packages/fabro-api-client/src/models/replace-automation-request.ts +++ b/lib/packages/fabro-api-client/src/models/replace-automation-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/replace-environment-request.ts b/lib/packages/fabro-api-client/src/models/replace-environment-request.ts index bddac795e..5fb4554b1 100644 --- a/lib/packages/fabro-api-client/src/models/replace-environment-request.ts +++ b/lib/packages/fabro-api-client/src/models/replace-environment-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/replace-mcp-server-request.ts b/lib/packages/fabro-api-client/src/models/replace-mcp-server-request.ts index 3efb9cf8b..fc1b5c2d0 100644 --- a/lib/packages/fabro-api-client/src/models/replace-mcp-server-request.ts +++ b/lib/packages/fabro-api-client/src/models/replace-mcp-server-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/repo-check-response-permissions.ts b/lib/packages/fabro-api-client/src/models/repo-check-response-permissions.ts index 7ef36c796..55e5a8f7b 100644 --- a/lib/packages/fabro-api-client/src/models/repo-check-response-permissions.ts +++ b/lib/packages/fabro-api-client/src/models/repo-check-response-permissions.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 e61d1558f..d36ecfbe2 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/repository-ref.ts b/lib/packages/fabro-api-client/src/models/repository-ref.ts index 1c9652e82..68ce062c6 100644 --- a/lib/packages/fabro-api-client/src/models/repository-ref.ts +++ b/lib/packages/fabro-api-client/src/models/repository-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/review-target-kind.ts b/lib/packages/fabro-api-client/src/models/review-target-kind.ts index e50c78a38..37cf9b3e3 100644 --- a/lib/packages/fabro-api-client/src/models/review-target-kind.ts +++ b/lib/packages/fabro-api-client/src/models/review-target-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/review-target.ts b/lib/packages/fabro-api-client/src/models/review-target.ts index 61b476d21..0b4a883ff 100644 --- a/lib/packages/fabro-api-client/src/models/review-target.ts +++ b/lib/packages/fabro-api-client/src/models/review-target.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/rewind-request.ts b/lib/packages/fabro-api-client/src/models/rewind-request.ts index 50e6072f2..ade0f4f4c 100644 --- a/lib/packages/fabro-api-client/src/models/rewind-request.ts +++ b/lib/packages/fabro-api-client/src/models/rewind-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/rewind-response.ts b/lib/packages/fabro-api-client/src/models/rewind-response.ts index 527c0e62f..45a5b7179 100644 --- a/lib/packages/fabro-api-client/src/models/rewind-response.ts +++ b/lib/packages/fabro-api-client/src/models/rewind-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/root-response-urls.ts b/lib/packages/fabro-api-client/src/models/root-response-urls.ts index 7f09efd4d..0caa27dcd 100644 --- a/lib/packages/fabro-api-client/src/models/root-response-urls.ts +++ b/lib/packages/fabro-api-client/src/models/root-response-urls.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/root-response.ts b/lib/packages/fabro-api-client/src/models/root-response.ts index cc29060ab..6ffd8144f 100644 --- a/lib/packages/fabro-api-client/src/models/root-response.ts +++ b/lib/packages/fabro-api-client/src/models/root-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-agent-settings.ts b/lib/packages/fabro-api-client/src/models/run-agent-settings.ts index 044c251c8..be5774084 100644 --- a/lib/packages/fabro-api-client/src/models/run-agent-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-agent-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-approval-state.ts b/lib/packages/fabro-api-client/src/models/run-approval-state.ts index 4345fa4aa..c13c90e5e 100644 --- a/lib/packages/fabro-api-client/src/models/run-approval-state.ts +++ b/lib/packages/fabro-api-client/src/models/run-approval-state.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-approval.ts b/lib/packages/fabro-api-client/src/models/run-approval.ts index 639d6d4df..45fc161e4 100644 --- a/lib/packages/fabro-api-client/src/models/run-approval.ts +++ b/lib/packages/fabro-api-client/src/models/run-approval.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-artifact-entry.ts b/lib/packages/fabro-api-client/src/models/run-artifact-entry.ts index d88afb21a..f655c5dfc 100644 --- a/lib/packages/fabro-api-client/src/models/run-artifact-entry.ts +++ b/lib/packages/fabro-api-client/src/models/run-artifact-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-artifact-list-response.ts b/lib/packages/fabro-api-client/src/models/run-artifact-list-response.ts index 74ed37164..d8b0c7d01 100644 --- a/lib/packages/fabro-api-client/src/models/run-artifact-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/run-artifact-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-billing-stage.ts b/lib/packages/fabro-api-client/src/models/run-billing-stage.ts index 6238e97c8..5db2989dd 100644 --- a/lib/packages/fabro-api-client/src/models/run-billing-stage.ts +++ b/lib/packages/fabro-api-client/src/models/run-billing-stage.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-billing-summary.ts b/lib/packages/fabro-api-client/src/models/run-billing-summary.ts index 4e0cb5ee7..c573d568d 100644 --- a/lib/packages/fabro-api-client/src/models/run-billing-summary.ts +++ b/lib/packages/fabro-api-client/src/models/run-billing-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 68861f7f8..66e64f64a 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-billing.ts b/lib/packages/fabro-api-client/src/models/run-billing.ts index 7bf377d78..77cab4145 100644 --- a/lib/packages/fabro-api-client/src/models/run-billing.ts +++ b/lib/packages/fabro-api-client/src/models/run-billing.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-branch-settings.ts b/lib/packages/fabro-api-client/src/models/run-branch-settings.ts index 1805c3f2b..b1c62222c 100644 --- a/lib/packages/fabro-api-client/src/models/run-branch-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-branch-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-checkpoint-settings.ts b/lib/packages/fabro-api-client/src/models/run-checkpoint-settings.ts index 4af156da7..2342ac774 100644 --- a/lib/packages/fabro-api-client/src/models/run-checkpoint-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-checkpoint-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-checkpoint.ts b/lib/packages/fabro-api-client/src/models/run-checkpoint.ts index 3bc50540b..1d6481b7e 100644 --- a/lib/packages/fabro-api-client/src/models/run-checkpoint.ts +++ b/lib/packages/fabro-api-client/src/models/run-checkpoint.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-client-provenance.ts b/lib/packages/fabro-api-client/src/models/run-client-provenance.ts index f1645f81f..647aec1bf 100644 --- a/lib/packages/fabro-api-client/src/models/run-client-provenance.ts +++ b/lib/packages/fabro-api-client/src/models/run-client-provenance.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-clone-settings.ts b/lib/packages/fabro-api-client/src/models/run-clone-settings.ts index 4c4b6a657..7258d9d8d 100644 --- a/lib/packages/fabro-api-client/src/models/run-clone-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-clone-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-commit-parent.ts b/lib/packages/fabro-api-client/src/models/run-commit-parent.ts index 1cc1cea61..479b5232f 100644 --- a/lib/packages/fabro-api-client/src/models/run-commit-parent.ts +++ b/lib/packages/fabro-api-client/src/models/run-commit-parent.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-commit-person.ts b/lib/packages/fabro-api-client/src/models/run-commit-person.ts index 6a33f0ce6..1eabb61b6 100644 --- a/lib/packages/fabro-api-client/src/models/run-commit-person.ts +++ b/lib/packages/fabro-api-client/src/models/run-commit-person.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-commit.ts b/lib/packages/fabro-api-client/src/models/run-commit.ts index f0b033ffc..34ad5dad0 100644 --- a/lib/packages/fabro-api-client/src/models/run-commit.ts +++ b/lib/packages/fabro-api-client/src/models/run-commit.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-commits-meta.ts b/lib/packages/fabro-api-client/src/models/run-commits-meta.ts index 06730f348..7ecfcb7a5 100644 --- a/lib/packages/fabro-api-client/src/models/run-commits-meta.ts +++ b/lib/packages/fabro-api-client/src/models/run-commits-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-control-action.ts b/lib/packages/fabro-api-client/src/models/run-control-action.ts index c68e17dec..93434cbe2 100644 --- a/lib/packages/fabro-api-client/src/models/run-control-action.ts +++ b/lib/packages/fabro-api-client/src/models/run-control-action.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-diff.ts b/lib/packages/fabro-api-client/src/models/run-diff.ts index 6b740259f..b625efafa 100644 --- a/lib/packages/fabro-api-client/src/models/run-diff.ts +++ b/lib/packages/fabro-api-client/src/models/run-diff.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-environment-settings.ts b/lib/packages/fabro-api-client/src/models/run-environment-settings.ts index b5eafa3d2..5ee20ffc0 100644 --- a/lib/packages/fabro-api-client/src/models/run-environment-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-environment-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-error.ts b/lib/packages/fabro-api-client/src/models/run-error.ts index 3367acc39..7f08f6498 100644 --- a/lib/packages/fabro-api-client/src/models/run-error.ts +++ b/lib/packages/fabro-api-client/src/models/run-error.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-event-detail-response-content.ts b/lib/packages/fabro-api-client/src/models/run-event-detail-response-content.ts index 211dcc46e..cdbf7a8a3 100644 --- a/lib/packages/fabro-api-client/src/models/run-event-detail-response-content.ts +++ b/lib/packages/fabro-api-client/src/models/run-event-detail-response-content.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-event-detail-response-event.ts b/lib/packages/fabro-api-client/src/models/run-event-detail-response-event.ts index b5f059e07..0214b752b 100644 --- a/lib/packages/fabro-api-client/src/models/run-event-detail-response-event.ts +++ b/lib/packages/fabro-api-client/src/models/run-event-detail-response-event.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-event-detail-response.ts b/lib/packages/fabro-api-client/src/models/run-event-detail-response.ts index 3d50004b6..800c08039 100644 --- a/lib/packages/fabro-api-client/src/models/run-event-detail-response.ts +++ b/lib/packages/fabro-api-client/src/models/run-event-detail-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 073afd03b..a27df1702 100644 --- a/lib/packages/fabro-api-client/src/models/run-event.ts +++ b/lib/packages/fabro-api-client/src/models/run-event.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-execution-settings.ts b/lib/packages/fabro-api-client/src/models/run-execution-settings.ts index 0508d2646..e68d95c32 100644 --- a/lib/packages/fabro-api-client/src/models/run-execution-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-execution-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-failure.ts b/lib/packages/fabro-api-client/src/models/run-failure.ts index 114e172db..ceb7c8cf3 100644 --- a/lib/packages/fabro-api-client/src/models/run-failure.ts +++ b/lib/packages/fabro-api-client/src/models/run-failure.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-files-meta.ts b/lib/packages/fabro-api-client/src/models/run-files-meta.ts index 2e095d758..83d95b836 100644 --- a/lib/packages/fabro-api-client/src/models/run-files-meta.ts +++ b/lib/packages/fabro-api-client/src/models/run-files-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-git-settings.ts b/lib/packages/fabro-api-client/src/models/run-git-settings.ts index 2d390957b..5007209e3 100644 --- a/lib/packages/fabro-api-client/src/models/run-git-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-git-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-goal-file.ts b/lib/packages/fabro-api-client/src/models/run-goal-file.ts index a2b0052ef..64dc5c3f2 100644 --- a/lib/packages/fabro-api-client/src/models/run-goal-file.ts +++ b/lib/packages/fabro-api-client/src/models/run-goal-file.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-goal-inline.ts b/lib/packages/fabro-api-client/src/models/run-goal-inline.ts index d0afe3a11..9c2deb82b 100644 --- a/lib/packages/fabro-api-client/src/models/run-goal-inline.ts +++ b/lib/packages/fabro-api-client/src/models/run-goal-inline.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-goal.ts b/lib/packages/fabro-api-client/src/models/run-goal.ts index 560389840..7b28656f1 100644 --- a/lib/packages/fabro-api-client/src/models/run-goal.ts +++ b/lib/packages/fabro-api-client/src/models/run-goal.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-integrations-github-settings.ts b/lib/packages/fabro-api-client/src/models/run-integrations-github-settings.ts index 88df508a5..a28ae5b4b 100644 --- a/lib/packages/fabro-api-client/src/models/run-integrations-github-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-integrations-github-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-integrations-settings.ts b/lib/packages/fabro-api-client/src/models/run-integrations-settings.ts index 4bf715c94..28c4f5cc8 100644 --- a/lib/packages/fabro-api-client/src/models/run-integrations-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-integrations-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-interviews-settings.ts b/lib/packages/fabro-api-client/src/models/run-interviews-settings.ts index 5d7108e20..b01a6bbd9 100644 --- a/lib/packages/fabro-api-client/src/models/run-interviews-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-interviews-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-lifecycle.ts b/lib/packages/fabro-api-client/src/models/run-lifecycle.ts index ca44ba35e..13e2c22b6 100644 --- a/lib/packages/fabro-api-client/src/models/run-lifecycle.ts +++ b/lib/packages/fabro-api-client/src/models/run-lifecycle.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-links.ts b/lib/packages/fabro-api-client/src/models/run-links.ts index ac0336dd7..7c645794b 100644 --- a/lib/packages/fabro-api-client/src/models/run-links.ts +++ b/lib/packages/fabro-api-client/src/models/run-links.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 6c2813065..0ad1ff4d7 100644 --- a/lib/packages/fabro-api-client/src/models/run-manifest.ts +++ b/lib/packages/fabro-api-client/src/models/run-manifest.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-meta-branch-settings.ts b/lib/packages/fabro-api-client/src/models/run-meta-branch-settings.ts index 950734a44..ffb69731a 100644 --- a/lib/packages/fabro-api-client/src/models/run-meta-branch-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-meta-branch-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-mode.ts b/lib/packages/fabro-api-client/src/models/run-mode.ts index 4a8ab07e2..1a21817ae 100644 --- a/lib/packages/fabro-api-client/src/models/run-mode.ts +++ b/lib/packages/fabro-api-client/src/models/run-mode.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-model-controls.ts b/lib/packages/fabro-api-client/src/models/run-model-controls.ts index 5d60f0fa4..770bb3493 100644 --- a/lib/packages/fabro-api-client/src/models/run-model-controls.ts +++ b/lib/packages/fabro-api-client/src/models/run-model-controls.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-model-settings.ts b/lib/packages/fabro-api-client/src/models/run-model-settings.ts index 599b6a26a..82b7c0798 100644 --- a/lib/packages/fabro-api-client/src/models/run-model-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-model-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-model.ts b/lib/packages/fabro-api-client/src/models/run-model.ts index 261182e70..518f3bb71 100644 --- a/lib/packages/fabro-api-client/src/models/run-model.ts +++ b/lib/packages/fabro-api-client/src/models/run-model.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-namespace.ts b/lib/packages/fabro-api-client/src/models/run-namespace.ts index cea567a72..19a89a218 100644 --- a/lib/packages/fabro-api-client/src/models/run-namespace.ts +++ b/lib/packages/fabro-api-client/src/models/run-namespace.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-origin.ts b/lib/packages/fabro-api-client/src/models/run-origin.ts index fe4a05773..a03407dd7 100644 --- a/lib/packages/fabro-api-client/src/models/run-origin.ts +++ b/lib/packages/fabro-api-client/src/models/run-origin.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-pair-status-response.ts b/lib/packages/fabro-api-client/src/models/run-pair-status-response.ts index 5bf9a5adc..4d2d987a8 100644 --- a/lib/packages/fabro-api-client/src/models/run-pair-status-response.ts +++ b/lib/packages/fabro-api-client/src/models/run-pair-status-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-prepare-settings.ts b/lib/packages/fabro-api-client/src/models/run-prepare-settings.ts index 48a4b75fa..26900c950 100644 --- a/lib/packages/fabro-api-client/src/models/run-prepare-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-prepare-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 bd527066f..2f679a012 100644 --- a/lib/packages/fabro-api-client/src/models/run-projection.ts +++ b/lib/packages/fabro-api-client/src/models/run-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-provenance.ts b/lib/packages/fabro-api-client/src/models/run-provenance.ts index 59fa7a063..525391cc5 100644 --- a/lib/packages/fabro-api-client/src/models/run-provenance.ts +++ b/lib/packages/fabro-api-client/src/models/run-provenance.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-question.ts b/lib/packages/fabro-api-client/src/models/run-question.ts index 9ad4b72fd..a4dc008e5 100644 --- a/lib/packages/fabro-api-client/src/models/run-question.ts +++ b/lib/packages/fabro-api-client/src/models/run-question.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-reference.ts b/lib/packages/fabro-api-client/src/models/run-reference.ts index 890d55119..2f1d853df 100644 --- a/lib/packages/fabro-api-client/src/models/run-reference.ts +++ b/lib/packages/fabro-api-client/src/models/run-reference.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-runnable-source.ts b/lib/packages/fabro-api-client/src/models/run-runnable-source.ts index 88d1bd649..35d0db75b 100644 --- a/lib/packages/fabro-api-client/src/models/run-runnable-source.ts +++ b/lib/packages/fabro-api-client/src/models/run-runnable-source.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-sandbox-failure.ts b/lib/packages/fabro-api-client/src/models/run-sandbox-failure.ts index c30582f99..a72e0117d 100644 --- a/lib/packages/fabro-api-client/src/models/run-sandbox-failure.ts +++ b/lib/packages/fabro-api-client/src/models/run-sandbox-failure.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-sandbox-instance.ts b/lib/packages/fabro-api-client/src/models/run-sandbox-instance.ts index 1fd11d41c..9b526b4bd 100644 --- a/lib/packages/fabro-api-client/src/models/run-sandbox-instance.ts +++ b/lib/packages/fabro-api-client/src/models/run-sandbox-instance.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-sandbox-kind.ts b/lib/packages/fabro-api-client/src/models/run-sandbox-kind.ts index 5839dafad..2dbcc46d0 100644 --- a/lib/packages/fabro-api-client/src/models/run-sandbox-kind.ts +++ b/lib/packages/fabro-api-client/src/models/run-sandbox-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-sandbox-plan.ts b/lib/packages/fabro-api-client/src/models/run-sandbox-plan.ts index 6a7e2d032..9ea86deff 100644 --- a/lib/packages/fabro-api-client/src/models/run-sandbox-plan.ts +++ b/lib/packages/fabro-api-client/src/models/run-sandbox-plan.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-sandbox-runtime.ts b/lib/packages/fabro-api-client/src/models/run-sandbox-runtime.ts index 24807703a..003a25cea 100644 --- a/lib/packages/fabro-api-client/src/models/run-sandbox-runtime.ts +++ b/lib/packages/fabro-api-client/src/models/run-sandbox-runtime.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-sandbox.ts b/lib/packages/fabro-api-client/src/models/run-sandbox.ts index 12c15b34f..c6df6dd0f 100644 --- a/lib/packages/fabro-api-client/src/models/run-sandbox.ts +++ b/lib/packages/fabro-api-client/src/models/run-sandbox.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-scm-settings.ts b/lib/packages/fabro-api-client/src/models/run-scm-settings.ts index f0970dcec..65a2a364e 100644 --- a/lib/packages/fabro-api-client/src/models/run-scm-settings.ts +++ b/lib/packages/fabro-api-client/src/models/run-scm-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-server-provenance.ts b/lib/packages/fabro-api-client/src/models/run-server-provenance.ts index 8acad6eb4..df303739c 100644 --- a/lib/packages/fabro-api-client/src/models/run-server-provenance.ts +++ b/lib/packages/fabro-api-client/src/models/run-server-provenance.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-size.ts b/lib/packages/fabro-api-client/src/models/run-size.ts index e1a4b60f2..a1c40398f 100644 --- a/lib/packages/fabro-api-client/src/models/run-size.ts +++ b/lib/packages/fabro-api-client/src/models/run-size.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-spec.ts b/lib/packages/fabro-api-client/src/models/run-spec.ts index 6abad2884..4797dc2ad 100644 --- a/lib/packages/fabro-api-client/src/models/run-spec.ts +++ b/lib/packages/fabro-api-client/src/models/run-spec.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-stage.ts b/lib/packages/fabro-api-client/src/models/run-stage.ts index 442753331..cb976f5c0 100644 --- a/lib/packages/fabro-api-client/src/models/run-stage.ts +++ b/lib/packages/fabro-api-client/src/models/run-stage.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-blocked.ts b/lib/packages/fabro-api-client/src/models/run-status-blocked.ts index 659a28a05..e71c51ce8 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-blocked.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-blocked.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-dead.ts b/lib/packages/fabro-api-client/src/models/run-status-dead.ts index 422710ef5..a05b36986 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-dead.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-dead.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-failed.ts b/lib/packages/fabro-api-client/src/models/run-status-failed.ts index 36b9dbeec..6b7642e3a 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-failed.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-failed.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-paused.ts b/lib/packages/fabro-api-client/src/models/run-status-paused.ts index 4ee7870a9..c99d8b558 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-paused.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-paused.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-pending.ts b/lib/packages/fabro-api-client/src/models/run-status-pending.ts index f2e1e3f91..b442a13e4 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-pending.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-pending.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-removing.ts b/lib/packages/fabro-api-client/src/models/run-status-removing.ts index 94935af9b..bcddd38cc 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-removing.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-removing.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-runnable.ts b/lib/packages/fabro-api-client/src/models/run-status-runnable.ts index 08141c460..dfcef94c4 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-runnable.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-runnable.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-running.ts b/lib/packages/fabro-api-client/src/models/run-status-running.ts index b9347f7a1..608e9216f 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-running.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-running.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-starting.ts b/lib/packages/fabro-api-client/src/models/run-status-starting.ts index 85b5ae96b..a9d38b3ff 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-starting.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-starting.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-submitted.ts b/lib/packages/fabro-api-client/src/models/run-status-submitted.ts index fba39f37a..56903e07b 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-submitted.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-submitted.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status-succeeded.ts b/lib/packages/fabro-api-client/src/models/run-status-succeeded.ts index 6d2c1bced..bca6666af 100644 --- a/lib/packages/fabro-api-client/src/models/run-status-succeeded.ts +++ b/lib/packages/fabro-api-client/src/models/run-status-succeeded.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-status.ts b/lib/packages/fabro-api-client/src/models/run-status.ts index 75c85f149..f04558848 100644 --- a/lib/packages/fabro-api-client/src/models/run-status.ts +++ b/lib/packages/fabro-api-client/src/models/run-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-superseded-by-props.ts b/lib/packages/fabro-api-client/src/models/run-superseded-by-props.ts index 49cfa9fa6..f27d4a85f 100644 --- a/lib/packages/fabro-api-client/src/models/run-superseded-by-props.ts +++ b/lib/packages/fabro-api-client/src/models/run-superseded-by-props.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-timestamps.ts b/lib/packages/fabro-api-client/src/models/run-timestamps.ts index abb59f410..c6c0b5759 100644 --- a/lib/packages/fabro-api-client/src/models/run-timestamps.ts +++ b/lib/packages/fabro-api-client/src/models/run-timestamps.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run-timing.ts b/lib/packages/fabro-api-client/src/models/run-timing.ts index f0344e5d3..0608f7c5c 100644 --- a/lib/packages/fabro-api-client/src/models/run-timing.ts +++ b/lib/packages/fabro-api-client/src/models/run-timing.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/run.ts b/lib/packages/fabro-api-client/src/models/run.ts index a4ade38a3..5771f15c2 100644 --- a/lib/packages/fabro-api-client/src/models/run.ts +++ b/lib/packages/fabro-api-client/src/models/run.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-details.ts b/lib/packages/fabro-api-client/src/models/sandbox-details.ts index 016fd2661..63075bcc9 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-details.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-details.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-file-entry.ts b/lib/packages/fabro-api-client/src/models/sandbox-file-entry.ts index ccc44e7e9..6189c5e05 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-file-entry.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-file-entry.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-file-list-response.ts b/lib/packages/fabro-api-client/src/models/sandbox-file-list-response.ts index 21ce28514..5056f949d 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-file-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-file-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-info.ts b/lib/packages/fabro-api-client/src/models/sandbox-info.ts index 9f026d745..6f7a8b71c 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-info.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-info.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-list-meta.ts b/lib/packages/fabro-api-client/src/models/sandbox-list-meta.ts index a8258b994..fbaf87e58 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-list-meta.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-list-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-list-response.ts b/lib/packages/fabro-api-client/src/models/sandbox-list-response.ts index 7ac3f6824..b4c93f957 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-network-policy-mode.ts b/lib/packages/fabro-api-client/src/models/sandbox-network-policy-mode.ts index 0579ee087..3a208c284 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-network-policy-mode.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-network-policy-mode.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-network-policy.ts b/lib/packages/fabro-api-client/src/models/sandbox-network-policy.ts index da49f0397..b26016a62 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-network-policy.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-network-policy.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-network.ts b/lib/packages/fabro-api-client/src/models/sandbox-network.ts index 91b5d8e1d..e378225e2 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-network.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-network.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-provider-kind.ts b/lib/packages/fabro-api-client/src/models/sandbox-provider-kind.ts index 57f0c222c..f92894dfd 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-provider-kind.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-provider-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-provider-lookup-error.ts b/lib/packages/fabro-api-client/src/models/sandbox-provider-lookup-error.ts index d5fee5806..c7f8b4fe5 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-provider-lookup-error.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-provider-lookup-error.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-resources.ts b/lib/packages/fabro-api-client/src/models/sandbox-resources.ts index 662cdb3de..f23c87f44 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-resources.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-resources.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-service-discovery-source.ts b/lib/packages/fabro-api-client/src/models/sandbox-service-discovery-source.ts index 442f173e0..1c6db31fe 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-service-discovery-source.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-service-discovery-source.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-service-list-meta.ts b/lib/packages/fabro-api-client/src/models/sandbox-service-list-meta.ts index eeba349a3..c24d6c81d 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-service-list-meta.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-service-list-meta.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-service-list-response.ts b/lib/packages/fabro-api-client/src/models/sandbox-service-list-response.ts index 1494ec5b7..a41676b3b 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-service-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-service-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-service.ts b/lib/packages/fabro-api-client/src/models/sandbox-service.ts index fffdbd642..9e89797e7 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-service.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-service.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-state.ts b/lib/packages/fabro-api-client/src/models/sandbox-state.ts index 38f785751..c40419d2f 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-state.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-state.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sandbox-timestamps.ts b/lib/packages/fabro-api-client/src/models/sandbox-timestamps.ts index 83937e370..da431e4cb 100644 --- a/lib/packages/fabro-api-client/src/models/sandbox-timestamps.ts +++ b/lib/packages/fabro-api-client/src/models/sandbox-timestamps.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/save-query-request.ts b/lib/packages/fabro-api-client/src/models/save-query-request.ts index 0b3753cfb..95dc328ca 100644 --- a/lib/packages/fabro-api-client/src/models/save-query-request.ts +++ b/lib/packages/fabro-api-client/src/models/save-query-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/saved-query.ts b/lib/packages/fabro-api-client/src/models/saved-query.ts index 21ae5bf6f..d907feed1 100644 --- a/lib/packages/fabro-api-client/src/models/saved-query.ts +++ b/lib/packages/fabro-api-client/src/models/saved-query.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/secret-list-response.ts b/lib/packages/fabro-api-client/src/models/secret-list-response.ts index f5b8354ac..424684530 100644 --- a/lib/packages/fabro-api-client/src/models/secret-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/secret-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/secret-metadata.ts b/lib/packages/fabro-api-client/src/models/secret-metadata.ts index 22cfc4497..7c2501029 100644 --- a/lib/packages/fabro-api-client/src/models/secret-metadata.ts +++ b/lib/packages/fabro-api-client/src/models/secret-metadata.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/secret-type.ts b/lib/packages/fabro-api-client/src/models/secret-type.ts index 1b8fc239c..8ae9c8e08 100644 --- a/lib/packages/fabro-api-client/src/models/secret-type.ts +++ b/lib/packages/fabro-api-client/src/models/secret-type.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-api-settings.ts b/lib/packages/fabro-api-client/src/models/server-api-settings.ts index 3392c3e71..9049d9f1b 100644 --- a/lib/packages/fabro-api-client/src/models/server-api-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-api-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-artifacts-settings.ts b/lib/packages/fabro-api-client/src/models/server-artifacts-settings.ts index 06131fc77..5452c2b94 100644 --- a/lib/packages/fabro-api-client/src/models/server-artifacts-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-artifacts-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-auth-github-settings.ts b/lib/packages/fabro-api-client/src/models/server-auth-github-settings.ts index 0eadd9e5d..eda32135b 100644 --- a/lib/packages/fabro-api-client/src/models/server-auth-github-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-auth-github-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-auth-method.ts b/lib/packages/fabro-api-client/src/models/server-auth-method.ts index 737fe1c2b..8de81bb47 100644 --- a/lib/packages/fabro-api-client/src/models/server-auth-method.ts +++ b/lib/packages/fabro-api-client/src/models/server-auth-method.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-auth-settings.ts b/lib/packages/fabro-api-client/src/models/server-auth-settings.ts index 650eecb9e..d1dbc18ed 100644 --- a/lib/packages/fabro-api-client/src/models/server-auth-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-auth-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-integrations-settings.ts b/lib/packages/fabro-api-client/src/models/server-integrations-settings.ts index b6e9eef93..88b8fdd8d 100644 --- a/lib/packages/fabro-api-client/src/models/server-integrations-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-integrations-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-listen-settings.ts b/lib/packages/fabro-api-client/src/models/server-listen-settings.ts index d3b6586ff..6898ed62d 100644 --- a/lib/packages/fabro-api-client/src/models/server-listen-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-listen-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-listen-tcp-settings.ts b/lib/packages/fabro-api-client/src/models/server-listen-tcp-settings.ts index 87b0bd4e0..ae99043d0 100644 --- a/lib/packages/fabro-api-client/src/models/server-listen-tcp-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-listen-tcp-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-listen-unix-settings.ts b/lib/packages/fabro-api-client/src/models/server-listen-unix-settings.ts index 643f0b727..ccf48d6ce 100644 --- a/lib/packages/fabro-api-client/src/models/server-listen-unix-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-listen-unix-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-logging-settings.ts b/lib/packages/fabro-api-client/src/models/server-logging-settings.ts index 2fef328fd..994118bdc 100644 --- a/lib/packages/fabro-api-client/src/models/server-logging-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-logging-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-namespace.ts b/lib/packages/fabro-api-client/src/models/server-namespace.ts index 153195ed8..5ff18c6d5 100644 --- a/lib/packages/fabro-api-client/src/models/server-namespace.ts +++ b/lib/packages/fabro-api-client/src/models/server-namespace.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-sandbox-provider-settings.ts b/lib/packages/fabro-api-client/src/models/server-sandbox-provider-settings.ts index c50d09f6d..96fa4f679 100644 --- a/lib/packages/fabro-api-client/src/models/server-sandbox-provider-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-sandbox-provider-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-sandbox-providers-settings.ts b/lib/packages/fabro-api-client/src/models/server-sandbox-providers-settings.ts index 9fa9a35a1..ffc563bb0 100644 --- a/lib/packages/fabro-api-client/src/models/server-sandbox-providers-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-sandbox-providers-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-sandbox-settings.ts b/lib/packages/fabro-api-client/src/models/server-sandbox-settings.ts index cb6a3b2d6..7fd2c4625 100644 --- a/lib/packages/fabro-api-client/src/models/server-sandbox-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-sandbox-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-scheduler-settings.ts b/lib/packages/fabro-api-client/src/models/server-scheduler-settings.ts index 32d67b631..ede8c6126 100644 --- a/lib/packages/fabro-api-client/src/models/server-scheduler-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-scheduler-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-settings.ts b/lib/packages/fabro-api-client/src/models/server-settings.ts index e299e4dda..f6291f430 100644 --- a/lib/packages/fabro-api-client/src/models/server-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-slate-db-settings.ts b/lib/packages/fabro-api-client/src/models/server-slate-db-settings.ts index 0b7b8583d..69c684618 100644 --- a/lib/packages/fabro-api-client/src/models/server-slate-db-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-slate-db-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-storage-settings.ts b/lib/packages/fabro-api-client/src/models/server-storage-settings.ts index 34c12ee29..8584ff40a 100644 --- a/lib/packages/fabro-api-client/src/models/server-storage-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-storage-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/server-web-settings.ts b/lib/packages/fabro-api-client/src/models/server-web-settings.ts index dd8ea8e0b..25b7e1d3b 100644 --- a/lib/packages/fabro-api-client/src/models/server-web-settings.ts +++ b/lib/packages/fabro-api-client/src/models/server-web-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/session-detail.ts b/lib/packages/fabro-api-client/src/models/session-detail.ts index e1dce8d26..0a2e726b1 100644 --- a/lib/packages/fabro-api-client/src/models/session-detail.ts +++ b/lib/packages/fabro-api-client/src/models/session-detail.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/session-message.ts b/lib/packages/fabro-api-client/src/models/session-message.ts index 6ac25cf10..5308f3332 100644 --- a/lib/packages/fabro-api-client/src/models/session-message.ts +++ b/lib/packages/fabro-api-client/src/models/session-message.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/session-record.ts b/lib/packages/fabro-api-client/src/models/session-record.ts index 5bb2ee06d..0c2ef4b79 100644 --- a/lib/packages/fabro-api-client/src/models/session-record.ts +++ b/lib/packages/fabro-api-client/src/models/session-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/session-status.ts b/lib/packages/fabro-api-client/src/models/session-status.ts index b0c6568ab..701bb97d7 100644 --- a/lib/packages/fabro-api-client/src/models/session-status.ts +++ b/lib/packages/fabro-api-client/src/models/session-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/session-summary.ts b/lib/packages/fabro-api-client/src/models/session-summary.ts index 6520d77c7..3aec2b2ff 100644 --- a/lib/packages/fabro-api-client/src/models/session-summary.ts +++ b/lib/packages/fabro-api-client/src/models/session-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/session-turn.ts b/lib/packages/fabro-api-client/src/models/session-turn.ts index 65950d477..ad83c28e2 100644 --- a/lib/packages/fabro-api-client/src/models/session-turn.ts +++ b/lib/packages/fabro-api-client/src/models/session-turn.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/skills-projection.ts b/lib/packages/fabro-api-client/src/models/skills-projection.ts index 897c4b4af..92f77b1a8 100644 --- a/lib/packages/fabro-api-client/src/models/skills-projection.ts +++ b/lib/packages/fabro-api-client/src/models/skills-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/slack-integration-settings.ts b/lib/packages/fabro-api-client/src/models/slack-integration-settings.ts index 4bdbd0687..cfe8a589b 100644 --- a/lib/packages/fabro-api-client/src/models/slack-integration-settings.ts +++ b/lib/packages/fabro-api-client/src/models/slack-integration-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/ssh-access-request.ts b/lib/packages/fabro-api-client/src/models/ssh-access-request.ts index 9f75dc437..4e27da135 100644 --- a/lib/packages/fabro-api-client/src/models/ssh-access-request.ts +++ b/lib/packages/fabro-api-client/src/models/ssh-access-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/ssh-access-response.ts b/lib/packages/fabro-api-client/src/models/ssh-access-response.ts index 4cbe63f52..c59390e87 100644 --- a/lib/packages/fabro-api-client/src/models/ssh-access-response.ts +++ b/lib/packages/fabro-api-client/src/models/ssh-access-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-completion.ts b/lib/packages/fabro-api-client/src/models/stage-completion.ts index 142cf40a6..d6f8abea9 100644 --- a/lib/packages/fabro-api-client/src/models/stage-completion.ts +++ b/lib/packages/fabro-api-client/src/models/stage-completion.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-breakdown-item.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-breakdown-item.ts index cbcd88a4a..df350dc38 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-breakdown-item.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-breakdown-item.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-category.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-category.ts index cca48ef46..315fe5f3f 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-category.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-category.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-count-method.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-count-method.ts index aefb7a767..2b706d8b2 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-count-method.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-count-method.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-projection.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-projection.ts index 33f02bf19..6cf4d2f8d 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-projection.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-staleness.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-staleness.ts index 60f0b777d..2163e7834 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-staleness.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-staleness.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-unavailable-reason.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-unavailable-reason.ts index 4420c4dbe..b22bb7392 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-unavailable-reason.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-unavailable-reason.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window-warning.ts b/lib/packages/fabro-api-client/src/models/stage-context-window-warning.ts index f10d15ad7..18c97d0df 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window-warning.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window-warning.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-context-window.ts b/lib/packages/fabro-api-client/src/models/stage-context-window.ts index ee63a7811..fe78e3f8f 100644 --- a/lib/packages/fabro-api-client/src/models/stage-context-window.ts +++ b/lib/packages/fabro-api-client/src/models/stage-context-window.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-handler.ts b/lib/packages/fabro-api-client/src/models/stage-handler.ts index 1398d3e34..6d8827ce0 100644 --- a/lib/packages/fabro-api-client/src/models/stage-handler.ts +++ b/lib/packages/fabro-api-client/src/models/stage-handler.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-inference-projection.ts b/lib/packages/fabro-api-client/src/models/stage-inference-projection.ts index 13a08869b..5a28adc18 100644 --- a/lib/packages/fabro-api-client/src/models/stage-inference-projection.ts +++ b/lib/packages/fabro-api-client/src/models/stage-inference-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-model-usage.ts b/lib/packages/fabro-api-client/src/models/stage-model-usage.ts index 8ba389a8a..c2f89645c 100644 --- a/lib/packages/fabro-api-client/src/models/stage-model-usage.ts +++ b/lib/packages/fabro-api-client/src/models/stage-model-usage.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-outcome.ts b/lib/packages/fabro-api-client/src/models/stage-outcome.ts index 1295b7ec4..3fa8b5caa 100644 --- a/lib/packages/fabro-api-client/src/models/stage-outcome.ts +++ b/lib/packages/fabro-api-client/src/models/stage-outcome.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-projection.ts b/lib/packages/fabro-api-client/src/models/stage-projection.ts index 56a53f7c0..35cfdc492 100644 --- a/lib/packages/fabro-api-client/src/models/stage-projection.ts +++ b/lib/packages/fabro-api-client/src/models/stage-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-state.ts b/lib/packages/fabro-api-client/src/models/stage-state.ts index 9443fdfad..650829f85 100644 --- a/lib/packages/fabro-api-client/src/models/stage-state.ts +++ b/lib/packages/fabro-api-client/src/models/stage-state.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-summary.ts b/lib/packages/fabro-api-client/src/models/stage-summary.ts index 011fcf555..bfd131b68 100644 --- a/lib/packages/fabro-api-client/src/models/stage-summary.ts +++ b/lib/packages/fabro-api-client/src/models/stage-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-timing.ts b/lib/packages/fabro-api-client/src/models/stage-timing.ts index 4b106816c..dd9d9d9d6 100644 --- a/lib/packages/fabro-api-client/src/models/stage-timing.ts +++ b/lib/packages/fabro-api-client/src/models/stage-timing.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/stage-tool-batch-projection.ts b/lib/packages/fabro-api-client/src/models/stage-tool-batch-projection.ts index 971fa7c59..2432c19d6 100644 --- a/lib/packages/fabro-api-client/src/models/stage-tool-batch-projection.ts +++ b/lib/packages/fabro-api-client/src/models/stage-tool-batch-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/start-record.ts b/lib/packages/fabro-api-client/src/models/start-record.ts index 7882a9789..e361528a1 100644 --- a/lib/packages/fabro-api-client/src/models/start-record.ts +++ b/lib/packages/fabro-api-client/src/models/start-record.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/start-run-request.ts b/lib/packages/fabro-api-client/src/models/start-run-request.ts index baccb9915..d733c6fd8 100644 --- a/lib/packages/fabro-api-client/src/models/start-run-request.ts +++ b/lib/packages/fabro-api-client/src/models/start-run-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/steer-run-request.ts b/lib/packages/fabro-api-client/src/models/steer-run-request.ts index 4169fadc1..daa65e248 100644 --- a/lib/packages/fabro-api-client/src/models/steer-run-request.ts +++ b/lib/packages/fabro-api-client/src/models/steer-run-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sub-agent-projection.ts b/lib/packages/fabro-api-client/src/models/sub-agent-projection.ts index c2576d069..4d1b22a0f 100644 --- a/lib/packages/fabro-api-client/src/models/sub-agent-projection.ts +++ b/lib/packages/fabro-api-client/src/models/sub-agent-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sub-agent-status-closed.ts b/lib/packages/fabro-api-client/src/models/sub-agent-status-closed.ts index d4c7bb5a6..114cb14ca 100644 --- a/lib/packages/fabro-api-client/src/models/sub-agent-status-closed.ts +++ b/lib/packages/fabro-api-client/src/models/sub-agent-status-closed.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sub-agent-status-completed.ts b/lib/packages/fabro-api-client/src/models/sub-agent-status-completed.ts index 2250ee02a..b5c186fb3 100644 --- a/lib/packages/fabro-api-client/src/models/sub-agent-status-completed.ts +++ b/lib/packages/fabro-api-client/src/models/sub-agent-status-completed.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sub-agent-status-failed.ts b/lib/packages/fabro-api-client/src/models/sub-agent-status-failed.ts index a9eed6831..cc08b4a3a 100644 --- a/lib/packages/fabro-api-client/src/models/sub-agent-status-failed.ts +++ b/lib/packages/fabro-api-client/src/models/sub-agent-status-failed.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sub-agent-status-running.ts b/lib/packages/fabro-api-client/src/models/sub-agent-status-running.ts index 79063cbe0..9f47c69d1 100644 --- a/lib/packages/fabro-api-client/src/models/sub-agent-status-running.ts +++ b/lib/packages/fabro-api-client/src/models/sub-agent-status-running.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/sub-agent-status.ts b/lib/packages/fabro-api-client/src/models/sub-agent-status.ts index 630717c08..1d88f804b 100644 --- a/lib/packages/fabro-api-client/src/models/sub-agent-status.ts +++ b/lib/packages/fabro-api-client/src/models/sub-agent-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-answer-multi-selected-request.ts b/lib/packages/fabro-api-client/src/models/submit-answer-multi-selected-request.ts index b3458cfce..1786ffd3e 100644 --- a/lib/packages/fabro-api-client/src/models/submit-answer-multi-selected-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-answer-multi-selected-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-answer-no-request.ts b/lib/packages/fabro-api-client/src/models/submit-answer-no-request.ts index aef539155..f116ebd9b 100644 --- a/lib/packages/fabro-api-client/src/models/submit-answer-no-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-answer-no-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-answer-request.ts b/lib/packages/fabro-api-client/src/models/submit-answer-request.ts index 04fb93ddb..0390a6a30 100644 --- a/lib/packages/fabro-api-client/src/models/submit-answer-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-answer-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-answer-selected-request.ts b/lib/packages/fabro-api-client/src/models/submit-answer-selected-request.ts index 3c4c42b95..28ae12a47 100644 --- a/lib/packages/fabro-api-client/src/models/submit-answer-selected-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-answer-selected-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-answer-text-request.ts b/lib/packages/fabro-api-client/src/models/submit-answer-text-request.ts index a1c419d3b..816571bb2 100644 --- a/lib/packages/fabro-api-client/src/models/submit-answer-text-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-answer-text-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-answer-yes-request.ts b/lib/packages/fabro-api-client/src/models/submit-answer-yes-request.ts index 5a657bae4..aafdb10af 100644 --- a/lib/packages/fabro-api-client/src/models/submit-answer-yes-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-answer-yes-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/submit-turn-request.ts b/lib/packages/fabro-api-client/src/models/submit-turn-request.ts index 06375abf8..bac7445ff 100644 --- a/lib/packages/fabro-api-client/src/models/submit-turn-request.ts +++ b/lib/packages/fabro-api-client/src/models/submit-turn-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/success-reason.ts b/lib/packages/fabro-api-client/src/models/success-reason.ts index 011e1ca5e..a863a8a8a 100644 --- a/lib/packages/fabro-api-client/src/models/success-reason.ts +++ b/lib/packages/fabro-api-client/src/models/success-reason.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-actor-kind.ts b/lib/packages/fabro-api-client/src/models/system-actor-kind.ts index 9904e8b28..76eec34b9 100644 --- a/lib/packages/fabro-api-client/src/models/system-actor-kind.ts +++ b/lib/packages/fabro-api-client/src/models/system-actor-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts b/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts index e4637a6e7..fcbe410d9 100644 --- a/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts +++ b/lib/packages/fabro-api-client/src/models/system-cpu-resource-scope.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts b/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts index 48fd764fe..99739fb3c 100644 --- a/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts +++ b/lib/packages/fabro-api-client/src/models/system-cpu-resources.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts b/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts index 79daf2b31..bcbef3ba3 100644 --- a/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts +++ b/lib/packages/fabro-api-client/src/models/system-disk-resource-scope.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-disk-resources.ts b/lib/packages/fabro-api-client/src/models/system-disk-resources.ts index f44dca9ad..76c6df14b 100644 --- a/lib/packages/fabro-api-client/src/models/system-disk-resources.ts +++ b/lib/packages/fabro-api-client/src/models/system-disk-resources.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 6b3f8ebd5..8bf9b08b7 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 @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-integration-status.ts b/lib/packages/fabro-api-client/src/models/system-integration-status.ts index 6bc357f56..cb9adf24e 100644 --- a/lib/packages/fabro-api-client/src/models/system-integration-status.ts +++ b/lib/packages/fabro-api-client/src/models/system-integration-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-integrations-response.ts b/lib/packages/fabro-api-client/src/models/system-integrations-response.ts index b00aa3bf1..b557e6b5c 100644 --- a/lib/packages/fabro-api-client/src/models/system-integrations-response.ts +++ b/lib/packages/fabro-api-client/src/models/system-integrations-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts b/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts index 31340786e..463cee08a 100644 --- a/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts +++ b/lib/packages/fabro-api-client/src/models/system-memory-resource-scope.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-memory-resources.ts b/lib/packages/fabro-api-client/src/models/system-memory-resources.ts index 75f1b8e53..b90d1d41d 100644 --- a/lib/packages/fabro-api-client/src/models/system-memory-resources.ts +++ b/lib/packages/fabro-api-client/src/models/system-memory-resources.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-repair-run-issue.ts b/lib/packages/fabro-api-client/src/models/system-repair-run-issue.ts index dc5cc5abb..0167a6d5c 100644 --- a/lib/packages/fabro-api-client/src/models/system-repair-run-issue.ts +++ b/lib/packages/fabro-api-client/src/models/system-repair-run-issue.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-repair-runs-response.ts b/lib/packages/fabro-api-client/src/models/system-repair-runs-response.ts index 9ca571774..fbf50ce8f 100644 --- a/lib/packages/fabro-api-client/src/models/system-repair-runs-response.ts +++ b/lib/packages/fabro-api-client/src/models/system-repair-runs-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-resources-response.ts b/lib/packages/fabro-api-client/src/models/system-resources-response.ts index cdffb88e8..d758bc8eb 100644 --- a/lib/packages/fabro-api-client/src/models/system-resources-response.ts +++ b/lib/packages/fabro-api-client/src/models/system-resources-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/system-run-counts.ts b/lib/packages/fabro-api-client/src/models/system-run-counts.ts index 3fe29ae9b..5d77ff2f4 100644 --- a/lib/packages/fabro-api-client/src/models/system-run-counts.ts +++ b/lib/packages/fabro-api-client/src/models/system-run-counts.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/timeline-entry-response.ts b/lib/packages/fabro-api-client/src/models/timeline-entry-response.ts index be3839db8..b78a1b31c 100644 --- a/lib/packages/fabro-api-client/src/models/timeline-entry-response.ts +++ b/lib/packages/fabro-api-client/src/models/timeline-entry-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/tls-mode.ts b/lib/packages/fabro-api-client/src/models/tls-mode.ts index 302a16f11..22a837dbb 100644 --- a/lib/packages/fabro-api-client/src/models/tls-mode.ts +++ b/lib/packages/fabro-api-client/src/models/tls-mode.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/todo-list-kind.ts b/lib/packages/fabro-api-client/src/models/todo-list-kind.ts index 20f1da8ee..37a04a71a 100644 --- a/lib/packages/fabro-api-client/src/models/todo-list-kind.ts +++ b/lib/packages/fabro-api-client/src/models/todo-list-kind.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/todo-list-projection.ts b/lib/packages/fabro-api-client/src/models/todo-list-projection.ts index d74332c47..4b0b64b64 100644 --- a/lib/packages/fabro-api-client/src/models/todo-list-projection.ts +++ b/lib/packages/fabro-api-client/src/models/todo-list-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/todo-projection.ts b/lib/packages/fabro-api-client/src/models/todo-projection.ts index 5200eaf50..7cea92aa4 100644 --- a/lib/packages/fabro-api-client/src/models/todo-projection.ts +++ b/lib/packages/fabro-api-client/src/models/todo-projection.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/todo-status.ts b/lib/packages/fabro-api-client/src/models/todo-status.ts index e5be59ed9..a6a47d697 100644 --- a/lib/packages/fabro-api-client/src/models/todo-status.ts +++ b/lib/packages/fabro-api-client/src/models/todo-status.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/update-run-parent-request.ts b/lib/packages/fabro-api-client/src/models/update-run-parent-request.ts index 43bbe96ce..ab2a52e42 100644 --- a/lib/packages/fabro-api-client/src/models/update-run-parent-request.ts +++ b/lib/packages/fabro-api-client/src/models/update-run-parent-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/update-run-request.ts b/lib/packages/fabro-api-client/src/models/update-run-request.ts index 92697fb26..91a18b756 100644 --- a/lib/packages/fabro-api-client/src/models/update-run-request.ts +++ b/lib/packages/fabro-api-client/src/models/update-run-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/update-variable-request.ts b/lib/packages/fabro-api-client/src/models/update-variable-request.ts index 71d925149..ae94ff897 100644 --- a/lib/packages/fabro-api-client/src/models/update-variable-request.ts +++ b/lib/packages/fabro-api-client/src/models/update-variable-request.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/user-response.ts b/lib/packages/fabro-api-client/src/models/user-response.ts index 1debdf685..f8474b3ff 100644 --- a/lib/packages/fabro-api-client/src/models/user-response.ts +++ b/lib/packages/fabro-api-client/src/models/user-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/validate-response.ts b/lib/packages/fabro-api-client/src/models/validate-response.ts index 302222254..f1f4a0dfd 100644 --- a/lib/packages/fabro-api-client/src/models/validate-response.ts +++ b/lib/packages/fabro-api-client/src/models/validate-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/variable-list-response.ts b/lib/packages/fabro-api-client/src/models/variable-list-response.ts index b4ed0ab0a..4895e68a9 100644 --- a/lib/packages/fabro-api-client/src/models/variable-list-response.ts +++ b/lib/packages/fabro-api-client/src/models/variable-list-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/variable.ts b/lib/packages/fabro-api-client/src/models/variable.ts index a5d39e711..aba83d090 100644 --- a/lib/packages/fabro-api-client/src/models/variable.ts +++ b/lib/packages/fabro-api-client/src/models/variable.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/vnc-preview-response.ts b/lib/packages/fabro-api-client/src/models/vnc-preview-response.ts index aed16f52a..40e1e7bef 100644 --- a/lib/packages/fabro-api-client/src/models/vnc-preview-response.ts +++ b/lib/packages/fabro-api-client/src/models/vnc-preview-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/webhook-strategy.ts b/lib/packages/fabro-api-client/src/models/webhook-strategy.ts index 090689f95..d2f617762 100644 --- a/lib/packages/fabro-api-client/src/models/webhook-strategy.ts +++ b/lib/packages/fabro-api-client/src/models/webhook-strategy.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-detail-response.ts b/lib/packages/fabro-api-client/src/models/workflow-detail-response.ts index 0f9722566..3d992b1f5 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-detail-response.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-detail-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 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 5c5ee9790..e0a9686a1 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-diagnostic.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-diagnostic.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-last-run-summary.ts b/lib/packages/fabro-api-client/src/models/workflow-last-run-summary.ts index e5c443086..af27a3d15 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-last-run-summary.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-last-run-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-list-item.ts b/lib/packages/fabro-api-client/src/models/workflow-list-item.ts index 00ae2f734..839503230 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-list-item.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-list-item.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-namespace.ts b/lib/packages/fabro-api-client/src/models/workflow-namespace.ts index 5501b5b21..7451185ae 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-namespace.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-namespace.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-ref.ts b/lib/packages/fabro-api-client/src/models/workflow-ref.ts index d98cf2148..6189e8bd7 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-ref.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-ref.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-reference.ts b/lib/packages/fabro-api-client/src/models/workflow-reference.ts index f4a83080b..d85c64352 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-reference.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-reference.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-schedule-summary.ts b/lib/packages/fabro-api-client/src/models/workflow-schedule-summary.ts index 3165113d1..fc26a97f1 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-schedule-summary.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-schedule-summary.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-settings.ts b/lib/packages/fabro-api-client/src/models/workflow-settings.ts index 7f5214295..b3a2b8614 100644 --- a/lib/packages/fabro-api-client/src/models/workflow-settings.ts +++ b/lib/packages/fabro-api-client/src/models/workflow-settings.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/lib/packages/fabro-api-client/src/models/workflow-version.ts b/lib/packages/fabro-api-client/src/models/workflow-version.ts new file mode 100644 index 000000000..b96922261 --- /dev/null +++ b/lib/packages/fabro-api-client/src/models/workflow-version.ts @@ -0,0 +1,33 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Fabro Run API + * HTTP API for managing Fabro workflow run executions. + * + * The version of the OpenAPI document: 0.2.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * Complete immutable package for one rooted workflow. It contains at most 512 files and 512 workflow dependencies, each file is at most 512 KiB of UTF-8 content, and its compact canonical JSON representation is at most 2 MiB. + */ +export interface WorkflowVersion { + /** + * Canonical portable path inside one workflow version. Paths are UTF-8, relative, at most 240 bytes and 16 components, and cannot contain empty, dot, parent, backslash, control, tilde-root, or drive-letter segments. Map keys receive stricter byte and structural validation in the domain model than OpenAPI can express. + */ + 'entrypoint': string; + /** + * Workflow-local text files keyed by canonical path. Keys receive stricter domain validation than OpenAPI can express; each value is limited to 512 KiB of UTF-8 bytes. + */ + 'files': { [key: string]: string; }; + /** + * Exact stored workflow-version IDs keyed by resolved child-workflow path. Keys receive stricter domain validation than OpenAPI can express. + */ + 'workflow_dependencies': { [key: string]: string; }; +} diff --git a/lib/packages/fabro-api-client/src/models/write-blob-response.ts b/lib/packages/fabro-api-client/src/models/write-blob-response.ts index 295ff9874..d926f8118 100644 --- a/lib/packages/fabro-api-client/src/models/write-blob-response.ts +++ b/lib/packages/fabro-api-client/src/models/write-blob-response.ts @@ -4,7 +4,7 @@ * Fabro Run API * HTTP API for managing Fabro workflow run executions. * - * The version of the OpenAPI document: 0.1.0 + * The version of the OpenAPI document: 0.2.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -15,11 +15,11 @@ /** - * Content-addressed identifier for a stored blob. + * Content-addressed hash of a stored blob. */ export interface WriteBlobResponse { /** - * Blob identifier. + * Content-addressed SHA-256 hash of a stored blob. Hex input is case-insensitive; Fabro emits the canonical lowercase form. */ - 'id': string; + 'hash': string; }