mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-24 00:51:19 +00:00
fabro(01KS9BXFGAZ32SGNRE4YJV1354): simplify_gpt (succeeded)
Fabro-Run: 01KS9BXFGAZ32SGNRE4YJV1354
Fabro-Completed: 9
Fabro-Checkpoint: d9ebe7948c
⚒️ Generated with [Fabro](https://fabro.sh)
This commit is contained in:
parent
f98755fa02
commit
ae8a3c4308
25 changed files with 166 additions and 120 deletions
|
|
@ -161,7 +161,7 @@ fn start_detached_human_run(
|
|||
.args([
|
||||
"run",
|
||||
"--detach",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--provider",
|
||||
"openai",
|
||||
|
|
@ -391,7 +391,7 @@ fn attach_advances_when_pending_question_is_answered_elsewhere() {
|
|||
.args([
|
||||
"run",
|
||||
"--detach",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--provider",
|
||||
"openai",
|
||||
|
|
@ -516,7 +516,7 @@ fn attach_before_completion_streams_to_finished_state() {
|
|||
"--detach",
|
||||
"--provider",
|
||||
"openai",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"slow.fabro",
|
||||
]);
|
||||
|
|
@ -637,7 +637,7 @@ fn attach_json_errors_without_prompting_for_human_input() {
|
|||
.args([
|
||||
"run",
|
||||
"--detach",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--provider",
|
||||
"openai",
|
||||
|
|
|
|||
|
|
@ -45,25 +45,25 @@ fn help() {
|
|||
<WORKFLOW> Path to a .fabro workflow file or .toml task config
|
||||
|
||||
Options:
|
||||
--json Output as JSON [env: FABRO_JSON=]
|
||||
--server <SERVER> Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=]
|
||||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
-I, --input <KEY=VALUE> Override a workflow input value (repeatable, format: KEY=VALUE)
|
||||
--dry-run Execute with simulated LLM backend
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--auto-approve Auto-approve all human gates
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--goal <GOAL> Override the workflow goal (available as {{ goal }} in prompts)
|
||||
--goal-file <GOAL_FILE> Read the workflow goal from a file
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
-v, --verbose Enable verbose output
|
||||
--sandbox <SANDBOX> Sandbox for agent tools [possible values: local, docker, daytona]
|
||||
--label <KEY=VALUE> Attach a label to this run (repeatable, format: KEY=VALUE)
|
||||
--parent <RUN> Link this run to an existing orchestration parent run
|
||||
--preserve-sandbox Keep the sandbox alive after the run finishes (for debugging)
|
||||
-d, --detach Run the workflow in the background and print the run ID
|
||||
-h, --help Print help
|
||||
--json Output as JSON [env: FABRO_JSON=]
|
||||
--server <SERVER> Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=]
|
||||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
-I, --input <KEY=VALUE> Override a workflow input value (repeatable, format: KEY=VALUE)
|
||||
--dry-run Execute with simulated LLM backend
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--auto-approve Auto-approve all human gates
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--goal <GOAL> Override the workflow goal (available as {{ goal }} in prompts)
|
||||
--goal-file <GOAL_FILE> Read the workflow goal from a file
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
-v, --verbose Enable verbose output
|
||||
--environment <ENVIRONMENT> Named environment for agent tools
|
||||
--label <KEY=VALUE> Attach a label to this run (repeatable, format: KEY=VALUE)
|
||||
--parent <RUN> Link this run to an existing orchestration parent run
|
||||
--preserve-sandbox Keep the sandbox alive after the run finishes (for debugging)
|
||||
-d, --detach Run the workflow in the background and print the run ID
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ fn dump_exports_large_command_output_backed_by_blob_refs() {
|
|||
let mut run_cmd = context.run_cmd();
|
||||
run_cmd.current_dir(&context.temp_dir);
|
||||
run_cmd.timeout(Duration::from_secs(30));
|
||||
run_cmd.args(["--run-id", run_id.as_str(), "--sandbox", "local"]);
|
||||
run_cmd.args(["--run-id", run_id.as_str(), "--environment", "local"]);
|
||||
run_cmd.arg(&workflow);
|
||||
let run_output = run_cmd.output().expect("command should execute");
|
||||
assert!(
|
||||
|
|
@ -194,7 +194,7 @@ include = ["assets/**"]
|
|||
run_cmd.args([
|
||||
"--run-id",
|
||||
run_id.as_str(),
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"run.toml",
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -20,19 +20,19 @@ fn help() {
|
|||
<WORKFLOW> Path to a .fabro workflow file or .toml task config
|
||||
|
||||
Options:
|
||||
--json Output as JSON [env: FABRO_JSON=]
|
||||
--server <SERVER> Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=]
|
||||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
-I, --input <KEY=VALUE> Override a workflow input value (repeatable, format: KEY=VALUE)
|
||||
--goal <GOAL> Override the workflow goal (available as {{ goal }} in prompts)
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--goal-file <GOAL_FILE> Read the workflow goal from a file
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
-v, --verbose Enable verbose output
|
||||
--sandbox <SANDBOX> Sandbox for agent tools [possible values: local, docker, daytona]
|
||||
-h, --help Print help
|
||||
--json Output as JSON [env: FABRO_JSON=]
|
||||
--server <SERVER> Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=]
|
||||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
-I, --input <KEY=VALUE> Override a workflow input value (repeatable, format: KEY=VALUE)
|
||||
--goal <GOAL> Override the workflow goal (available as {{ goal }} in prompts)
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--goal-file <GOAL_FILE> Read the workflow goal from a file
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
-v, --verbose Enable verbose output
|
||||
--environment <ENVIRONMENT> Named environment for agent tools
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,25 +123,25 @@ fn help() {
|
|||
<WORKFLOW> Path to a .fabro workflow file or .toml task config
|
||||
|
||||
Options:
|
||||
--json Output as JSON [env: FABRO_JSON=]
|
||||
--server <SERVER> Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=]
|
||||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
-I, --input <KEY=VALUE> Override a workflow input value (repeatable, format: KEY=VALUE)
|
||||
--dry-run Execute with simulated LLM backend
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--auto-approve Auto-approve all human gates
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--goal <GOAL> Override the workflow goal (available as {{ goal }} in prompts)
|
||||
--goal-file <GOAL_FILE> Read the workflow goal from a file
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
-v, --verbose Enable verbose output
|
||||
--sandbox <SANDBOX> Sandbox for agent tools [possible values: local, docker, daytona]
|
||||
--label <KEY=VALUE> Attach a label to this run (repeatable, format: KEY=VALUE)
|
||||
--parent <RUN> Link this run to an existing orchestration parent run
|
||||
--preserve-sandbox Keep the sandbox alive after the run finishes (for debugging)
|
||||
-d, --detach Run the workflow in the background and print the run ID
|
||||
-h, --help Print help
|
||||
--json Output as JSON [env: FABRO_JSON=]
|
||||
--server <SERVER> Fabro server target: http(s) URL or absolute Unix socket path [env: FABRO_SERVER=]
|
||||
--debug Enable DEBUG-level logging (default is INFO) [env: FABRO_DEBUG=]
|
||||
-I, --input <KEY=VALUE> Override a workflow input value (repeatable, format: KEY=VALUE)
|
||||
--dry-run Execute with simulated LLM backend
|
||||
--no-upgrade-check Disable automatic upgrade check [env: FABRO_NO_UPGRADE_CHECK=true]
|
||||
--auto-approve Auto-approve all human gates
|
||||
--quiet Suppress non-essential output [env: FABRO_QUIET=]
|
||||
--goal <GOAL> Override the workflow goal (available as {{ goal }} in prompts)
|
||||
--goal-file <GOAL_FILE> Read the workflow goal from a file
|
||||
--model <MODEL> Override default LLM model
|
||||
--provider <PROVIDER> Override default LLM provider
|
||||
-v, --verbose Enable verbose output
|
||||
--environment <ENVIRONMENT> Named environment for agent tools
|
||||
--label <KEY=VALUE> Attach a label to this run (repeatable, format: KEY=VALUE)
|
||||
--parent <RUN> Link this run to an existing orchestration parent run
|
||||
--preserve-sandbox Keep the sandbox alive after the run finishes (for debugging)
|
||||
-d, --detach Run the workflow in the background and print the run ID
|
||||
-h, --help Print help
|
||||
----- stderr -----
|
||||
");
|
||||
}
|
||||
|
|
@ -412,7 +412,7 @@ digraph VaultWorkerLlm {
|
|||
"--run-id",
|
||||
run_id.as_str(),
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--provider",
|
||||
"anthropic",
|
||||
|
|
@ -770,7 +770,7 @@ include = ["assets/**"]
|
|||
"--run-id",
|
||||
run_id.as_str(),
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--provider",
|
||||
"openai",
|
||||
|
|
@ -899,7 +899,7 @@ fn dry_run_persists_event_history_in_store() {
|
|||
"run",
|
||||
"--dry-run",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--run-id",
|
||||
run_id.as_str(),
|
||||
|
|
@ -1041,7 +1041,7 @@ fn json_run_requires_manual_input_for_human_gates_without_auto_approve() {
|
|||
.args([
|
||||
"--json",
|
||||
"run",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
workflow.to_str().unwrap(),
|
||||
])
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ methods = ["dev-token"]
|
|||
run_id.as_str(),
|
||||
"--detach",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
workflow_path
|
||||
.to_str()
|
||||
|
|
@ -734,7 +734,7 @@ fn detached_run_answers_pending_question_without_interview_scratch_files() {
|
|||
"--detach",
|
||||
"--run-id",
|
||||
run_id.as_str(),
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
workflow_path.to_str().unwrap(),
|
||||
])
|
||||
|
|
@ -807,7 +807,7 @@ fn worker_exits_after_sigterm_cancel_even_when_stdin_stays_open() {
|
|||
.args([
|
||||
"create",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--run-id",
|
||||
run_id.as_str(),
|
||||
|
|
|
|||
|
|
@ -208,8 +208,8 @@ fn help() {
|
|||
Override default LLM model
|
||||
--provider <PROVIDER>
|
||||
Override default LLM provider
|
||||
--sandbox <SANDBOX>
|
||||
Sandbox for agent tools
|
||||
--environment <ENVIRONMENT>
|
||||
Named environment for agent tools
|
||||
--max-concurrent-runs <MAX_CONCURRENT_RUNS>
|
||||
Maximum number of concurrent run executions
|
||||
--config <CONFIG>
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ fn start_rejects_already_active_or_completed_run() {
|
|||
"create",
|
||||
"--provider",
|
||||
"openai",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"slow.fabro",
|
||||
]);
|
||||
|
|
@ -204,7 +204,7 @@ fn start_runs_under_server_ownership_without_launcher_record() {
|
|||
"create",
|
||||
"--provider",
|
||||
"openai",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"owned-by-server.fabro",
|
||||
])
|
||||
|
|
|
|||
|
|
@ -245,14 +245,14 @@ fn run_completed_dry_run(context: &TestContext, workflow: &Path) -> RunSetup {
|
|||
run_id.as_str(),
|
||||
"--dry-run",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
]);
|
||||
cmd.arg(workflow);
|
||||
let output = cmd.output().expect("command should execute");
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"command failed: fabro run --dry-run --auto-approve --sandbox local {}\nstdout:\n{}\nstderr:\n{}",
|
||||
"command failed: fabro run --dry-run --auto-approve --environment local {}\nstdout:\n{}\nstderr:\n{}",
|
||||
workflow.display(),
|
||||
stdout(&output),
|
||||
stderr(&output)
|
||||
|
|
@ -308,14 +308,14 @@ pub(crate) fn setup_detached_dry_run(context: &TestContext) -> RunSetup {
|
|||
"--detach",
|
||||
"--dry-run",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
]);
|
||||
cmd.arg(workflow);
|
||||
let output = cmd.output().expect("command should execute");
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"command failed: fabro run --detach --dry-run --auto-approve --sandbox local {}\nstdout:\n{}\nstderr:\n{}",
|
||||
"command failed: fabro run --detach --dry-run --auto-approve --environment local {}\nstdout:\n{}\nstderr:\n{}",
|
||||
fixture("simple.fabro").display(),
|
||||
stdout(&output),
|
||||
stderr(&output)
|
||||
|
|
@ -413,7 +413,7 @@ fn run_local_workflow(context: &TestContext, workspace_dir: &Path, workflow: &st
|
|||
"--run-id",
|
||||
run_id.as_str(),
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
"--provider",
|
||||
"openai",
|
||||
|
|
@ -422,7 +422,7 @@ fn run_local_workflow(context: &TestContext, workspace_dir: &Path, workflow: &st
|
|||
let output = cmd.output().expect("command should execute");
|
||||
if !output.status.success() {
|
||||
panic!(
|
||||
"command failed: fabro run --auto-approve --sandbox local --provider openai {workflow}\nstdout:\n{}\nstderr:\n{}",
|
||||
"command failed: fabro run --auto-approve --environment local --provider openai {workflow}\nstdout:\n{}\nstderr:\n{}",
|
||||
stdout(&output),
|
||||
stderr(&output)
|
||||
);
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ async fn github_only_server_dispatched_worker_succeeds_without_worker_auth_store
|
|||
"--detach",
|
||||
"--dry-run",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
workflow.to_str().unwrap(),
|
||||
])
|
||||
|
|
@ -358,7 +358,7 @@ fn runner_rejects_bogus_worker_token_against_github_only_server() {
|
|||
&run_id,
|
||||
"--dry-run",
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
workflow.to_str().unwrap(),
|
||||
])
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ fn local_run_lifecycle() {
|
|||
.run_cmd()
|
||||
.args([
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
"local",
|
||||
fixture("command_pipeline.fabro").to_str().unwrap(),
|
||||
])
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ fn acp_backend_workflow() {
|
|||
|
||||
context
|
||||
.run_cmd()
|
||||
.args(["--auto-approve", "--sandbox", "local"])
|
||||
.args(["--auto-approve", "--environment", "local"])
|
||||
.arg(&workflow)
|
||||
.assert()
|
||||
.success();
|
||||
|
|
@ -119,7 +119,7 @@ fn acp_backend_does_not_inject_registered_provider_credentials() {
|
|||
.env_remove("ANTHROPIC_API_KEY")
|
||||
.env_remove("OPENAI_API_KEY")
|
||||
.env_remove("GEMINI_API_KEY")
|
||||
.args(["--auto-approve", "--sandbox", "local"])
|
||||
.args(["--auto-approve", "--environment", "local"])
|
||||
.arg(&workflow)
|
||||
.assert()
|
||||
.success();
|
||||
|
|
@ -193,7 +193,7 @@ include = ["verification-artifacts/**"]
|
|||
|
||||
context
|
||||
.run_cmd()
|
||||
.args(["--auto-approve", "--sandbox", "local"])
|
||||
.args(["--auto-approve", "--environment", "local"])
|
||||
.arg(context.temp_dir.join("run.toml"))
|
||||
.assert()
|
||||
.success();
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ fn scenario_agent_linear(sandbox: &str) {
|
|||
.run_cmd()
|
||||
.args([
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
sandbox,
|
||||
"--model",
|
||||
"claude-haiku-4-5",
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ include = ["assets/**"]
|
|||
|
||||
context
|
||||
.run_cmd()
|
||||
.args(["--auto-approve", "--sandbox", "local"])
|
||||
.args(["--auto-approve", "--environment", "local"])
|
||||
.arg(context.temp_dir.join("run.toml"))
|
||||
.assert()
|
||||
.success();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ fn scenario_command_agent_mixed(sandbox: &str) {
|
|||
.run_cmd()
|
||||
.args([
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
sandbox,
|
||||
"--model",
|
||||
"claude-haiku-4-5",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ fn scenario_command_pipeline(sandbox: &str) {
|
|||
|
||||
context
|
||||
.run_cmd()
|
||||
.args(["--auto-approve", "--sandbox", sandbox])
|
||||
.args(["--auto-approve", "--environment", sandbox])
|
||||
.arg(fixture("command_pipeline.fabro"))
|
||||
.timeout(timeout_for(sandbox))
|
||||
.assert()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ fn scenario_conditional_branching(sandbox: &str) {
|
|||
|
||||
context
|
||||
.run_cmd()
|
||||
.args(["--auto-approve", "--sandbox", sandbox])
|
||||
.args(["--auto-approve", "--environment", sandbox])
|
||||
.arg(fixture("conditional_branching.fabro"))
|
||||
.timeout(timeout_for(sandbox))
|
||||
.assert()
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ fn scenario_full_stack(sandbox: &str) {
|
|||
.run_cmd()
|
||||
.args([
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
sandbox,
|
||||
"--model",
|
||||
"claude-haiku-4-5",
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ fn configure_hook_env(cmd: &mut assert_cmd::Command, hook_model: &str) {
|
|||
if TestMode::from_env().is_twin() {
|
||||
cmd.env_remove("ANTHROPIC_API_KEY");
|
||||
}
|
||||
cmd.arg("--sandbox").arg("local");
|
||||
cmd.arg("--environment").arg("local");
|
||||
cmd.arg("--auto-approve");
|
||||
cmd.arg("--provider").arg(stage_provider());
|
||||
cmd.arg("--model").arg(hook_model);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ fn scenario_human_gate(sandbox: &str) {
|
|||
.run_cmd()
|
||||
.args([
|
||||
"--auto-approve",
|
||||
"--sandbox",
|
||||
"--environment",
|
||||
sandbox,
|
||||
"--model",
|
||||
"claude-haiku-4-5",
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ use fabro_util::error::SharedError;
|
|||
use crate::defaults::DEFAULTS_LAYER;
|
||||
use crate::load::load_settings_path;
|
||||
use crate::resolve::{
|
||||
ResolveError, resolve_cli, resolve_project, resolve_run, resolve_server,
|
||||
resolve_workflow,
|
||||
ResolveError, resolve_cli, resolve_project, resolve_run, resolve_server, resolve_workflow,
|
||||
};
|
||||
use crate::user::load_settings_config;
|
||||
use crate::{
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@ pub(crate) fn resolve_run_environment(
|
|||
return RunEnvironmentSettings::from_environment(id, EnvironmentSettings::default());
|
||||
};
|
||||
|
||||
let merged = layer.clone().into_environment_override().combine(base.clone());
|
||||
let merged = layer
|
||||
.clone()
|
||||
.into_environment_override()
|
||||
.combine(base.clone());
|
||||
let environment = resolve_environment_layer(&merged, "run.environment", errors);
|
||||
validate_provider_capabilities(&environment, "run.environment", errors);
|
||||
RunEnvironmentSettings::from_environment(id, environment)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
//! These mappings are consumed by both the workflow run-start path and the
|
||||
//! server preflight path, so they live here next to their destination types.
|
||||
|
||||
#[cfg(feature = "docker")]
|
||||
use fabro_types::settings::interp::InterpString;
|
||||
#[cfg(feature = "daytona")]
|
||||
use fabro_types::settings::run::DockerfileSource as ResolvedDockerfileSource;
|
||||
use fabro_types::settings::run::{EnvironmentNetworkMode, RunEnvironmentSettings};
|
||||
|
|
@ -55,16 +53,18 @@ pub fn daytona_config_from_environment(
|
|||
.resources
|
||||
.disk
|
||||
.map(|size| size_to_gb_i32(size.as_bytes())),
|
||||
dockerfile: settings.image.dockerfile.as_ref().map(|dockerfile| {
|
||||
match dockerfile {
|
||||
dockerfile: settings
|
||||
.image
|
||||
.dockerfile
|
||||
.as_ref()
|
||||
.map(|dockerfile| match dockerfile {
|
||||
ResolvedDockerfileSource::Inline(text) => {
|
||||
SandboxDockerfileSource::Inline(text.clone())
|
||||
}
|
||||
ResolvedDockerfileSource::Path { path } => {
|
||||
SandboxDockerfileSource::Path { path: path.clone() }
|
||||
}
|
||||
}
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
network: Some(match settings.network.mode {
|
||||
EnvironmentNetworkMode::Block => DaytonaNetwork::Block,
|
||||
|
|
@ -84,9 +84,9 @@ pub fn docker_config_from_environment(
|
|||
skip_clone: bool,
|
||||
) -> DockerSandboxOptions {
|
||||
let mut env_vars = settings
|
||||
.env
|
||||
.iter()
|
||||
.map(|(key, value)| format!("{key}={}", resolve_interp(value)))
|
||||
.resolve_env(process_env_var)
|
||||
.into_iter()
|
||||
.map(|(key, value)| format!("{key}={value}"))
|
||||
.collect::<Vec<_>>();
|
||||
env_vars.sort();
|
||||
let default_options = DockerSandboxOptions::default();
|
||||
|
|
@ -117,13 +117,6 @@ pub fn docker_config_from_environment(
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "docker")]
|
||||
fn resolve_interp(value: &InterpString) -> String {
|
||||
value
|
||||
.resolve(process_env_var)
|
||||
.map_or_else(|_| value.as_source(), |resolved| resolved.value)
|
||||
}
|
||||
|
||||
#[cfg(feature = "docker")]
|
||||
#[expect(
|
||||
clippy::disallowed_methods,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//!
|
||||
//! `[run]` is the shared execution domain. It may appear in all three config
|
||||
//! files and layer normally. Subdomains cover model selection, git author,
|
||||
//! prepare steps, execution posture, checkpoint policy, sandbox selection,
|
||||
//! prepare steps, execution posture, checkpoint policy, environment selection,
|
||||
//! notifications, interviews, agent knobs, hooks, SCM targeting, pull-request
|
||||
//! behavior, and artifact collection.
|
||||
|
||||
|
|
@ -468,6 +468,24 @@ impl RunEnvironmentSettings {
|
|||
env: environment.env,
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve every environment value's `{{ env.* }}` tokens via `lookup`,
|
||||
/// falling back to the original source string when resolution fails.
|
||||
#[must_use]
|
||||
pub fn resolve_env<F>(&self, mut lookup: F) -> HashMap<String, String>
|
||||
where
|
||||
F: FnMut(&str) -> Option<String>,
|
||||
{
|
||||
self.env
|
||||
.iter()
|
||||
.map(|(name, value)| {
|
||||
let resolved = value
|
||||
.resolve(&mut lookup)
|
||||
.map_or_else(|_| value.as_source(), |resolved| resolved.value);
|
||||
(name.clone(), resolved)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RunEnvironmentSettings {
|
||||
|
|
@ -476,6 +494,50 @@ impl Default for RunEnvironmentSettings {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod run_environment_settings_tests {
|
||||
use super::{HashMap, InterpString, RunEnvironmentSettings};
|
||||
|
||||
fn settings(env: &[(&str, &str)]) -> RunEnvironmentSettings {
|
||||
RunEnvironmentSettings {
|
||||
env: env
|
||||
.iter()
|
||||
.map(|(k, v)| ((*k).to_string(), InterpString::parse(v)))
|
||||
.collect(),
|
||||
..RunEnvironmentSettings::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_env_substitutes_env_tokens_via_lookup() {
|
||||
let s = settings(&[("NODE_ENV", "{{ env.NODE_ENV }}"), ("STATIC", "value")]);
|
||||
let resolved = s.resolve_env(|name| match name {
|
||||
"NODE_ENV" => Some("test".to_string()),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
assert_eq!(resolved.get("NODE_ENV"), Some(&"test".to_string()));
|
||||
assert_eq!(resolved.get("STATIC"), Some(&"value".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_env_falls_back_to_source_when_lookup_fails() {
|
||||
let s = settings(&[("NODE_ENV", "{{ env.MISSING_NODE_ENV }}")]);
|
||||
let resolved = s.resolve_env(|_| None);
|
||||
|
||||
assert_eq!(
|
||||
resolved.get("NODE_ENV"),
|
||||
Some(&"{{ env.MISSING_NODE_ENV }}".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_env_is_empty_for_empty_settings() {
|
||||
let s: HashMap<String, String> = settings(&[]).resolve_env(|_| None);
|
||||
assert!(s.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum DockerfileSource {
|
||||
Inline(String),
|
||||
|
|
|
|||
|
|
@ -363,12 +363,7 @@ impl RunSession {
|
|||
}
|
||||
};
|
||||
|
||||
let toml_env: HashMap<String, String> = resolved
|
||||
.environment
|
||||
.env
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), resolve_interp(v)))
|
||||
.collect();
|
||||
let toml_env = resolved.environment.resolve_env(process_env_var);
|
||||
let github_permissions: Option<HashMap<String, String>> =
|
||||
(!services.github_permissions.is_empty()).then(|| services.github_permissions.clone());
|
||||
let sandbox_env = SandboxEnvSpec {
|
||||
|
|
@ -459,12 +454,6 @@ async fn configured_providers_for_start(
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_interp(value: &InterpString) -> String {
|
||||
value
|
||||
.resolve(process_env_var)
|
||||
.map_or_else(|_| value.as_source(), |resolved| resolved.value)
|
||||
}
|
||||
|
||||
fn git_checkpoint_options_from_start(
|
||||
settings: &fabro_types::WorkflowSettings,
|
||||
run_id: &RunId,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue