mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-06 02:48:25 +00:00
refactor: wire vendored Graphviz into fabro-graphviz, remove dot dependency
Replace the Command::new("dot") shell-out in render_dot() with a direct
FFI call to the vendored Graphviz library. Drop PNG support (SVG only).
Remove GraphFormat enum, dot_is_available() helpers, dot-related
diagnostics/doctor checks, and the graphviz install prompt. Update
OpenAPI spec to remove png format and 502 responses. Update CLI help
text, snapshot tests, and documentation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0d4e4a3cbb
commit
15cf4d8640
32 changed files with 135 additions and 426 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1715,6 +1715,7 @@ name = "fabro-graphviz"
|
|||
version = "0.176.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"fabro-graphviz-sys",
|
||||
"fabro-types",
|
||||
"nom",
|
||||
"regex",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ It checks:
|
|||
- Server-reported LLM provider connectivity
|
||||
- GitHub App, sandbox, and Brave Search credentials
|
||||
- Server authentication and crypto configuration
|
||||
- Server-side Graphviz availability
|
||||
|
||||
## Common issues
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ paths:
|
|||
operationId: renderWorkflowGraph
|
||||
tags: [Runs]
|
||||
summary: Render Workflow Graph
|
||||
description: Validates and renders a workflow manifest as SVG or PNG without creating a run.
|
||||
description: Validates and renders a workflow manifest as SVG without creating a run.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
|
|
@ -204,22 +204,12 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
image/png:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"400":
|
||||
description: Invalid manifest or workflow
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"502":
|
||||
description: Graphviz rendering failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}:
|
||||
get:
|
||||
|
|
@ -398,12 +388,6 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"502":
|
||||
description: Graphviz not available
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/api/v1/runs/{id}/checkpoint:
|
||||
get:
|
||||
|
|
@ -2337,7 +2321,6 @@ components:
|
|||
type: string
|
||||
enum:
|
||||
- svg
|
||||
- png
|
||||
|
||||
RenderWorkflowGraphDirection:
|
||||
type: string
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ Each entry in the `errors` array contains:
|
|||
| `409 Conflict` | The resource is in a conflicting state | Answering a question on a run that isn't running yet |
|
||||
| `410 Gone` | The resource is no longer available | SSE event stream has closed |
|
||||
| `501 Not Implemented` | The endpoint exists but is not yet implemented | Placeholder routes |
|
||||
| `502 Bad Gateway` | An upstream dependency failed | Graphviz `dot` not installed or returned an error |
|
||||
| `502 Bad Gateway` | An upstream dependency failed | An upstream service returned an error |
|
||||
|
||||
## Pagination
|
||||
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ After installation, AI assistants in your editor can use the skill when generati
|
|||
|
||||
## Visualize workflows with fabro graph
|
||||
|
||||
`fabro graph` renders your workflow DOT graphs as SVG or PNG, so you can see the full structure of your workflow at a glance. Requires Graphviz `dot` to be installed.
|
||||
`fabro graph` renders your workflow DOT graphs as SVG, so you can see the full structure of your workflow at a glance.
|
||||
|
||||
```bash
|
||||
fabro graph # SVG to stdout
|
||||
fabro graph -o flow.png # PNG to file
|
||||
fabro graph -o flow.svg # SVG to file
|
||||
```
|
||||
|
||||
## More
|
||||
|
|
|
|||
|
|
@ -493,18 +493,18 @@ fabro system df -v
|
|||
|
||||
## `fabro graph`
|
||||
|
||||
Render a workflow graph as SVG or PNG. Requires [Graphviz](https://graphviz.org) (`dot`) to be installed. SVG output includes styled defaults (teal node strokes, clean typography, transparent background) and automatic dark mode support via `prefers-color-scheme` media queries.
|
||||
Render a workflow graph as SVG. SVG output includes styled defaults (teal node strokes, clean typography, transparent background) and automatic dark mode support via `prefers-color-scheme` media queries.
|
||||
|
||||
```bash
|
||||
fabro graph workflow.fabro
|
||||
fabro graph workflow.fabro --format png -o diagram.png
|
||||
fabro graph run.toml --format svg
|
||||
fabro graph workflow.fabro -o diagram.svg
|
||||
fabro graph run.toml
|
||||
```
|
||||
|
||||
| Argument / Flag | Description |
|
||||
|---|---|
|
||||
| `<WORKFLOW>` | Path to a `.fabro` workflow file or `.toml` run config (required) |
|
||||
| `--format <FORMAT>` | Output format: `svg` (default) or `png` |
|
||||
| `--format <FORMAT>` | Output format: `svg` (default) |
|
||||
| `-o, --output <FILE>` | Output file path. Defaults to stdout. |
|
||||
| `-d, --direction <DIR>` | Graph direction: `lr` or `tb`. If omitted, uses the Graphviz file's own `rankdir`. |
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use clap::{Args, Subcommand, ValueEnum};
|
||||
use fabro_agent::cli::AgentArgs;
|
||||
use fabro_graphviz::render::GraphFormat;
|
||||
|
||||
pub(crate) const LONG_VERSION: &str = concat!(
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
|
|
@ -306,23 +305,12 @@ impl fmt::Display for GraphDirection {
|
|||
#[derive(Debug, Clone, Copy, ValueEnum)]
|
||||
pub(crate) enum GraphOutputFormat {
|
||||
Svg,
|
||||
Png,
|
||||
}
|
||||
|
||||
impl From<GraphOutputFormat> for GraphFormat {
|
||||
fn from(value: GraphOutputFormat) -> Self {
|
||||
match value {
|
||||
GraphOutputFormat::Svg => Self::Svg,
|
||||
GraphOutputFormat::Png => Self::Png,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GraphOutputFormat {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Svg => write!(f, "svg"),
|
||||
Self::Png => write!(f, "png"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -935,7 +923,7 @@ pub(crate) enum Commands {
|
|||
Preflight(PreflightArgs),
|
||||
/// Validate a workflow
|
||||
Validate(ValidateArgs),
|
||||
/// Render a workflow graph as SVG or PNG
|
||||
/// Render a workflow graph as SVG
|
||||
Graph(GraphArgs),
|
||||
/// Parse a DOT file and print its AST
|
||||
#[command(hide = true)]
|
||||
|
|
|
|||
|
|
@ -38,16 +38,7 @@ pub(crate) enum ProbeOutcome {
|
|||
Ok { version: Option<Version> },
|
||||
}
|
||||
|
||||
static DOT_RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"graphviz version (\d+)\.(\d+)\.(\d+)").unwrap());
|
||||
|
||||
pub(crate) const DEP_SPECS: &[DepSpec] = &[DepSpec {
|
||||
name: "dot",
|
||||
command: &["dot", "-V"],
|
||||
required: false,
|
||||
min_version: Version::new(2, 0, 0),
|
||||
pattern: &DOT_RE,
|
||||
}];
|
||||
pub(crate) const DEP_SPECS: &[DepSpec] = &[];
|
||||
|
||||
fn parse_version(re: &Regex, output: &str) -> Option<Version> {
|
||||
let caps = re.captures(output)?;
|
||||
|
|
@ -661,19 +652,6 @@ mod tests {
|
|||
assert_eq!(result.status, CheckStatus::Warning);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_version_dot() {
|
||||
assert_eq!(
|
||||
parse_version(&DOT_RE, "dot - graphviz version 12.2.1 (20241206.2024)"),
|
||||
Some(Version::new(12, 2, 1))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_version_garbage_returns_none() {
|
||||
assert_eq!(parse_version(&DOT_RE, "no version here"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_report_text_without_color_has_no_ansi() {
|
||||
let report = CheckReport {
|
||||
|
|
@ -701,13 +679,16 @@ mod tests {
|
|||
assert!(rendered.contains("[✓] Configuration (loaded)"));
|
||||
}
|
||||
|
||||
static TEST_RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"version (\d+)\.(\d+)\.(\d+)").unwrap());
|
||||
|
||||
fn spec(name: &'static str, required: bool, min_version: Version) -> DepSpec {
|
||||
DepSpec {
|
||||
name,
|
||||
command: &["echo", "unused"],
|
||||
required,
|
||||
min_version,
|
||||
pattern: &DOT_RE,
|
||||
pattern: &TEST_RE,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use fabro_util::printer::Printer;
|
|||
use fabro_util::terminal::Styles;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::args::{GlobalArgs, GraphArgs, GraphDirection, GraphOutputFormat};
|
||||
use crate::args::{GlobalArgs, GraphArgs, GraphDirection};
|
||||
use crate::command_context::CommandContext;
|
||||
use crate::commands::run::output::api_diagnostics_to_local;
|
||||
use crate::manifest_builder::{ManifestBuildInput, build_run_manifest};
|
||||
|
|
@ -50,10 +50,7 @@ pub(crate) async fn run(
|
|||
let rendered = client
|
||||
.render_workflow_graph(types::RenderWorkflowGraphRequest {
|
||||
manifest: built.manifest,
|
||||
format: Some(match args.format {
|
||||
GraphOutputFormat::Svg => types::RenderWorkflowGraphFormat::Svg,
|
||||
GraphOutputFormat::Png => types::RenderWorkflowGraphFormat::Png,
|
||||
}),
|
||||
format: Some(types::RenderWorkflowGraphFormat::Svg),
|
||||
direction: args.direction.map(|direction| match direction {
|
||||
GraphDirection::Lr => types::RenderWorkflowGraphDirection::Lr,
|
||||
GraphDirection::Tb => types::RenderWorkflowGraphDirection::Tb,
|
||||
|
|
|
|||
|
|
@ -415,8 +415,6 @@ fn install_github_app_handoff_event(url: &str, owner: &GitHubAppOwner) -> serde_
|
|||
|
||||
#[async_trait]
|
||||
trait InstallInputSource {
|
||||
async fn choose_graphviz_install(&self, dot_missing: bool) -> Result<bool>;
|
||||
|
||||
async fn collect_llm_selection(
|
||||
&self,
|
||||
facts: &InstallFacts,
|
||||
|
|
@ -439,15 +437,6 @@ struct InteractiveInstallInputSource;
|
|||
|
||||
#[async_trait]
|
||||
impl InstallInputSource for InteractiveInstallInputSource {
|
||||
async fn choose_graphviz_install(&self, dot_missing: bool) -> Result<bool> {
|
||||
if !dot_missing {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
spawn_blocking(|| prompt_confirm("Graphviz (dot) not found. Install via Homebrew?", true))
|
||||
.await?
|
||||
}
|
||||
|
||||
async fn collect_llm_selection(
|
||||
&self,
|
||||
facts: &InstallFacts,
|
||||
|
|
@ -676,10 +665,6 @@ impl NonInteractiveInstallInputSource {
|
|||
|
||||
#[async_trait]
|
||||
impl InstallInputSource for NonInteractiveInstallInputSource {
|
||||
async fn choose_graphviz_install(&self, _dot_missing: bool) -> Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
async fn collect_llm_selection(
|
||||
&self,
|
||||
_facts: &InstallFacts,
|
||||
|
|
@ -1323,10 +1308,6 @@ async fn run_install_inner(
|
|||
let facts = {
|
||||
let dep_outcomes = doctor::probe_system_deps().await;
|
||||
let dep_check = doctor::check_system_deps(doctor::DEP_SPECS, &dep_outcomes);
|
||||
let dot_missing = doctor::DEP_SPECS
|
||||
.iter()
|
||||
.position(|spec| spec.name == "dot")
|
||||
.is_some_and(|idx| matches!(dep_outcomes[idx], doctor::ProbeOutcome::NotFound));
|
||||
|
||||
fabro_util::printerr!(
|
||||
printer,
|
||||
|
|
@ -1342,17 +1323,6 @@ async fn run_install_inner(
|
|||
bail!("Install missing required tools before running setup");
|
||||
}
|
||||
|
||||
if input_source.choose_graphviz_install(dot_missing).await? {
|
||||
let status = TokioCommand::new("brew")
|
||||
.args(["install", "graphviz"])
|
||||
.status()
|
||||
.await
|
||||
.context("failed to run brew install graphviz")?;
|
||||
if !status.success() {
|
||||
fabro_util::printerr!(printer, " Warning: brew install graphviz failed");
|
||||
}
|
||||
}
|
||||
|
||||
for detail in &dep_check.details {
|
||||
fabro_util::printerr!(printer, " {}", detail.text);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fn help() {
|
|||
wait Block until a workflow run completes
|
||||
preflight Validate run configuration without executing
|
||||
validate Validate a workflow
|
||||
graph Render a workflow graph as SVG or PNG
|
||||
graph Render a workflow graph as SVG
|
||||
artifact Inspect and copy run artifacts (screenshots, reports, traces)
|
||||
store Export store-backed run state for debugging
|
||||
rm Remove one or more workflow runs
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ fn help() {
|
|||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Render a workflow graph as SVG or PNG
|
||||
Render a workflow graph as SVG
|
||||
|
||||
Usage: fabro graph [OPTIONS] <WORKFLOW>
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ fn help() {
|
|||
Output format
|
||||
|
||||
[default: svg]
|
||||
[possible values: svg, png]
|
||||
[possible values: svg]
|
||||
|
||||
--no-upgrade-check
|
||||
Disable automatic upgrade check
|
||||
|
|
|
|||
|
|
@ -1,24 +1,8 @@
|
|||
#![expect(
|
||||
clippy::disallowed_methods,
|
||||
reason = "These CLI integration tests synchronously probe for dot before exercising JSON output paths."
|
||||
)]
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use fabro_test::test_context;
|
||||
use serde_json::Value;
|
||||
|
||||
use super::support::{fixture, output_stderr, output_stdout, setup_completed_fast_dry_run};
|
||||
|
||||
fn dot_is_available() -> bool {
|
||||
Command::new("dot")
|
||||
.arg("-V")
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.status()
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completion_rejects_json() {
|
||||
let context = test_context!();
|
||||
|
|
@ -143,10 +127,6 @@ fn graph_json_without_output_is_rejected() {
|
|||
|
||||
#[test]
|
||||
fn graph_json_with_output_reports_file() {
|
||||
if !dot_is_available() {
|
||||
return;
|
||||
}
|
||||
|
||||
let context = test_context!();
|
||||
let output_path = context.temp_dir.join("graph.svg");
|
||||
let workflow = fixture("simple.fabro");
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ workspace = true
|
|||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
fabro-graphviz-sys = { path = "../fabro-graphviz-sys" }
|
||||
fabro-types = { path = "../fabro-types" }
|
||||
nom = "7"
|
||||
regex = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,29 +1,5 @@
|
|||
use std::fmt;
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use anyhow::bail;
|
||||
|
||||
/// Output format for graph rendering.
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||
pub enum GraphFormat {
|
||||
/// Scalable Vector Graphics
|
||||
#[default]
|
||||
Svg,
|
||||
/// Portable Network Graphics
|
||||
Png,
|
||||
}
|
||||
|
||||
impl fmt::Display for GraphFormat {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Svg => write!(f, "svg"),
|
||||
Self::Png => write!(f, "png"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dark mode CSS injected into SVG output (leading newline included for
|
||||
/// insertion).
|
||||
const DARK_MODE_STYLE: &str = r##"
|
||||
|
|
@ -88,60 +64,12 @@ pub fn postprocess_svg(raw: Vec<u8>) -> Vec<u8> {
|
|||
svg.into_bytes()
|
||||
}
|
||||
|
||||
/// Render styled DOT source into the given format via the `dot` command.
|
||||
#[expect(
|
||||
clippy::disallowed_methods,
|
||||
reason = "This synchronous rendering helper is intentionally called behind spawn_blocking from async server code."
|
||||
)]
|
||||
pub fn render_dot(source: &str, format: GraphFormat) -> anyhow::Result<Vec<u8>> {
|
||||
/// Render styled DOT source into SVG via the vendored Graphviz library.
|
||||
pub fn render_dot(source: &str) -> anyhow::Result<Vec<u8>> {
|
||||
let styled_source = inject_dot_style_defaults(source);
|
||||
let mut child = match Command::new("dot")
|
||||
.arg(format!("-T{format}"))
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => child,
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
bail!("Graphviz is not installed. Install it with: brew install graphviz");
|
||||
}
|
||||
Err(err) => {
|
||||
bail!("Failed to run dot: {err}");
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
stdin.write_all(styled_source.as_bytes())?;
|
||||
}
|
||||
|
||||
let output = child.wait_with_output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
bail!("dot failed: {stderr}");
|
||||
}
|
||||
|
||||
let raw = output.stdout;
|
||||
if matches!(format, GraphFormat::Svg) {
|
||||
Ok(postprocess_svg(raw))
|
||||
} else {
|
||||
Ok(raw)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[expect(
|
||||
clippy::disallowed_methods,
|
||||
reason = "This synchronous test probe checks whether dot is installed before running render assertions."
|
||||
)]
|
||||
fn dot_is_available() -> bool {
|
||||
Command::new("dot")
|
||||
.arg("-V")
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.status()
|
||||
.is_ok()
|
||||
let raw = fabro_graphviz_sys::render_dot_to_svg(&styled_source)
|
||||
.map_err(|e| anyhow::anyhow!("Graphviz rendering failed: {e}"))?;
|
||||
Ok(postprocess_svg(raw))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -173,14 +101,39 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn render_dot_svg_or_png_if_graphviz_is_available() {
|
||||
if !dot_is_available() {
|
||||
return;
|
||||
}
|
||||
let svg = render_dot("digraph { a -> b }", GraphFormat::Svg).unwrap();
|
||||
fn render_dot_produces_svg() {
|
||||
let svg = render_dot("digraph { a -> b }").unwrap();
|
||||
assert!(String::from_utf8(svg).unwrap().contains("<svg"));
|
||||
}
|
||||
|
||||
let png = render_dot("digraph { a -> b }", GraphFormat::Png).unwrap();
|
||||
assert!(!png.is_empty());
|
||||
#[test]
|
||||
fn render_dot_complex_graph() {
|
||||
let source = r#"digraph {
|
||||
subgraph cluster_0 {
|
||||
label = "process #1";
|
||||
a0 -> a1 -> a2 -> a3;
|
||||
}
|
||||
subgraph cluster_1 {
|
||||
label = "process #2";
|
||||
b0 -> b1 -> b2 -> b3;
|
||||
}
|
||||
start -> a0;
|
||||
start -> b0;
|
||||
a1 -> b3;
|
||||
b2 -> a3;
|
||||
a3 -> end;
|
||||
b3 -> end;
|
||||
}"#;
|
||||
let svg = render_dot(source).unwrap();
|
||||
let svg_str = String::from_utf8(svg).unwrap();
|
||||
assert!(svg_str.contains("<svg"));
|
||||
assert!(svg_str.contains("process #1"));
|
||||
assert!(svg_str.contains("process #2"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_dot_invalid_source_returns_error() {
|
||||
let result = render_dot("not valid dot {{{");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ pub(crate) async fn get_run_graph(
|
|||
// Use graphviz to render the demo DOT source
|
||||
let dot_source = "digraph demo {\n graph [goal=\"Demo\"]\n rankdir=LR\n start [shape=Mdiamond, label=\"Start\"]\n detect [label=\"Detect\\nDrift\"]\n exit [shape=Msquare, label=\"Exit\"]\n propose [label=\"Propose\\nChanges\"]\n review [label=\"Review\\nChanges\"]\n apply [label=\"Apply\\nChanges\"]\n start -> detect\n detect -> exit [label=\"No drift\"]\n detect -> propose [label=\"Drift found\"]\n propose -> review\n review -> propose [label=\"Revise\"]\n review -> apply [label=\"Accept\"]\n apply -> exit\n}";
|
||||
|
||||
crate::server::render_graph_bytes(dot_source, fabro_graphviz::render::GraphFormat::Svg).await
|
||||
crate::server::render_graph_bytes(dot_source).await
|
||||
}
|
||||
|
||||
pub(crate) async fn list_secrets(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
use std::time::Duration;
|
||||
|
||||
use base64::Engine as _;
|
||||
|
|
@ -13,10 +12,7 @@ use fabro_util::check_report::{CheckDetail, CheckResult, CheckSection, CheckStat
|
|||
use fabro_util::dev_token::validate_dev_token_format;
|
||||
use fabro_util::session_secret;
|
||||
use fabro_util::version::FABRO_VERSION;
|
||||
use regex::Regex;
|
||||
use semver::Version;
|
||||
use serde::Serialize;
|
||||
use tokio::process::Command;
|
||||
use tokio::time::timeout;
|
||||
|
||||
use crate::server::AppState;
|
||||
|
|
@ -41,69 +37,6 @@ pub struct DiagnosticsReport {
|
|||
pub sections: Vec<CheckSection>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
enum ProbeOutcome {
|
||||
NotFound,
|
||||
Failed,
|
||||
Ok { version: Option<Version> },
|
||||
}
|
||||
|
||||
static DOT_RE: LazyLock<Regex> =
|
||||
LazyLock::new(|| Regex::new(r"graphviz version (\d+)\.(\d+)\.(\d+)").unwrap());
|
||||
|
||||
fn parse_version(re: &Regex, output: &str) -> Option<Version> {
|
||||
let caps = re.captures(output)?;
|
||||
Some(Version::new(
|
||||
caps[1].parse().ok()?,
|
||||
caps[2].parse().ok()?,
|
||||
caps[3].parse().ok()?,
|
||||
))
|
||||
}
|
||||
|
||||
async fn probe_dot() -> ProbeOutcome {
|
||||
let result = Command::new("dot").arg("-V").output().await.ok();
|
||||
match result {
|
||||
None => ProbeOutcome::NotFound,
|
||||
Some(output) if !output.status.success() => ProbeOutcome::Failed,
|
||||
Some(output) => {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
let version =
|
||||
parse_version(&DOT_RE, &stdout).or_else(|| parse_version(&DOT_RE, &stderr));
|
||||
ProbeOutcome::Ok { version }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn check_dot() -> CheckResult {
|
||||
let outcome = probe_dot().await;
|
||||
let (status, summary, remediation) = match &outcome {
|
||||
ProbeOutcome::NotFound => (
|
||||
CheckStatus::Warning,
|
||||
"not installed".to_string(),
|
||||
Some("Install Graphviz to enable workflow graph rendering".to_string()),
|
||||
),
|
||||
ProbeOutcome::Failed => (
|
||||
CheckStatus::Warning,
|
||||
"command failed".to_string(),
|
||||
Some("Check that `dot -V` succeeds on the server host".to_string()),
|
||||
),
|
||||
ProbeOutcome::Ok {
|
||||
version: Some(version),
|
||||
} => (CheckStatus::Pass, format!("dot {version}"), None),
|
||||
ProbeOutcome::Ok { version: None } => {
|
||||
(CheckStatus::Pass, "dot available".to_string(), None)
|
||||
}
|
||||
};
|
||||
CheckResult {
|
||||
name: "dot".to_string(),
|
||||
status,
|
||||
summary,
|
||||
details: Vec::new(),
|
||||
remediation,
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_pem_value(name: &str, value: &str) -> Result<String, String> {
|
||||
if value.starts_with("-----") {
|
||||
return Ok(value.to_string());
|
||||
|
|
@ -150,11 +83,10 @@ fn validate_session_secret(value: &str) -> Result<(), String> {
|
|||
}
|
||||
|
||||
pub async fn run_all(state: &AppState) -> DiagnosticsReport {
|
||||
let (llm, github, brave, dot) = tokio::join!(
|
||||
let (llm, github, brave) = tokio::join!(
|
||||
check_llm_providers(state),
|
||||
check_github_app(state),
|
||||
check_brave_search(state),
|
||||
check_dot(),
|
||||
);
|
||||
let sandbox = check_sandbox(state);
|
||||
let crypto = check_crypto(state);
|
||||
|
|
@ -166,10 +98,6 @@ pub async fn run_all(state: &AppState) -> DiagnosticsReport {
|
|||
title: "Credentials".to_string(),
|
||||
checks: vec![llm, github, sandbox, brave],
|
||||
},
|
||||
CheckSection {
|
||||
title: "System".to_string(),
|
||||
checks: vec![dot],
|
||||
},
|
||||
CheckSection {
|
||||
title: "Configuration".to_string(),
|
||||
checks: vec![crypto],
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ pub use fabro_api::types::{
|
|||
DiskUsageSummaryRow, EventEnvelope as ApiEventEnvelope, ModelReference, PaginatedEventList,
|
||||
PaginatedRunList, PaginationMeta, PreflightResponse, PreviewUrlRequest, PreviewUrlResponse,
|
||||
PruneRunEntry, PruneRunsRequest, PruneRunsResponse, QuestionType as ApiQuestionType,
|
||||
RenderWorkflowGraphDirection, RenderWorkflowGraphFormat, RenderWorkflowGraphRequest,
|
||||
RunArtifactEntry, RunArtifactListResponse, RunBilling, RunBillingStage, RunBillingTotals,
|
||||
RenderWorkflowGraphDirection, RenderWorkflowGraphRequest, RunArtifactEntry,
|
||||
RunArtifactListResponse, RunBilling, RunBillingStage, RunBillingTotals,
|
||||
RunControlAction as ApiRunControlAction, RunError, RunManifest, RunStatus, RunStatusResponse,
|
||||
SandboxFileEntry, SandboxFileListResponse, SecretType as ApiSecretType, ServerSettings,
|
||||
SshAccessRequest, SshAccessResponse, StartRunRequest, StatusReason as ApiStatusReason,
|
||||
|
|
@ -39,7 +39,6 @@ pub use fabro_api::types::{
|
|||
};
|
||||
use fabro_auth::parse_credential_secret;
|
||||
use fabro_config::{Storage, resolve_server_from_file};
|
||||
use fabro_graphviz::render::GraphFormat;
|
||||
use fabro_interview::{
|
||||
Answer, ControlInterviewer, Interviewer, Question, QuestionType, WorkerControlEnvelope,
|
||||
};
|
||||
|
|
@ -3590,16 +3589,12 @@ async fn render_graph_from_manifest(
|
|||
return ApiError::bad_request("Validation failed").into_response();
|
||||
}
|
||||
|
||||
let format = match req.format.unwrap_or(RenderWorkflowGraphFormat::Svg) {
|
||||
RenderWorkflowGraphFormat::Svg => GraphFormat::Svg,
|
||||
RenderWorkflowGraphFormat::Png => GraphFormat::Png,
|
||||
};
|
||||
let direction = req.direction.as_ref().map(|direction| match direction {
|
||||
RenderWorkflowGraphDirection::Lr => "LR",
|
||||
RenderWorkflowGraphDirection::Tb => "TB",
|
||||
});
|
||||
let dot_source = run_manifest::graph_source(&prepared, direction);
|
||||
render_graph_bytes(&dot_source, format).await
|
||||
render_graph_bytes(&dot_source).await
|
||||
}
|
||||
|
||||
async fn start_run(
|
||||
|
|
@ -6178,18 +6173,17 @@ async fn create_completion(
|
|||
}
|
||||
}
|
||||
|
||||
/// Render DOT source to a styled image via `render_dot` on a blocking thread.
|
||||
pub(crate) async fn render_graph_bytes(dot_source: &str, format: GraphFormat) -> Response {
|
||||
/// Render DOT source to a styled SVG image via `render_dot` on a blocking
|
||||
/// thread.
|
||||
pub(crate) async fn render_graph_bytes(dot_source: &str) -> Response {
|
||||
use fabro_graphviz::render::render_dot;
|
||||
|
||||
let content_type = match format {
|
||||
GraphFormat::Svg => "image/svg+xml",
|
||||
GraphFormat::Png => "image/png",
|
||||
};
|
||||
let source = dot_source.to_owned();
|
||||
match spawn_blocking(move || render_dot(&source, format)).await {
|
||||
Ok(Ok(bytes)) => (StatusCode::OK, [("content-type", content_type)], bytes).into_response(),
|
||||
Ok(Err(e)) => ApiError::new(StatusCode::BAD_GATEWAY, e.to_string()).into_response(),
|
||||
match spawn_blocking(move || render_dot(&source)).await {
|
||||
Ok(Ok(bytes)) => {
|
||||
(StatusCode::OK, [("content-type", "image/svg+xml")], bytes).into_response()
|
||||
}
|
||||
Ok(Err(e)) => ApiError::new(StatusCode::BAD_REQUEST, e.to_string()).into_response(),
|
||||
Err(e) => ApiError::new(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
|
@ -6211,13 +6205,13 @@ async fn get_graph(
|
|||
}
|
||||
};
|
||||
if !live_dot_source.is_empty() {
|
||||
return render_graph_bytes(&live_dot_source, GraphFormat::Svg).await;
|
||||
return render_graph_bytes(&live_dot_source).await;
|
||||
}
|
||||
|
||||
match state.store.open_run_reader(&id).await {
|
||||
Ok(run_store) => match run_store.state().await {
|
||||
Ok(run_state) => match run_state.graph_source {
|
||||
Some(dot_source) => render_graph_bytes(&dot_source, GraphFormat::Svg).await,
|
||||
Some(dot_source) => render_graph_bytes(&dot_source).await,
|
||||
None => ApiError::new(StatusCode::NOT_FOUND, "Graph not found.").into_response(),
|
||||
},
|
||||
Err(err) => ApiError::new(StatusCode::BAD_GATEWAY, err.to_string()).into_response(),
|
||||
|
|
@ -7830,11 +7824,6 @@ slug = "fabro"
|
|||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
|
||||
// If graphviz is not installed, we get 502 — skip assertion
|
||||
if response.status() == StatusCode::BAD_GATEWAY {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
|
||||
let content_type = response
|
||||
|
|
@ -7886,10 +7875,6 @@ slug = "fabro"
|
|||
|
||||
let response = app.oneshot(req).await.unwrap();
|
||||
|
||||
if response.status() == StatusCode::BAD_GATEWAY {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
response
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ export const BillingApiAxiosParamCreator = function (configuration?: Configurati
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -54,8 +54,7 @@ export const CompletionsApiAxiosParamCreator = function (configuration?: Configu
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -145,8 +145,7 @@ export const DiscoveryApiAxiosParamCreator = function (configuration?: Configura
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -182,8 +181,7 @@ export const DiscoveryApiAxiosParamCreator = function (configuration?: Configura
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -114,8 +113,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -160,8 +158,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -207,8 +204,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -260,8 +256,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -315,8 +310,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -369,8 +363,7 @@ export const HumanInTheLoopApiAxiosParamCreator = function (configuration?: Conf
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -105,8 +104,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -145,8 +143,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -186,8 +183,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -233,8 +229,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -282,8 +277,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -326,8 +320,7 @@ export const InsightsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@ export const ModelsApiAxiosParamCreator = function (configuration?: Configuratio
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -115,8 +114,7 @@ export const ModelsApiAxiosParamCreator = function (configuration?: Configuratio
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -55,8 +55,7 @@ export const ReposApiAxiosParamCreator = function (configuration?: Configuration
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -120,8 +119,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -165,8 +163,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -213,8 +210,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -258,8 +254,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -301,8 +296,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -352,8 +346,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -405,8 +398,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -452,8 +444,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -509,8 +500,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -560,8 +550,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -601,8 +590,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -642,8 +630,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -686,8 +673,7 @@ export const RunInternalsApiAxiosParamCreator = function (configuration?: Config
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ export const RunOutputsApiAxiosParamCreator = function (configuration?: Configur
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -105,8 +104,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -148,8 +146,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -187,8 +184,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -232,8 +228,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -273,8 +268,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -292,7 +286,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
};
|
||||
},
|
||||
/**
|
||||
* Validates and renders a workflow manifest as SVG or PNG without creating a run.
|
||||
* Validates and renders a workflow manifest as SVG without creating a run.
|
||||
* @summary Render Workflow Graph
|
||||
* @param {RenderWorkflowGraphRequest} renderWorkflowGraphRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -313,15 +307,14 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
await setBearerAuthToObject(localVarHeaderParameter, configuration)
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'application/json';
|
||||
localVarHeaderParameter['Accept'] = 'image/svg+xml,image/png,application/json';
|
||||
localVarHeaderParameter['Accept'] = 'image/svg+xml,application/json';
|
||||
|
||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||
|
|
@ -356,8 +349,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -397,8 +389,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -437,8 +428,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -481,8 +471,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -524,8 +513,7 @@ export const RunsApiAxiosParamCreator = function (configuration?: Configuration)
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -630,7 +618,7 @@ export const RunsApiFp = function(configuration?: Configuration) {
|
|||
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
||||
},
|
||||
/**
|
||||
* Validates and renders a workflow manifest as SVG or PNG without creating a run.
|
||||
* Validates and renders a workflow manifest as SVG without creating a run.
|
||||
* @summary Render Workflow Graph
|
||||
* @param {RenderWorkflowGraphRequest} renderWorkflowGraphRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -778,7 +766,7 @@ export const RunsApiFactory = function (configuration?: Configuration, basePath?
|
|||
return localVarFp.pauseRun(id, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* Validates and renders a workflow manifest as SVG or PNG without creating a run.
|
||||
* Validates and renders a workflow manifest as SVG without creating a run.
|
||||
* @summary Render Workflow Graph
|
||||
* @param {RenderWorkflowGraphRequest} renderWorkflowGraphRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
@ -912,7 +900,7 @@ export class RunsApi extends BaseAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates and renders a workflow manifest as SVG or PNG without creating a run.
|
||||
* Validates and renders a workflow manifest as SVG without creating a run.
|
||||
* @summary Render Workflow Graph
|
||||
* @param {RenderWorkflowGraphRequest} renderWorkflowGraphRequest
|
||||
* @param {*} [options] Override http request option.
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ export const SecretsApiAxiosParamCreator = function (configuration?: Configurati
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -100,8 +99,7 @@ export const SecretsApiAxiosParamCreator = function (configuration?: Configurati
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -139,8 +137,7 @@ export const SecretsApiAxiosParamCreator = function (configuration?: Configurati
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ export const SettingsApiAxiosParamCreator = function (configuration?: Configurat
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -56,8 +56,7 @@ export const SystemApiAxiosParamCreator = function (configuration?: Configuratio
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -98,8 +97,7 @@ export const SystemApiAxiosParamCreator = function (configuration?: Configuratio
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -139,8 +137,7 @@ export const SystemApiAxiosParamCreator = function (configuration?: Configuratio
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
@ -179,8 +176,7 @@ export const SystemApiAxiosParamCreator = function (configuration?: Configuratio
|
|||
const localVarHeaderParameter = {} as any;
|
||||
const localVarQueryParameter = {} as any;
|
||||
|
||||
// authentication mTLS required
|
||||
await setApiKeyToObject(localVarHeaderParameter, "X-mTLS-Client-CN", configuration)
|
||||
// authentication SessionCookie required
|
||||
|
||||
// authentication BearerAuth required
|
||||
// http bearer authentication required
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
|
||||
export const RenderWorkflowGraphFormat = {
|
||||
SVG: 'svg',
|
||||
PNG: 'png'
|
||||
SVG: 'svg'
|
||||
} as const;
|
||||
|
||||
export type RenderWorkflowGraphFormat = typeof RenderWorkflowGraphFormat[keyof typeof RenderWorkflowGraphFormat];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue