diff --git a/.env-example b/.env-example index c6307e4..6ee67d5 100644 --- a/.env-example +++ b/.env-example @@ -1,8 +1,13 @@ ENVIRONMENT='development' MODE='dynamic' + NATS_URL='nats://localhost:4222' -AQUILA_URL='http://localhost:8080' +AQUILA_URL='http://localhost:50051' +AQUILA_TOKEN='token' + WITH_HEALTH_SERVICE=false GRPC_HOST='127.0.0.1' GRPC_PORT=50051 -DEFINITIONS='./definitions' \ No newline at end of file + +DEFINITIONS='./definitions' +RUNTIME_STATUS_UPDATE_INTERVAL_SECONDS=30 diff --git a/Cargo.lock b/Cargo.lock index 9ca9fbb..baa2632 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,9 +295,9 @@ checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "code0-flow" -version = "0.0.32" +version = "0.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d74d62174eb76c90d7c1642a05f20084bb563ec8a1249c0f05bbd7ed03023" +checksum = "6e8a97ac31e8340a97ab6468dbcab82d835346182ca309d8518245acb1f6ffd3" dependencies = [ "async-nats", "async-trait", @@ -2184,9 +2184,9 @@ dependencies = [ [[package]] name = "tucana" -version = "0.0.68" +version = "0.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abae78f798d1203bbcce361ba4cb4c500f8fe64e56d16ba3a5a0854e285377eb" +checksum = "1ececdc8eeccd39a9ba82a4ee78e9663d9871a9ca9da65013477536360322392" dependencies = [ "pbjson", "pbjson-build", diff --git a/Cargo.toml b/Cargo.toml index 09e8841..9f73441 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,8 @@ edition = "2024" [workspace.dependencies] async-trait = "0.1.89" -code0-flow = { version = "0.0.32" } -tucana = { version = "0.0.68" } +code0-flow = { version = "0.0.33" } +tucana = { version = "0.0.70" } tokio = { version = "1.44.1", features = ["rt-multi-thread", "signal"] } log = "0.4.27" futures-lite = "2.6.0" diff --git a/README.md b/README.md new file mode 100644 index 0000000..0ef7fca --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Taurus +The heart of the execution block - the runtime itself + +- Executes flows and handles test executions +- Requests single node executions from Actions +- Serves the standard CodeZero library + +## Used Technologies + +[Rust](https://www.rust-lang.org/) x [Tonic](https://docs.rs/tonic/latest/tonic/) + +## Contribute / Setup +Read the [Installation Guide](https://docs.code0.tech/taurus/installation/) if you want to deploy a Taurus instance or see the [Development Guide](https://docs.code0.tech/taurus/dev/) if you want to contribute. diff --git a/crates/taurus-core/src/runtime/engine.rs b/crates/taurus-core/src/runtime/engine.rs index c7e4599..f2f1e53 100644 --- a/crates/taurus-core/src/runtime/engine.rs +++ b/crates/taurus-core/src/runtime/engine.rs @@ -181,6 +181,7 @@ mod tests { value: Some(NodeValue { value: Some(node_value::Value::LiteralValue(value)), }), + cast: None, } } @@ -189,8 +190,11 @@ mod tests { database_id, runtime_parameter_id: runtime_parameter_id.to_string(), value: Some(NodeValue { - value: Some(node_value::Value::NodeFunctionId(node_id)), + value: Some(node_value::Value::SubFlow(unimplemented!( + "Taurus needs to handle SubFlows (issue nr #184)" + ))), }), + cast: None, } } @@ -208,6 +212,7 @@ mod tests { paths: Vec::new(), })), }), + cast: None, } } @@ -276,6 +281,7 @@ mod tests { paths: Vec::new(), })), }), + cast: None, } } diff --git a/crates/taurus-core/src/runtime/engine/compiler.rs b/crates/taurus-core/src/runtime/engine/compiler.rs index 3f4ae57..33a5d8f 100644 --- a/crates/taurus-core/src/runtime/engine/compiler.rs +++ b/crates/taurus-core/src/runtime/engine/compiler.rs @@ -125,7 +125,7 @@ pub fn compile_flow( let arg = match value { node_value::Value::LiteralValue(v) => CompiledArg::Literal(v.clone()), node_value::Value::ReferenceValue(r) => CompiledArg::Reference(r.clone()), - node_value::Value::NodeFunctionId(id) => CompiledArg::DeferredNode(*id), + node_value::Value::SubFlow(_sub_flow) => unimplemented!("Taurus needs to handle SubFlows (issue nr #184)"), }; parameters.push(CompiledParameter { diff --git a/crates/taurus-core/src/runtime/engine/executor.rs b/crates/taurus-core/src/runtime/engine/executor.rs index c8aeb27..ea2acc1 100644 --- a/crates/taurus-core/src/runtime/engine/executor.rs +++ b/crates/taurus-core/src/runtime/engine/executor.rs @@ -4,7 +4,7 @@ use std::cell::RefCell; use std::collections::HashMap; use futures_lite::future::block_on; -use tucana::aquila::ExecutionRequest; +use tucana::aquila::ActionExecutionRequest; use tucana::shared::reference_value::Target; use tucana::shared::value::Kind; use tucana::shared::{Struct, Value}; @@ -485,7 +485,7 @@ impl<'a> EngineExecutor<'a> { &self, node: &CompiledNode, values: Vec, - ) -> Result { + ) -> Result { if node.parameters.len() != values.len() { return Err(RuntimeError::new( "T-CORE-000005", @@ -499,7 +499,7 @@ impl<'a> EngineExecutor<'a> { fields.insert(parameter.runtime_parameter_id.clone(), value); } - Ok(ExecutionRequest { + Ok(ActionExecutionRequest { execution_identifier: Uuid::new_v4().to_string(), function_identifier: node.handler_id.clone(), parameters: Some(Struct { fields }), diff --git a/crates/taurus-core/src/runtime/remote/mod.rs b/crates/taurus-core/src/runtime/remote/mod.rs index f5ab662..5b3cd9f 100644 --- a/crates/taurus-core/src/runtime/remote/mod.rs +++ b/crates/taurus-core/src/runtime/remote/mod.rs @@ -4,7 +4,7 @@ //! trait without coupling the core engine to a specific transport. use async_trait::async_trait; -use tucana::{aquila::ExecutionRequest, shared::Value}; +use tucana::{aquila::ActionExecutionRequest, shared::Value}; use crate::types::errors::runtime_error::RuntimeError; @@ -12,7 +12,8 @@ pub struct RemoteExecution { /// Remote service identifier to route the call. pub target_service: String, /// Execution request payload expected by the remote runtime. - pub request: ExecutionRequest, + pub request: ActionExecutionRequest, + } #[async_trait] diff --git a/crates/taurus-provider/src/providers/remote/nats_remote_runtime.rs b/crates/taurus-provider/src/providers/remote/nats_remote_runtime.rs index 9ef694b..e7b09e7 100644 --- a/crates/taurus-provider/src/providers/remote/nats_remote_runtime.rs +++ b/crates/taurus-provider/src/providers/remote/nats_remote_runtime.rs @@ -3,7 +3,7 @@ use prost::Message; use taurus_core::runtime::remote::{RemoteExecution, RemoteRuntime}; use taurus_core::types::errors::runtime_error::RuntimeError; use tonic::async_trait; -use tucana::aquila::ExecutionResult; +use tucana::aquila::ActionExecutionResponse; use tucana::shared::Value; pub struct NATSRemoteRuntime { @@ -42,8 +42,8 @@ impl RemoteRuntime for NATSRemoteRuntime { } }; - let decode_result = ExecutionResult::decode(message.payload); - let execution_result = match decode_result { + let decode_result = ActionExecutionResponse::decode(message.payload); + let _execution_result = match decode_result { Ok(r) => r, Err(err) => { log::error!( @@ -58,24 +58,6 @@ impl RemoteRuntime for NATSRemoteRuntime { } }; - match execution_result.result { - Some(result) => match result { - tucana::aquila::execution_result::Result::Success(value) => Ok(value), - tucana::aquila::execution_result::Result::Error(err) => { - let code = err.code.to_string(); - let description = match err.description { - Some(string) => string, - None => "Unknown Error".to_string(), - }; - let error = RuntimeError::new(code, "RemoteExecutionError", description); - Err(error) - } - }, - None => Err(RuntimeError::new( - "T-PROV-000003", - "RemoteRuntimeExeption", - "Result of Remote Response was empty.", - )), - } + unimplemented!("Taurus needs to handle text executions (issue nr #185)") } } diff --git a/crates/taurus/src/app/mod.rs b/crates/taurus/src/app/mod.rs index 3bf3587..fe3712e 100644 --- a/crates/taurus/src/app/mod.rs +++ b/crates/taurus/src/app/mod.rs @@ -1,10 +1,10 @@ mod worker; -use std::time::Duration; - use code0_flow::flow_config::load_env_file; use code0_flow::flow_config::mode::Mode::DYNAMIC; use code0_flow::flow_service::FlowUpdateService; +use std::sync::Arc; +use std::time::Duration; use taurus_core::runtime::engine::ExecutionEngine; use taurus_provider::providers::emitter::nats_emitter::NATSRespondEmitter; use taurus_provider::providers::remote::nats_remote_runtime::NATSRemoteRuntime; @@ -12,7 +12,6 @@ use tokio::signal; use tokio::task::JoinHandle; use tokio::time::sleep; use tonic_health::pb::health_server::HealthServer; -use tucana::shared::{RuntimeFeature, Translation}; use crate::client::runtime_status::TaurusRuntimeStatusService; use crate::client::runtime_usage::TaurusRuntimeUsageService; @@ -27,7 +26,7 @@ pub async fn run() { let client = connect_nats(&config).await; let mut health_task = spawn_health_task(&config); - let (runtime_status_service, runtime_usage_service) = + let (runtime_status_service, runtime_usage_service, mut runtime_status_heartbeat_task) = setup_dynamic_services_if_needed(&config).await; let nats_remote = NATSRemoteRuntime::new(client.clone()); @@ -41,6 +40,14 @@ pub async fn run() { ); wait_for_shutdown(&mut worker_task, &mut health_task).await; + if let Some(handle) = runtime_status_heartbeat_task.take() { + handle.abort(); + if let Err(err) = handle.await { + if !err.is_cancelled() { + log::warn!("Runtime status heartbeat task ended unexpectedly: {}", err); + } + } + } update_stopped_status(runtime_status_service.as_ref()).await; log::info!("Taurus shutdown complete"); @@ -95,11 +102,12 @@ fn spawn_health_task(config: &Config) -> Option> { async fn setup_dynamic_services_if_needed( config: &Config, ) -> ( - Option, + Option>, Option, + Option>, ) { if config.mode != DYNAMIC { - return (None, None); + return (None, None, None); } push_definitions_until_success(config).await; @@ -109,15 +117,14 @@ async fn setup_dynamic_services_if_needed( .await, ); - let runtime_status_service = Some( + let runtime_status_service = Some(Arc::new( TaurusRuntimeStatusService::from_url( config.aquila_url.clone(), config.aquila_token.clone(), "taurus".into(), - runtime_features(), ) .await, - ); + )); if let Some(status_service) = runtime_status_service.as_ref() { status_service @@ -125,7 +132,45 @@ async fn setup_dynamic_services_if_needed( .await; } - (runtime_status_service, runtime_usage_service) + let runtime_status_heartbeat_task = if config.runtime_status_update_interval_seconds > 0 { + let status_service = runtime_status_service + .as_ref() + .expect("runtime status service should exist in dynamic mode") + .clone(); + let update_interval_seconds = config.runtime_status_update_interval_seconds; + + let handle = tokio::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_secs(update_interval_seconds)); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); + + // First tick is immediate; consume it so heartbeats start after the interval. + interval.tick().await; + + loop { + interval.tick().await; + status_service + .update_runtime_status( + tucana::shared::execution_runtime_status::Status::Running, + ) + .await; + } + }); + + log::info!( + "Runtime status heartbeat started (interval={}s)", + update_interval_seconds + ); + Some(handle) + } else { + log::info!("Runtime status heartbeat is disabled"); + None + }; + + ( + runtime_status_service, + runtime_usage_service, + runtime_status_heartbeat_task, + ) } async fn push_definitions_until_success(config: &Config) { @@ -152,20 +197,7 @@ async fn push_definitions_until_success(config: &Config) { } } -fn runtime_features() -> Vec { - vec![RuntimeFeature { - name: vec![Translation { - code: "en-US".to_string(), - content: "Runtime".to_string(), - }], - description: vec![Translation { - code: "en-US".to_string(), - content: "Will execute incoming flows.".to_string(), - }], - }] -} - -async fn update_stopped_status(runtime_status_service: Option<&TaurusRuntimeStatusService>) { +async fn update_stopped_status(runtime_status_service: Option<&Arc>) { if let Some(status_service) = runtime_status_service { status_service .update_runtime_status(tucana::shared::execution_runtime_status::Status::Stopped) diff --git a/crates/taurus/src/client/runtime_status.rs b/crates/taurus/src/client/runtime_status.rs index 12a64dc..f2f21bb 100644 --- a/crates/taurus/src/client/runtime_status.rs +++ b/crates/taurus/src/client/runtime_status.rs @@ -9,37 +9,25 @@ use tucana::{ RuntimeStatusUpdateRequest, runtime_status_service_client::RuntimeStatusServiceClient, runtime_status_update_request::Status, }, - shared::{ExecutionRuntimeStatus, RuntimeFeature}, + shared::ExecutionRuntimeStatus, }; pub struct TaurusRuntimeStatusService { channel: Channel, identifier: String, - features: Vec, aquila_token: String, } impl TaurusRuntimeStatusService { - pub async fn from_url( - aquila_url: String, - aquila_token: String, - identifier: String, - features: Vec, - ) -> Self { + pub async fn from_url(aquila_url: String, aquila_token: String, identifier: String) -> Self { let channel = create_channel_with_retry("Aquila", aquila_url).await; - Self::new(channel, aquila_token, identifier, features) + Self::new(channel, aquila_token, identifier) } - pub fn new( - channel: Channel, - aquila_token: String, - identifier: String, - features: Vec, - ) -> Self { + pub fn new(channel: Channel, aquila_token: String, identifier: String) -> Self { TaurusRuntimeStatusService { channel, identifier, - features, aquila_token, } } @@ -68,7 +56,6 @@ impl TaurusRuntimeStatusService { status: status.into(), timestamp: timestamp as i64, identifier: self.identifier.clone(), - features: self.features.clone(), })), }, ); diff --git a/crates/taurus/src/config/mod.rs b/crates/taurus/src/config/mod.rs index dfc2a39..d0e83a7 100644 --- a/crates/taurus/src/config/mod.rs +++ b/crates/taurus/src/config/mod.rs @@ -1,15 +1,18 @@ use code0_flow::flow_config::env_with_default; +use code0_flow::flow_config::environment::Environment; use code0_flow::flow_config::mode::Mode; /// Struct for all relevant `Taurus` startup configurations pub struct Config { - /// Aquila mode + pub environment: Environment, + /// Taurus mode /// /// Options: /// `static` (default) - /// `hybrid` + /// `dynamic` pub mode: Mode, + /// URL to the NATS service pub nats_url: String, pub aquila_url: String, @@ -23,15 +26,20 @@ pub struct Config { pub grpc_port: u16, pub definitions: String, + + /// Runtime status heartbeat interval in seconds while Taurus is running. + /// Set to 0 to disable periodic heartbeat updates. + pub runtime_status_update_interval_seconds: u64, } -/// Implementation for all relevant `Aquila` startup configurations +/// Implementation for all relevant `Taurus` startup configurations /// /// Behavior: /// Searches for the env. file at root level. Filename: `.env` impl Config { pub fn new() -> Self { Config { + environment: env_with_default("ENVIRONMENT", Environment::Development), mode: env_with_default("MODE", Mode::DYNAMIC), nats_url: env_with_default("NATS_URL", String::from("nats://localhost:4222")), aquila_url: env_with_default("AQUILA_URL", String::from("http://localhost:50051")), @@ -40,6 +48,10 @@ impl Config { grpc_host: env_with_default("GRPC_HOST", "127.0.0.1".to_string()), grpc_port: env_with_default("GRPC_PORT", 50051), definitions: env_with_default("DEFINITIONS", String::from("./definitions")), + runtime_status_update_interval_seconds: env_with_default( + "RUNTIME_STATUS_UPDATE_INTERVAL_SECONDS", + 30_u64, + ), } } } diff --git a/docs/dev.md b/docs/dev.md new file mode 100644 index 0000000..9290963 --- /dev/null +++ b/docs/dev.md @@ -0,0 +1,165 @@ +--- +title: Taurus Development Guide +--- + +This guide is for contributors working on Taurus itself. +It documents how Taurus is structured, how execution flows through the runtime, and how to run and test changes locally. + +## What Taurus Does + +Taurus is the execution runtime in the CodeZero execution block. + +- Consumes flow execution requests from NATS (`execution.*`) +- Executes flow graphs via `taurus-core::runtime::engine::ExecutionEngine` +- Emits lifecycle events to NATS (`runtime.emitter.`) +- Delegates remote nodes to external services over NATS (`action..`) +- Reports runtime status and usage to Aquila in dynamic mode + +## Workspace Layout + +| Path | Purpose | +| --- | --- | +| `crates/taurus` | Main runtime binary (startup, config, NATS worker, dynamic integrations) | +| `crates/taurus-core` | Execution engine, compiler, runtime functions, errors, tracing | +| `crates/taurus-provider` | Transport adapters (NATS emitter + NATS remote runtime) | +| `crates/taurus-manual` | Manual CLI executor for running a single validation flow file | +| `crates/taurus-tests` | Local execution-suite runner for JSON flow fixtures under `flows/` | +| `flows/` | Example/validation flow cases used by `taurus-tests` | + +## Runtime Flow + +```mermaid +graph TD + NATS[NATS] + Taurus[Taurus Runtime + crates/taurus] + Core[ExecutionEngine + crates/taurus-core] + Emitter[Runtime Emitter + crates/taurus-provider] + Remote[Remote Runtime Adapter + crates/taurus-provider] + Service[Remote Service / Action Runtime] + Aquila[Aquila gRPC APIs + dynamic mode only] + + NATS -->|execution.*| Taurus + Taurus --> Core + Core --> Emitter + Emitter -->|runtime.emitter.| NATS + Core --> Remote + Remote -->|action..| NATS + NATS --> Service + Taurus -->|runtime status + usage| Aquila +``` + +### Execution details + +1. Taurus subscribes to queue subject `execution.*` with queue group `taurus`. +2. Incoming payload is decoded as `tucana::shared::ExecutionFlow`. +3. `ExecutionEngine::execute_flow_with_execution_id(...)` compiles and executes nodes. +4. Local nodes run handlers from the built-in function registry. +5. Non-local `definition_source` values are executed remotely via `RemoteRuntime`. +6. Lifecycle events are emitted as `starting`, `ongoing`, `finished`, or `failed`. + +## Runtime Modes + +Taurus mode is controlled by `MODE`. + +### `dynamic` + +`dynamic` enables control-plane integrations: + +- Sends definitions to Aquila (retry loop until success) +- Starts runtime status reporting (including heartbeat) +- Sends runtime usage updates after each flow run + +### `static` + +`static` disables those control-plane interactions. + +- Taurus still executes flows from NATS +- No definition push +- No runtime status updates +- No runtime usage updates + +## Environment Variables + +Defaults are defined in `crates/taurus/src/config/mod.rs`. + +| Name | Description | Default | +| --- | --- | --- | +| `ENVIRONMENT` | Running env | `development` | +| `MODE` | Runtime mode (`dynamic` or `static`) | `dynamic` | +| `NATS_URL` | NATS connection URL | `nats://localhost:4222` | +| `AQUILA_URL` | Aquila gRPC endpoint (used in dynamic mode) | `http://localhost:50051` | +| `AQUILA_TOKEN` | Auth token for Aquila runtime APIs | `token` | +| `WITH_HEALTH_SERVICE` | Enables gRPC health server | `false` | +| `GRPC_HOST` | Health server host | `127.0.0.1` | +| `GRPC_PORT` | Health server port | `50051` | +| `DEFINITIONS` | Path sent to `FlowUpdateService` for definition sync | `./definitions` | +| `RUNTIME_STATUS_UPDATE_INTERVAL_SECONDS` | Heartbeat interval in dynamic mode (`0` disables heartbeat) | `30` | + +## Local Development + +### 1. Start dependencies + +At minimum, start a reachable NATS instance at `NATS_URL`. + +### 2. Configure environment + +Create `.env` in the repository root (you can copy from `.env-example` and extend it). + +### 3. Run Taurus + +```bash +cargo run -p taurus +``` + +### 4. Run the execution suite + +```bash +cargo run -p tests +``` + +This executes all JSON files in `./flows` and compares runtime outputs. + +### 5. Run one flow manually + +```bash +cargo run -p manual -- --path ./flows/01_return_object.json --index 0 --nats-url nats://127.0.0.1:4222 +``` + +This is useful when debugging one case or remote-execution behavior. + +## Testing + +- Core unit/integration tests: + +```bash +cargo test -p taurus-core +``` + +- Full workspace checks (recommended before merge): + +```bash +cargo test +``` + +## Extending Taurus + +### Add or modify built-in functions + +- Implement handler logic in `crates/taurus-core/src/runtime/functions/*` +- Register function IDs via the `FUNCTIONS` arrays +- Registration is aggregated through `ALL_FUNCTION_SETS` in `runtime/functions/mod.rs` + +### Remote execution routing rule + +In the compiler, a node is treated as local when `definition_source` is: + +- empty +- `taurus` +- prefixed with `draco` + +Any other source is routed as remote execution to that service name. diff --git a/crates/taurus-core/src/ERROR_CODES.md b/docs/errors.md similarity index 94% rename from crates/taurus-core/src/ERROR_CODES.md rename to docs/errors.md index 0a3550b..6355d41 100644 --- a/crates/taurus-core/src/ERROR_CODES.md +++ b/docs/errors.md @@ -1,11 +1,15 @@ -# Taurus Runtime Error Codes +--- +title: Taurus Error Table +--- + +## Taurus Runtime Error Codes This document is the canonical catalog for runtime error codes emitted by Taurus runtime crates (`taurus-core` and `taurus-provider`). ## Code Format - `T-STD-XXXXX`: Errors originating inside standard function implementations under `runtime/functions/*`. -- `T-CORE-XXXXXX`: Errors originating from core runtime infrastructure (`engine`, `handler`, type conversion, app-layer mapping). +- `T-CORE-XXXXXX`: Errors originating from core runtime infrastructure. - `T-PROV-XXXXXX`: Errors originating from provider integrations (transport adapters, remote runtime connectors). ## Code Table @@ -37,4 +41,6 @@ This document is the canonical catalog for runtime error codes emitted by Taurus ## Provider Note -`taurus-provider` can also forward remote service errors with service-owned codes (for example codes returned inside Aquila `ExecutionResult::Error`). Those are intentionally preserved instead of remapped, so they are not enumerated as static Taurus provider codes here. +`taurus-provider` can also forward remote service errors with service-owned codes (for example +codes returned inside Aquila `ExecutionResult::Error`). Those are intentionally preserved instead of remapped, +so they are not enumerated as static Taurus provider codes here. diff --git a/docs/index.mdx b/docs/index.mdx index 4b1e4c9..569fd17 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -1,7 +1,18 @@ --- -title: Welcome to the Documentation for Taurus -description: Find out how the execution works +title: Welcome to Taurus Documentation +description: Learn how Taurus works and how to build with it template: splash --- -Taurus executes Flows. +## What is Taurus? + +Taurus runs inside the execution block and serves as the runtime itself. +It handles flow execution requests and requests single node executions from Actions. + +--- + +If you want to work on or with Taurus, start here: + +- **[Setup Guide](installation.mdx)**: install and configure Taurus for local or containerized use, with Aquila required for dynamic mode. +- **[Development Guide](dev.md)**: runtime architecture. +- **[Error Table](errors.md)**: table of possible runtime errors. diff --git a/docs/installation.mdx b/docs/installation.mdx new file mode 100644 index 0000000..d6d4bef --- /dev/null +++ b/docs/installation.mdx @@ -0,0 +1,103 @@ +--- +title: Taurus Installation Guide +--- + +import {Step, Steps} from 'fumadocs-ui/components/steps'; + +Use this guide to install and configure Taurus. + +## Setup Options + +### Using Docker Compose + +Use Docker Compose to run Taurus and related services. +If you are developing Taurus locally, make sure the Taurus container is stopped to avoid port conflicts. +If your compose setup supports profiles, you can set `COMPOSE_PROFILES=ide` to run only +IDE-related services and start Taurus manually. + +### Virtual Development Environment (Preferred) + +Use the shared environment setup from the main platform docs: + +- [Visit Setup Guide](https://docs.code0.tech/general/install/) + +### Manual Installation + + + + + +#### **Clone Taurus** + +Clone this repository to your local machine. + + + + + +#### **Set up environment variables** + +Configure `.env` in the project root with the required settings. +You can use `.env-example` as a starting point. + + + + + +#### **Ensure required services are running** + +**NATS**: + +- Ensure a NATS instance is reachable +- Enable JetStream +- See [NATS installation docs](https://docs.nats.io/running-a-nats-service/introduction/installation) + +**Aquila**: + +- Required for dynamic mode (`MODE=dynamic`) +- Ensure the configured endpoint is reachable + + + + + +#### **Start Taurus** + +Run: + +```bash +cargo run -p taurus +``` + + + + +--- + +## Environment Variables + +Taurus configuration is split into shared variables and mode-specific variables. + +### Common (Static + Dynamic) + +| Name | Description | Default | +|-----------------------|--------------------------------------------------------------------------------------------------------------|---------------------------------| +| `MODE` | Runtime mode. `static` loads local flows. `dynamic` enables dynamic synchronization with Sagittarius. | `static` | +| `ENVIRONMENT` | Runtime environment (`development`, `staging`, `production`). | `development` | +| `NATS_URL` | URL of the NATS instance Taurus connects to. | `nats://localhost:4222` | +| `AQUILA_URL` | URL of the Aquila instance . | `nats://localhost:4222` | +| `AQUILA_TOKEN` | Token to authenticate agains Aquila. | `nats://localhost:4222` | +| `GRPC_HOST` | Hostname for the Taurus gRPC server. | `127.0.0.1` | +| `GRPC_PORT` | Port for the Taurus gRPC server. | `50051` | +| `WITH_HEALTH_SERVICE` | Enables the gRPC health service when set to `true`. | `false` | + +### Dynamic Mode + +Set `MODE=dynamic` when the IDE is required/needed. + +| Name | Description | Default | +|-------------------|-----------------------------------------------------------------------------------|--------------------------| +| `AQUILA_URL` | URL of the Aquila instance. | `http://localhost:50051` | +| `AQUILA_TOKEN` | Token used by Taurus to authenticate with Aquila. | `token` | +| `DEFINITIONS` | Path to the runtime definition modules. | `./definitions` | +| `RUNTIME_STATUS_UPDATE_INTERVAL_SECONDS` | Interval (in seconds) of updating the current runtime status. | `30s` |