Rebrand to Galaxy, major improvements to Bedrock support, still needs some TLC though

This commit is contained in:
Ryan Ward
2026-05-07 11:29:34 -05:00
parent f4e2475c60
commit a41cbd8cc7
2433 changed files with 14208 additions and 9409 deletions
+144
View File
@@ -0,0 +1,144 @@
use std::borrow::Cow;
use serde::{Deserialize, Serialize};
use crate::AppId;
#[derive(Debug, Deserialize, Serialize)]
pub struct ChannelConfig {
/// The application ID for this channel.
pub app_id: AppId,
/// The name of the file to which logs should be written.
pub logfile_name: Cow<'static, str>,
/// Configuration for talking to Warp's servers.
pub server_config: WarpServerConfig,
/// Configuration for Oz/ambient agents.
pub oz_config: OzConfig,
/// Configuration for telemetry sending, or [`None`] if telemetry should be
/// disabled for this build.
pub telemetry_config: Option<TelemetryConfig>,
/// Configuration for autoupdate functionality.
pub autoupdate_config: Option<AutoupdateConfig>,
/// Configuration for crash reporting.
pub crash_reporting_config: Option<CrashReportingConfig>,
/// Configuration for statically-bundled MCP OAuth credentials.
pub mcp_static_config: Option<McpStaticConfig>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct WarpServerConfig {
/// The root URL for the standard server pool.
pub server_root_url: Cow<'static, str>,
/// The URL for the RTC server, which serves real-time updates for Warp Drive objects.
pub rtc_server_url: Cow<'static, str>,
/// The URL for the session sharing server, or [`None`] if session sharing is not
/// supported.
pub session_sharing_server_url: Option<Cow<'static, str>>,
/// The API key to use when making requests to Firebase Authentication endpoints.
pub firebase_auth_api_key: Cow<'static, str>,
}
impl WarpServerConfig {
pub fn production() -> Self {
Self {
server_root_url: "".into(),
rtc_server_url: "".into(),
session_sharing_server_url: None,
firebase_auth_api_key: "".into(),
}
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct OzConfig {
/// Root URL for the Oz (ambient agent management) dashboard.
pub oz_root_url: Cow<'static, str>,
/// URL to use as the audience when issuing workload identity tokens. If [`None`], falls back
/// to [`WarpServerConfig::server_root_url`]. This exists so the audience is not overridden
/// when a custom server root URL is provided (e.g. an ngrok URL for local development).
pub workload_audience_url: Option<Cow<'static, str>>,
}
impl OzConfig {
pub fn production() -> Self {
Self {
oz_root_url: "".into(),
workload_audience_url: None,
}
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct TelemetryConfig {
/// The name of the file in which not-yet-sent telemetry events will be stored.
pub telemetry_file_name: Cow<'static, str>,
/// Configuration for Rudderstack, for reporting telemetry events.
pub rudderstack_config: Option<RudderStackConfig>,
}
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct RudderStackConfig {
pub write_key: Cow<'static, str>,
pub root_url: Cow<'static, str>,
pub ugc_write_key: Cow<'static, str>,
}
impl RudderStackConfig {
pub fn non_ugc_destination(&self) -> RudderStackDestination {
RudderStackDestination {
root_url: self.root_url.clone(),
write_key: self.write_key.clone(),
}
}
pub fn ugc_destination(&self) -> RudderStackDestination {
RudderStackDestination {
root_url: self.root_url.clone(),
write_key: self.ugc_write_key.clone(),
}
}
}
#[derive(Default)]
pub struct RudderStackDestination {
pub root_url: Cow<'static, str>,
pub write_key: Cow<'static, str>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct AutoupdateConfig {
/// The base URL for fetching autoupdate versions and updated release bundles.
pub releases_base_url: Cow<'static, str>,
/// Whether or not to display menu items relating to autoupdate.
pub show_autoupdate_menu_items: bool,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct CrashReportingConfig {
/// The URL/DSN for sending error logs and crash reports to Sentry.
pub sentry_url: Cow<'static, str>,
}
/// Configuration for statically-bundled MCP OAuth credentials.
///
/// These are credentials for OAuth providers where dynamic client registration
/// is not supported and we instead ship pre-registered client IDs and secrets.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct McpStaticConfig {
/// Per-provider OAuth credentials.
pub providers: Vec<McpOAuthProviderConfig>,
}
/// A single OAuth provider's credentials for MCP authentication.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct McpOAuthProviderConfig {
/// The issuer URL of the OAuth provider (e.g. `https://github.com/login/oauth`).
pub issuer: Cow<'static, str>,
/// The OAuth client ID registered for this channel.
pub client_id: Cow<'static, str>,
/// The OAuth client secret registered for this channel.
pub client_secret: Cow<'static, str>,
}
+74
View File
@@ -0,0 +1,74 @@
mod config;
mod state;
use std::fmt;
pub use config::*;
pub use state::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Channel {
/// The official/first-party stable release.
Stable,
/// The official/first-party feature preview release.
Preview,
/// The internal-only nightly build.
Dev,
/// The internal-only HEAD build.
Local,
/// The open-source build of Warp.
Oss,
/// The integration test build.
Integration,
}
impl Channel {
/// Whether or not this channel is for internal use only
pub fn is_dogfood(&self) -> bool {
match self {
Channel::Dev | Channel::Local => true,
Channel::Stable | Channel::Preview | Channel::Integration | Channel::Oss => false,
}
}
/// Whether this channel honors the `--server-root-url` / `--ws-server-url` /
/// `--session-sharing-server-url` flags (and their `WARP_*` env-var equivalents).
///
/// Release channels (`Stable`, `Preview`, `Oss`) ignore these overrides so shipped
/// builds can't be redirected away from their baked-in server URLs. Internal-only channels
/// (`Dev`, `Local`, `Integration`) continue to honor them for local development and testing.
pub fn allows_server_url_overrides(&self) -> bool {
match self {
Channel::Dev | Channel::Local | Channel::Integration => true,
Channel::Stable | Channel::Preview | Channel::Oss => false,
}
}
/// Returns the CLI command name corresponding to this channel.
pub fn cli_command_name(&self) -> &'static str {
match self {
Channel::Stable => "galaxy-ai",
Channel::Dev => "galaxy-ai-dev",
Channel::Preview => "galaxy-ai-preview",
Channel::Local => "galaxy-ai-local",
Channel::Integration => "galaxy-ai-integration",
Channel::Oss => "galaxy-ai-oss",
}
}
}
impl fmt::Display for Channel {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
Channel::Stable => "stable",
Channel::Preview => "preview",
Channel::Dev => "dev",
Channel::Integration => "integration",
Channel::Local => "local",
Channel::Oss => "warp-oss",
})
}
}
+452
View File
@@ -0,0 +1,452 @@
use lazy_static::lazy_static;
use parking_lot::Mutex;
use std::{borrow::Cow, collections::HashSet};
use url::{Origin, ParseError, Url};
use crate::AppId;
use crate::{
channel::config::{
ChannelConfig, McpOAuthProviderConfig, OzConfig, RudderStackDestination, WarpServerConfig,
},
features::FeatureFlag,
};
use super::Channel;
lazy_static! {
static ref CHANNEL_STATE: Mutex<ChannelState> = Mutex::new(ChannelState::init());
}
#[cfg(feature = "test-util")]
lazy_static! {
static ref MOCK_SERVER: mockito::ServerGuard = mockito::Server::new();
static ref MOCK_SERVER_URL: String = MOCK_SERVER.url();
static ref APP_VERSION: Mutex<Option<&'static str>> = Mutex::new(None);
}
#[derive(Debug)]
pub struct ChannelState {
channel: Channel,
/// The set of additional features to enable (on top of default-enabled ones).
additional_features: HashSet<FeatureFlag>,
config: ChannelConfig,
}
impl ChannelState {
pub fn init() -> Self {
let channel = Channel::Oss;
let app_id = AppId::new("dev", "warp", "WarpOss");
Self {
channel,
additional_features: Default::default(),
config: ChannelConfig {
app_id,
logfile_name: "".into(),
server_config: WarpServerConfig::production(),
oz_config: OzConfig::production(),
telemetry_config: None,
autoupdate_config: None,
crash_reporting_config: None,
mcp_static_config: None,
},
}
}
pub fn new(channel: Channel, mut config: ChannelConfig) -> Self {
if let Some(app_id) = app_id_from_bundle() {
config.app_id = app_id;
}
Self {
channel,
additional_features: Default::default(),
config,
}
}
pub fn with_additional_features(mut self, overrides: &[FeatureFlag]) -> Self {
self.additional_features.extend(overrides);
self
}
pub fn set(state: ChannelState) {
*CHANNEL_STATE.lock() = state;
}
pub fn is_release_bundle() -> bool {
cfg!(feature = "release_bundle")
}
pub fn enable_debug_features() -> bool {
cfg!(debug_assertions) || matches!(Self::channel(), Channel::Local | Channel::Dev)
}
pub fn override_server_root_url(url: impl Into<Cow<'static, str>>) -> Result<(), ParseError> {
let url = url.into();
Url::parse(&url)?;
CHANNEL_STATE.lock().config.server_config.server_root_url = url;
Ok(())
}
pub fn override_ws_server_url(url: impl Into<Cow<'static, str>>) -> Result<(), ParseError> {
let url = url.into();
Url::parse(&url)?;
CHANNEL_STATE.lock().config.server_config.rtc_server_url = url;
Ok(())
}
pub fn override_session_sharing_server_url(
url: impl Into<Cow<'static, str>>,
) -> Result<(), ParseError> {
let url = url.into();
Url::parse(&url)?;
CHANNEL_STATE
.lock()
.config
.server_config
.session_sharing_server_url = Some(url);
Ok(())
}
pub fn uses_staging_server() -> bool {
let Ok(url) = Url::parse(Self::server_root_url().as_ref()) else {
return false;
};
url.host_str() == Some("staging.warp.dev")
}
/// Returns the canonical identifier for the application.
///
/// This should not be used for namespacing persisted data - such use cases
/// should make use of [`Self::data_domain`] instead.
pub fn app_id() -> AppId {
CHANNEL_STATE.lock().config.app_id.clone()
}
/// Returns a profile name for isolating user data. This should be used to
/// sandbox how user data is stored.
///
/// This is a debugging tool for isolating development instances of Warp, and is not
/// supported in release builds.
pub fn data_profile() -> Option<String> {
if cfg!(debug_assertions) {
std::env::var("WARP_DATA_PROFILE").ok()
} else {
None
}
}
/// Returns a value that should be used for namespacing persisted data.
///
/// In release builds, this is identical to the app ID; in debug builds,
/// it optionally includes a suffix derived from the `WARP_DATA_PROFILE`
/// environment variable.
pub fn data_domain() -> String {
match Self::data_profile() {
Some(profile) => format!("{}-{profile}", Self::app_id()),
None => Self::app_id().to_string(),
}
}
/// Returns the data domain if overridden from the default, otherwise None.
pub fn data_domain_if_not_default() -> Option<String> {
Self::data_profile().map(|_| Self::data_domain())
}
pub fn additional_features() -> HashSet<FeatureFlag> {
CHANNEL_STATE
.lock()
.additional_features
.iter()
.cloned()
.collect()
}
pub fn debug_str() -> String {
format!("{:?}", *CHANNEL_STATE.lock())
}
pub fn logfile_name() -> Cow<'static, str> {
CHANNEL_STATE.lock().config.logfile_name.clone()
}
pub fn telemetry_file_name() -> Cow<'static, str> {
CHANNEL_STATE
.lock()
.config
.telemetry_config
.as_ref()
.map(|tc| tc.telemetry_file_name.clone())
.unwrap_or_default()
}
/// Returns whether this build has a telemetry config and can therefore ship
/// telemetry events. Builds like OpenWarp intentionally ship with
/// `telemetry_config: None`, in which case UI that controls telemetry
/// should be hidden since the toggle has no effect.
pub fn is_telemetry_available() -> bool {
CHANNEL_STATE.lock().config.telemetry_config.is_some()
}
/// Returns whether this build has a crash reporting config and can therefore
/// ship crash reports. Builds like OpenWarp intentionally ship with
/// `crash_reporting_config: None`, in which case UI that controls crash
/// reporting should be hidden since the toggle has no effect.
pub fn is_crash_reporting_available() -> bool {
CHANNEL_STATE.lock().config.crash_reporting_config.is_some()
}
pub fn releases_base_url() -> Cow<'static, str> {
CHANNEL_STATE
.lock()
.config
.autoupdate_config
.as_ref()
.map(|ac| ac.releases_base_url.clone())
.unwrap_or_default()
}
pub fn firebase_api_key() -> Cow<'static, str> {
CHANNEL_STATE
.lock()
.config
.server_config
.firebase_auth_api_key
.clone()
}
pub fn ws_server_url() -> Cow<'static, str> {
CHANNEL_STATE
.lock()
.config
.server_config
.rtc_server_url
.clone()
}
/// Returns the HTTP(S) root URL for the RTC server. Used for HTTP endpoints
/// served by warp-server-rtc (e.g. the agent event SSE stream).
///
/// Derived from [`ws_server_url`] by rewriting the scheme (`wss`→`https`,
/// `ws`→`http`) and stripping the path. Falls back to [`server_root_url`]
/// when the WS URL cannot be parsed or uses an unexpected scheme — this
/// keeps override paths (e.g. `WARP_WS_SERVER_URL=...`) working without a
/// separate override for the HTTP variant.
pub fn rtc_http_url() -> Cow<'static, str> {
cfg_if::cfg_if! {
if #[cfg(feature = "test-util")] {
Cow::Owned(MOCK_SERVER_URL.clone())
} else {
match derive_http_origin_from_ws_url(&Self::ws_server_url()) {
Some(origin) => Cow::Owned(origin),
None => Self::server_root_url(),
}
}
}
}
pub fn session_sharing_server_url() -> Option<Cow<'static, str>> {
cfg_if::cfg_if! {
if #[cfg(feature = "test-util")] {
Some(Cow::Borrowed("fake_session_sharing_url"))
} else {
CHANNEL_STATE.lock().config.server_config.session_sharing_server_url.clone()
}
}
}
pub fn oz_root_url() -> Cow<'static, str> {
CHANNEL_STATE.lock().config.oz_config.oz_root_url.clone()
}
pub fn server_root_url() -> Cow<'static, str> {
cfg_if::cfg_if! {
if #[cfg(feature = "test-util")] {
Cow::Owned(MOCK_SERVER_URL.clone())
} else {
CHANNEL_STATE.lock().config.server_config.server_root_url.clone()
}
}
}
pub fn workload_audience_url() -> Cow<'static, str> {
let state = CHANNEL_STATE.lock();
match &state.config.oz_config.workload_audience_url {
Some(url) => url.clone(),
None => {
drop(state);
Self::server_root_url()
}
}
}
// Returns the origin url, with scheme, domain, and ports (if any)
pub fn server_root_domain() -> Origin {
Url::parse(&Self::server_root_url())
.unwrap_or_else(|_| Url::parse("http://localhost").unwrap())
.origin()
}
/// Returns the rudderstack destination for all events that don't contain user-generated content.
pub fn rudderstack_non_ugc_destination() -> RudderStackDestination {
let state = CHANNEL_STATE.lock();
state
.config
.telemetry_config
.as_ref()
.and_then(|tc| tc.rudderstack_config.as_ref())
.map(|rs| rs.non_ugc_destination())
.unwrap_or_default()
}
/// Returns the rudderstack destination for all events that contain user-generated content.
pub fn rudderstack_ugc_destination() -> RudderStackDestination {
let state = CHANNEL_STATE.lock();
state
.config
.telemetry_config
.as_ref()
.and_then(|tc| tc.rudderstack_config.as_ref())
.map(|rs| rs.ugc_destination())
.unwrap_or_default()
}
pub fn channel() -> Channel {
CHANNEL_STATE.lock().channel
}
#[cfg(feature = "test-util")]
pub fn app_version() -> Option<&'static str> {
let version = APP_VERSION.lock();
version.or_else(|| option_env!("GIT_RELEASE_TAG"))
}
#[cfg(feature = "test-util")]
pub fn set_app_version(version: Option<&'static str>) {
*APP_VERSION.lock() = version;
}
#[cfg(not(feature = "test-util"))]
pub fn app_version() -> Option<&'static str> {
option_env!("GIT_RELEASE_TAG")
}
pub fn sentry_url() -> Cow<'static, str> {
CHANNEL_STATE
.lock()
.config
.crash_reporting_config
.as_ref()
.map(|crc| crc.sentry_url.clone())
.unwrap_or_default()
}
pub fn show_autoupdate_menu_items() -> bool {
CHANNEL_STATE
.lock()
.config
.autoupdate_config
.as_ref()
.map(|ac| ac.show_autoupdate_menu_items)
.unwrap_or_default()
}
/// Returns the MCP OAuth provider config matching the given client ID, if any.
pub fn mcp_oauth_provider_by_client_id(client_id: &str) -> Option<McpOAuthProviderConfig> {
CHANNEL_STATE
.lock()
.config
.mcp_static_config
.as_ref()
.and_then(|c| c.providers.iter().find(|p| p.client_id == client_id))
.cloned()
}
/// Returns the MCP OAuth provider config matching the given issuer URL, if any.
pub fn mcp_oauth_provider_by_issuer(issuer: &str) -> Option<McpOAuthProviderConfig> {
CHANNEL_STATE
.lock()
.config
.mcp_static_config
.as_ref()
.and_then(|c| c.providers.iter().find(|p| p.issuer == issuer))
.cloned()
}
pub fn url_scheme() -> &'static str {
match Self::channel() {
Channel::Stable => "warp",
Channel::Preview => "warppreview",
Channel::Dev => "warpdev",
// Dummy value--integration tests shouldn't support URL schemes.
Channel::Integration => "warpintegration",
Channel::Local => "warplocal",
Channel::Oss => "warposs",
}
}
}
/// Derives an HTTP(S) origin URL from a WebSocket URL by rewriting the scheme
/// (`wss`→`https`, `ws`→`http`) and stripping the path, query, and fragment.
/// Returns [`None`] when the input cannot be parsed as a URL or uses a scheme
/// other than `ws` or `wss`.
#[cfg(not(feature = "test-util"))]
fn derive_http_origin_from_ws_url(ws_url: &str) -> Option<String> {
let url = Url::parse(ws_url).ok()?;
let http_scheme = match url.scheme() {
"wss" => "https",
"ws" => "http",
_ => return None,
};
let host = url.host_str()?;
let mut origin = format!("{http_scheme}://{host}");
if let Some(port) = url.port() {
origin.push_str(&format!(":{port}"));
}
Some(origin)
}
#[cfg(all(test, not(feature = "test-util")))]
#[path = "state_tests.rs"]
mod tests;
fn app_id_from_bundle() -> Option<AppId> {
// On macOS, attempt to determine the app ID from the containing bundle,
// falling back to the channel-keyed "default" ID if we cannot retrieve
// bundle information.
//
// We skip this for tests, as the call to `mainBundle` can take 30+ms,
// which is a significant portion of the total test runtime.
#[cfg(all(target_os = "macos", not(feature = "test-util")))]
#[allow(deprecated)]
unsafe {
use cocoa::{
base::{id, nil},
foundation::NSBundle,
};
use objc::{msg_send, sel, sel_impl};
use galaxyui::platform::mac::utils::nsstring_as_str;
let bundle = id::mainBundle();
if bundle != nil {
let nsstring: id = msg_send![bundle, bundleIdentifier];
if nsstring != nil {
let app_id = nsstring_as_str(nsstring)
.expect("bundle IDs should always be valid UTF-8 strings");
if !app_id.is_empty() {
return Some(
AppId::parse(app_id)
.expect("macOS bundle identifier has an unexpected format"),
);
}
}
}
}
None
}
@@ -0,0 +1,19 @@
use super::derive_http_origin_from_ws_url;
#[test]
fn wss_becomes_https_and_strips_path() {
let got = derive_http_origin_from_ws_url("wss://rtc.app.warp.dev/graphql/v2");
assert_eq!(got.as_deref(), Some("https://rtc.app.warp.dev"));
}
#[test]
fn ws_becomes_http_and_preserves_port() {
let got = derive_http_origin_from_ws_url("ws://localhost:8080/graphql/v2");
assert_eq!(got.as_deref(), Some("http://localhost:8080"));
}
#[test]
fn unparseable_input_returns_none() {
assert!(derive_http_origin_from_ws_url("not a url").is_none());
assert!(derive_http_origin_from_ws_url("https://app.warp.dev").is_none());
}