mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
refactor(omo): deduplicate OMO/OMO Slim via OmoVariant parameterization
Introduce OmoVariant struct with STANDARD/SLIM constants to eliminate ~250 lines of copy-pasted code across DAO, service, commands, and frontend layers. Adding a new OMO variant now requires only a single const declaration instead of duplicating ~400 lines.
This commit is contained in:
@@ -238,22 +238,28 @@ pub async fn set_common_config_snippet(
|
||||
if app_type == "omo"
|
||||
&& state
|
||||
.db
|
||||
.get_current_omo_provider("opencode")
|
||||
.get_current_omo_provider("opencode", "omo")
|
||||
.map_err(|e| e.to_string())?
|
||||
.is_some()
|
||||
{
|
||||
crate::services::OmoService::write_config_to_file(state.inner())
|
||||
.map_err(|e| e.to_string())?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state.inner(),
|
||||
&crate::services::omo::STANDARD,
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
}
|
||||
if app_type == "omo-slim"
|
||||
&& state
|
||||
.db
|
||||
.get_current_omo_slim_provider("opencode")
|
||||
.get_current_omo_provider("opencode", "omo-slim")
|
||||
.map_err(|e| e.to_string())?
|
||||
.is_some()
|
||||
{
|
||||
crate::services::OmoService::write_config_to_file_slim(state.inner())
|
||||
.map_err(|e| e.to_string())?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state.inner(),
|
||||
&crate::services::omo::SLIM,
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
use tauri::State;
|
||||
|
||||
use crate::services::omo::OmoLocalFileData;
|
||||
use crate::services::omo::{OmoLocalFileData, SLIM, STANDARD};
|
||||
use crate::services::OmoService;
|
||||
use crate::store::AppState;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn read_omo_local_file() -> Result<OmoLocalFileData, String> {
|
||||
OmoService::read_local_file().map_err(|e| e.to_string())
|
||||
OmoService::read_local_file(&STANDARD).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_current_omo_provider_id(state: State<'_, AppState>) -> Result<String, String> {
|
||||
let provider = state
|
||||
.db
|
||||
.get_current_omo_provider("opencode")
|
||||
.get_current_omo_provider("opencode", "omo")
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(provider.map(|p| p.id).unwrap_or_default())
|
||||
}
|
||||
@@ -28,11 +28,11 @@ pub async fn disable_current_omo(state: State<'_, AppState>) -> Result<(), Strin
|
||||
if p.category.as_deref() == Some("omo") {
|
||||
state
|
||||
.db
|
||||
.clear_omo_provider_current("opencode", id)
|
||||
.clear_omo_provider_current("opencode", id, "omo")
|
||||
.map_err(|e| e.to_string())?;
|
||||
}
|
||||
}
|
||||
OmoService::delete_config_file().map_err(|e| e.to_string())?;
|
||||
OmoService::delete_config_file(&STANDARD).map_err(|e| e.to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ pub async fn get_omo_provider_count(state: State<'_, AppState>) -> Result<usize,
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn read_omo_slim_local_file() -> Result<OmoLocalFileData, String> {
|
||||
OmoService::read_local_file_slim().map_err(|e| e.to_string())
|
||||
OmoService::read_local_file(&SLIM).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -62,7 +62,7 @@ pub async fn get_current_omo_slim_provider_id(
|
||||
) -> Result<String, String> {
|
||||
let provider = state
|
||||
.db
|
||||
.get_current_omo_slim_provider("opencode")
|
||||
.get_current_omo_provider("opencode", "omo-slim")
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(provider.map(|p| p.id).unwrap_or_default())
|
||||
}
|
||||
@@ -77,11 +77,11 @@ pub async fn disable_current_omo_slim(state: State<'_, AppState>) -> Result<(),
|
||||
if p.category.as_deref() == Some("omo-slim") {
|
||||
state
|
||||
.db
|
||||
.clear_omo_slim_provider_current("opencode", id)
|
||||
.clear_omo_provider_current("opencode", id, "omo-slim")
|
||||
.map_err(|e| e.to_string())?;
|
||||
}
|
||||
}
|
||||
OmoService::delete_config_file_slim().map_err(|e| e.to_string())?;
|
||||
OmoService::delete_config_file(&SLIM).map_err(|e| e.to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -55,38 +55,23 @@ impl Default for OmoGlobalConfig {
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn get_omo_global_config(&self) -> Result<OmoGlobalConfig, AppError> {
|
||||
let json_str = self.get_setting("common_config_omo")?;
|
||||
pub fn get_omo_global_config(&self, key: &str) -> Result<OmoGlobalConfig, AppError> {
|
||||
let json_str = self.get_setting(key)?;
|
||||
match json_str {
|
||||
Some(s) => serde_json::from_str::<OmoGlobalConfig>(&s)
|
||||
.map_err(|e| AppError::Config(format!("Failed to parse common_config_omo: {e}"))),
|
||||
.map_err(|e| AppError::Config(format!("Failed to parse {key}: {e}"))),
|
||||
None => Ok(OmoGlobalConfig::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_omo_global_config(&self, config: &OmoGlobalConfig) -> Result<(), AppError> {
|
||||
pub fn save_omo_global_config(
|
||||
&self,
|
||||
key: &str,
|
||||
config: &OmoGlobalConfig,
|
||||
) -> Result<(), AppError> {
|
||||
let json_str = serde_json::to_string(config)
|
||||
.map_err(|e| AppError::Config(format!("JSON serialization failed: {e}")))?;
|
||||
self.set_setting("common_config_omo", &json_str)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ── OMO Slim global config ──────────────────────────────────
|
||||
|
||||
pub fn get_omo_slim_global_config(&self) -> Result<OmoGlobalConfig, AppError> {
|
||||
let json_str = self.get_setting("common_config_omo_slim")?;
|
||||
match json_str {
|
||||
Some(s) => serde_json::from_str::<OmoGlobalConfig>(&s).map_err(|e| {
|
||||
AppError::Config(format!("Failed to parse common_config_omo_slim: {e}"))
|
||||
}),
|
||||
None => Ok(OmoGlobalConfig::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_omo_slim_global_config(&self, config: &OmoGlobalConfig) -> Result<(), AppError> {
|
||||
let json_str = serde_json::to_string(config)
|
||||
.map_err(|e| AppError::Config(format!("JSON serialization failed: {e}")))?;
|
||||
self.set_setting("common_config_omo_slim", &json_str)?;
|
||||
self.set_setting(key, &json_str)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,25 +364,26 @@ impl Database {
|
||||
&self,
|
||||
app_type: &str,
|
||||
provider_id: &str,
|
||||
category: &str,
|
||||
) -> Result<(), AppError> {
|
||||
let mut conn = lock_conn!(self.conn);
|
||||
let tx = conn
|
||||
.transaction()
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
tx.execute(
|
||||
"UPDATE providers SET is_current = 0 WHERE app_type = ?1 AND category = 'omo'",
|
||||
params![app_type],
|
||||
"UPDATE providers SET is_current = 0 WHERE app_type = ?1 AND category = ?2",
|
||||
params![app_type, category],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
let updated = tx
|
||||
.execute(
|
||||
"UPDATE providers SET is_current = 1 WHERE id = ?1 AND app_type = ?2 AND category = 'omo'",
|
||||
params![provider_id, app_type],
|
||||
)
|
||||
"UPDATE providers SET is_current = 1 WHERE id = ?1 AND app_type = ?2 AND category = ?3",
|
||||
params![provider_id, app_type, category],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
if updated != 1 {
|
||||
return Err(AppError::Database(format!(
|
||||
"Failed to set OMO provider current: provider '{provider_id}' not found in app '{app_type}'"
|
||||
"Failed to set {category} provider current: provider '{provider_id}' not found in app '{app_type}'"
|
||||
)));
|
||||
}
|
||||
tx.commit().map_err(|e| AppError::Database(e.to_string()))?;
|
||||
@@ -393,12 +394,13 @@ impl Database {
|
||||
&self,
|
||||
app_type: &str,
|
||||
provider_id: &str,
|
||||
category: &str,
|
||||
) -> Result<bool, AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
match conn.query_row(
|
||||
"SELECT is_current FROM providers
|
||||
WHERE id = ?1 AND app_type = ?2 AND category = 'omo'",
|
||||
params![provider_id, app_type],
|
||||
WHERE id = ?1 AND app_type = ?2 AND category = ?3",
|
||||
params![provider_id, app_type, category],
|
||||
|row| row.get(0),
|
||||
) {
|
||||
Ok(is_current) => Ok(is_current),
|
||||
@@ -411,152 +413,30 @@ impl Database {
|
||||
&self,
|
||||
app_type: &str,
|
||||
provider_id: &str,
|
||||
category: &str,
|
||||
) -> Result<(), AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
conn.execute(
|
||||
"UPDATE providers SET is_current = 0
|
||||
WHERE id = ?1 AND app_type = ?2 AND category = 'omo'",
|
||||
params![provider_id, app_type],
|
||||
WHERE id = ?1 AND app_type = ?2 AND category = ?3",
|
||||
params![provider_id, app_type, category],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_current_omo_provider(&self, app_type: &str) -> Result<Option<Provider>, AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
let row_data: Result<OmoProviderRow, rusqlite::Error> = conn.query_row(
|
||||
"SELECT id, name, settings_config, category, created_at, sort_index, notes, meta
|
||||
FROM providers
|
||||
WHERE app_type = ?1 AND category = 'omo' AND is_current = 1
|
||||
LIMIT 1",
|
||||
params![app_type],
|
||||
|row| {
|
||||
Ok((
|
||||
row.get(0)?,
|
||||
row.get(1)?,
|
||||
row.get(2)?,
|
||||
row.get(3)?,
|
||||
row.get(4)?,
|
||||
row.get(5)?,
|
||||
row.get(6)?,
|
||||
row.get(7)?,
|
||||
))
|
||||
},
|
||||
);
|
||||
|
||||
let (id, name, settings_config_str, category, created_at, sort_index, notes, meta_str) =
|
||||
match row_data {
|
||||
Ok(v) => v,
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => return Ok(None),
|
||||
Err(e) => return Err(AppError::Database(e.to_string())),
|
||||
};
|
||||
|
||||
let settings_config = serde_json::from_str(&settings_config_str).map_err(|e| {
|
||||
AppError::Database(format!(
|
||||
"Failed to parse OMO provider settings_config (provider_id={id}): {e}"
|
||||
))
|
||||
})?;
|
||||
let meta: crate::provider::ProviderMeta = if meta_str.trim().is_empty() {
|
||||
crate::provider::ProviderMeta::default()
|
||||
} else {
|
||||
serde_json::from_str(&meta_str).map_err(|e| {
|
||||
AppError::Database(format!(
|
||||
"Failed to parse OMO provider meta (provider_id={id}): {e}"
|
||||
))
|
||||
})?
|
||||
};
|
||||
|
||||
Ok(Some(Provider {
|
||||
id,
|
||||
name,
|
||||
settings_config,
|
||||
website_url: None,
|
||||
category,
|
||||
created_at,
|
||||
sort_index,
|
||||
notes,
|
||||
meta: Some(meta),
|
||||
icon: None,
|
||||
icon_color: None,
|
||||
in_failover_queue: false,
|
||||
}))
|
||||
}
|
||||
|
||||
// ── OMO Slim provider management ────────────────────────────
|
||||
|
||||
pub fn set_omo_slim_provider_current(
|
||||
&self,
|
||||
app_type: &str,
|
||||
provider_id: &str,
|
||||
) -> Result<(), AppError> {
|
||||
let mut conn = lock_conn!(self.conn);
|
||||
let tx = conn
|
||||
.transaction()
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
tx.execute(
|
||||
"UPDATE providers SET is_current = 0 WHERE app_type = ?1 AND category = 'omo-slim'",
|
||||
params![app_type],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
let updated = tx
|
||||
.execute(
|
||||
"UPDATE providers SET is_current = 1 WHERE id = ?1 AND app_type = ?2 AND category = 'omo-slim'",
|
||||
params![provider_id, app_type],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
if updated != 1 {
|
||||
return Err(AppError::Database(format!(
|
||||
"Failed to set OMO Slim provider current: provider '{provider_id}' not found in app '{app_type}'"
|
||||
)));
|
||||
}
|
||||
tx.commit().map_err(|e| AppError::Database(e.to_string()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_omo_slim_provider_current(
|
||||
&self,
|
||||
app_type: &str,
|
||||
provider_id: &str,
|
||||
) -> Result<bool, AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
match conn.query_row(
|
||||
"SELECT is_current FROM providers
|
||||
WHERE id = ?1 AND app_type = ?2 AND category = 'omo-slim'",
|
||||
params![provider_id, app_type],
|
||||
|row| row.get(0),
|
||||
) {
|
||||
Ok(is_current) => Ok(is_current),
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(false),
|
||||
Err(e) => Err(AppError::Database(e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_omo_slim_provider_current(
|
||||
&self,
|
||||
app_type: &str,
|
||||
provider_id: &str,
|
||||
) -> Result<(), AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
conn.execute(
|
||||
"UPDATE providers SET is_current = 0
|
||||
WHERE id = ?1 AND app_type = ?2 AND category = 'omo-slim'",
|
||||
params![provider_id, app_type],
|
||||
)
|
||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_current_omo_slim_provider(
|
||||
pub fn get_current_omo_provider(
|
||||
&self,
|
||||
app_type: &str,
|
||||
category: &str,
|
||||
) -> Result<Option<Provider>, AppError> {
|
||||
let conn = lock_conn!(self.conn);
|
||||
let row_data: Result<OmoProviderRow, rusqlite::Error> = conn.query_row(
|
||||
"SELECT id, name, settings_config, category, created_at, sort_index, notes, meta
|
||||
FROM providers
|
||||
WHERE app_type = ?1 AND category = 'omo-slim' AND is_current = 1
|
||||
WHERE app_type = ?1 AND category = ?2 AND is_current = 1
|
||||
LIMIT 1",
|
||||
params![app_type],
|
||||
params![app_type, category],
|
||||
|row| {
|
||||
Ok((
|
||||
row.get(0)?,
|
||||
@@ -571,7 +451,7 @@ impl Database {
|
||||
},
|
||||
);
|
||||
|
||||
let (id, name, settings_config_str, category, created_at, sort_index, notes, meta_str) =
|
||||
let (id, name, settings_config_str, _row_category, created_at, sort_index, notes, meta_str) =
|
||||
match row_data {
|
||||
Ok(v) => v,
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => return Ok(None),
|
||||
@@ -580,7 +460,7 @@ impl Database {
|
||||
|
||||
let settings_config = serde_json::from_str(&settings_config_str).map_err(|e| {
|
||||
AppError::Database(format!(
|
||||
"Failed to parse OMO Slim provider settings_config (provider_id={id}): {e}"
|
||||
"Failed to parse {category} provider settings_config (provider_id={id}): {e}"
|
||||
))
|
||||
})?;
|
||||
let meta: crate::provider::ProviderMeta = if meta_str.trim().is_empty() {
|
||||
@@ -588,7 +468,7 @@ impl Database {
|
||||
} else {
|
||||
serde_json::from_str(&meta_str).map_err(|e| {
|
||||
AppError::Database(format!(
|
||||
"Failed to parse OMO Slim provider meta (provider_id={id}): {e}"
|
||||
"Failed to parse {category} provider meta (provider_id={id}): {e}"
|
||||
))
|
||||
})?
|
||||
};
|
||||
@@ -598,7 +478,7 @@ impl Database {
|
||||
name,
|
||||
settings_config,
|
||||
website_url: None,
|
||||
category,
|
||||
category: Some(category.to_string()),
|
||||
created_at,
|
||||
sort_index,
|
||||
notes,
|
||||
|
||||
@@ -512,7 +512,7 @@ pub fn run() {
|
||||
.map(|providers| providers.values().any(|p| p.category.as_deref() == Some("omo")))
|
||||
.unwrap_or(false);
|
||||
if !has_omo {
|
||||
match crate::services::OmoService::import_from_local(&app_state) {
|
||||
match crate::services::OmoService::import_from_local(&app_state, &crate::services::omo::STANDARD) {
|
||||
Ok(provider) => {
|
||||
log::info!("✓ Imported OMO config from local as provider '{}'", provider.name);
|
||||
}
|
||||
@@ -538,7 +538,7 @@ pub fn run() {
|
||||
})
|
||||
.unwrap_or(false);
|
||||
if !has_omo_slim {
|
||||
match crate::services::OmoService::import_from_local_slim(&app_state) {
|
||||
match crate::services::OmoService::import_from_local(&app_state, &crate::services::omo::SLIM) {
|
||||
Ok(provider) => {
|
||||
log::info!(
|
||||
"✓ Imported OMO Slim config from local as provider '{}'",
|
||||
|
||||
+180
-271
@@ -20,15 +20,83 @@ pub struct OmoLocalFileData {
|
||||
|
||||
type OmoProfileData = (Option<Value>, Option<Value>, Option<Value>, bool);
|
||||
|
||||
// ── Variant descriptor ─────────────────────────────────────────
|
||||
|
||||
pub struct OmoVariant {
|
||||
pub filename: &'static str,
|
||||
pub category: &'static str,
|
||||
pub provider_prefix: &'static str,
|
||||
pub plugin_name: &'static str,
|
||||
pub plugin_prefix: &'static str,
|
||||
pub known_keys: &'static [&'static str],
|
||||
pub has_categories: bool,
|
||||
pub config_key: &'static str,
|
||||
pub label: &'static str,
|
||||
pub import_label: &'static str,
|
||||
}
|
||||
|
||||
pub const STANDARD: OmoVariant = OmoVariant {
|
||||
filename: "oh-my-opencode.jsonc",
|
||||
category: "omo",
|
||||
provider_prefix: "omo-",
|
||||
plugin_name: "oh-my-opencode@latest",
|
||||
plugin_prefix: "oh-my-opencode",
|
||||
known_keys: &[
|
||||
"$schema",
|
||||
"agents",
|
||||
"categories",
|
||||
"sisyphus_agent",
|
||||
"disabled_agents",
|
||||
"disabled_mcps",
|
||||
"disabled_hooks",
|
||||
"disabled_skills",
|
||||
"lsp",
|
||||
"experimental",
|
||||
"background_task",
|
||||
"browser_automation_engine",
|
||||
"claude_code",
|
||||
],
|
||||
has_categories: true,
|
||||
config_key: "common_config_omo",
|
||||
label: "OMO",
|
||||
import_label: "Imported",
|
||||
};
|
||||
|
||||
pub const SLIM: OmoVariant = OmoVariant {
|
||||
filename: "oh-my-opencode-slim.jsonc",
|
||||
category: "omo-slim",
|
||||
provider_prefix: "omo-slim-",
|
||||
plugin_name: "oh-my-opencode-slim@latest",
|
||||
plugin_prefix: "oh-my-opencode-slim",
|
||||
known_keys: &[
|
||||
"$schema",
|
||||
"agents",
|
||||
"sisyphus_agent",
|
||||
"disabled_agents",
|
||||
"disabled_mcps",
|
||||
"disabled_hooks",
|
||||
"lsp",
|
||||
"experimental",
|
||||
],
|
||||
has_categories: false,
|
||||
config_key: "common_config_omo_slim",
|
||||
label: "OMO Slim",
|
||||
import_label: "Imported Slim",
|
||||
};
|
||||
|
||||
// ── Service ────────────────────────────────────────────────────
|
||||
|
||||
pub struct OmoService;
|
||||
|
||||
impl OmoService {
|
||||
fn config_path() -> PathBuf {
|
||||
get_opencode_dir().join("oh-my-opencode.jsonc")
|
||||
// ── Path helpers ────────────────────────────────────────
|
||||
|
||||
fn config_path(v: &OmoVariant) -> PathBuf {
|
||||
get_opencode_dir().join(v.filename)
|
||||
}
|
||||
|
||||
fn resolve_local_config_path() -> Result<PathBuf, AppError> {
|
||||
let config_path = Self::config_path();
|
||||
fn resolve_local_config_path(v: &OmoVariant) -> Result<PathBuf, AppError> {
|
||||
let config_path = Self::config_path(v);
|
||||
if config_path.exists() {
|
||||
return Ok(config_path);
|
||||
}
|
||||
@@ -52,40 +120,7 @@ impl OmoService {
|
||||
.ok_or_else(|| AppError::Config("Expected JSON object".to_string()))
|
||||
}
|
||||
|
||||
const KNOWN_KEYS: [&str; 13] = [
|
||||
"$schema",
|
||||
"agents",
|
||||
"categories",
|
||||
"sisyphus_agent",
|
||||
"disabled_agents",
|
||||
"disabled_mcps",
|
||||
"disabled_hooks",
|
||||
"disabled_skills",
|
||||
"lsp",
|
||||
"experimental",
|
||||
"background_task",
|
||||
"browser_automation_engine",
|
||||
"claude_code",
|
||||
];
|
||||
|
||||
const KNOWN_KEYS_SLIM: [&str; 8] = [
|
||||
"$schema",
|
||||
"agents",
|
||||
"sisyphus_agent",
|
||||
"disabled_agents",
|
||||
"disabled_mcps",
|
||||
"disabled_hooks",
|
||||
"lsp",
|
||||
"experimental",
|
||||
];
|
||||
|
||||
fn extract_other_fields(obj: &Map<String, Value>) -> Map<String, Value> {
|
||||
Self::extract_other_fields_with_keys(obj, &Self::KNOWN_KEYS)
|
||||
}
|
||||
|
||||
fn extract_other_fields_slim(obj: &Map<String, Value>) -> Map<String, Value> {
|
||||
Self::extract_other_fields_with_keys(obj, &Self::KNOWN_KEYS_SLIM)
|
||||
}
|
||||
// ── Field extraction ───────────────────────────────────
|
||||
|
||||
fn extract_other_fields_with_keys(
|
||||
obj: &Map<String, Value>,
|
||||
@@ -141,6 +176,8 @@ impl OmoService {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Merge helpers ──────────────────────────────────────
|
||||
|
||||
fn insert_opt_value(result: &mut Map<String, Value>, key: &str, value: &Option<Value>) {
|
||||
if let Some(v) = value {
|
||||
result.insert(key.to_string(), v.clone());
|
||||
@@ -164,62 +201,40 @@ impl OmoService {
|
||||
}
|
||||
}
|
||||
|
||||
fn config_path_slim() -> PathBuf {
|
||||
get_opencode_dir().join("oh-my-opencode-slim.jsonc")
|
||||
}
|
||||
// ── Public API (variant-parameterized) ─────────────────
|
||||
|
||||
fn resolve_local_config_path_slim() -> Result<PathBuf, AppError> {
|
||||
let config_path = Self::config_path_slim();
|
||||
if config_path.exists() {
|
||||
return Ok(config_path);
|
||||
}
|
||||
|
||||
let json_path = config_path.with_extension("json");
|
||||
if json_path.exists() {
|
||||
return Ok(json_path);
|
||||
}
|
||||
|
||||
Err(AppError::OmoConfigNotFound)
|
||||
}
|
||||
|
||||
pub fn delete_config_file() -> Result<(), AppError> {
|
||||
let config_path = Self::config_path();
|
||||
pub fn delete_config_file(v: &OmoVariant) -> Result<(), AppError> {
|
||||
let config_path = Self::config_path(v);
|
||||
if config_path.exists() {
|
||||
std::fs::remove_file(&config_path).map_err(|e| AppError::io(&config_path, e))?;
|
||||
log::info!("OMO config file deleted: {config_path:?}");
|
||||
log::info!("{} config file deleted: {config_path:?}", v.label);
|
||||
}
|
||||
crate::opencode_config::remove_plugin_by_prefix("oh-my-opencode")?;
|
||||
crate::opencode_config::remove_plugin_by_prefix(v.plugin_prefix)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn delete_config_file_slim() -> Result<(), AppError> {
|
||||
let config_path = Self::config_path_slim();
|
||||
if config_path.exists() {
|
||||
std::fs::remove_file(&config_path).map_err(|e| AppError::io(&config_path, e))?;
|
||||
log::info!("OMO Slim config file deleted: {config_path:?}");
|
||||
}
|
||||
crate::opencode_config::remove_plugin_by_prefix("oh-my-opencode-slim")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_config_to_file(state: &AppState) -> Result<(), AppError> {
|
||||
let global = state.db.get_omo_global_config()?;
|
||||
let current_omo = state.db.get_current_omo_provider("opencode")?;
|
||||
pub fn write_config_to_file(state: &AppState, v: &OmoVariant) -> Result<(), AppError> {
|
||||
let global = state.db.get_omo_global_config(v.config_key)?;
|
||||
let current_omo = state.db.get_current_omo_provider("opencode", v.category)?;
|
||||
|
||||
let profile_data = current_omo.as_ref().map(|p| {
|
||||
let agents = p.settings_config.get("agents").cloned();
|
||||
let categories = p.settings_config.get("categories").cloned();
|
||||
let categories = if v.has_categories {
|
||||
p.settings_config.get("categories").cloned()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let other_fields = p.settings_config.get("otherFields").cloned();
|
||||
let use_common_config = p
|
||||
.settings_config
|
||||
.get("useCommonConfig")
|
||||
.and_then(|v| v.as_bool())
|
||||
.and_then(|val| val.as_bool())
|
||||
.unwrap_or(true);
|
||||
(agents, categories, other_fields, use_common_config)
|
||||
});
|
||||
|
||||
let merged = Self::merge_config(&global, profile_data.as_ref());
|
||||
let config_path = Self::config_path();
|
||||
let merged = Self::merge_config(v, &global, profile_data.as_ref());
|
||||
let config_path = Self::config_path(v);
|
||||
|
||||
if let Some(parent) = config_path.parent() {
|
||||
std::fs::create_dir_all(parent).map_err(|e| AppError::io(parent, e))?;
|
||||
@@ -227,45 +242,19 @@ impl OmoService {
|
||||
|
||||
write_json_file(&config_path, &merged)?;
|
||||
|
||||
crate::opencode_config::add_plugin("oh-my-opencode@latest")?;
|
||||
crate::opencode_config::add_plugin(v.plugin_name)?;
|
||||
|
||||
log::info!("OMO config written to {config_path:?}");
|
||||
log::info!("{} config written to {config_path:?}", v.label);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_config_to_file_slim(state: &AppState) -> Result<(), AppError> {
|
||||
let global = state.db.get_omo_slim_global_config()?;
|
||||
let current_omo = state.db.get_current_omo_slim_provider("opencode")?;
|
||||
|
||||
let profile_data = current_omo.as_ref().map(|p| {
|
||||
let agents = p.settings_config.get("agents").cloned();
|
||||
let other_fields = p.settings_config.get("otherFields").cloned();
|
||||
let use_common_config = p
|
||||
.settings_config
|
||||
.get("useCommonConfig")
|
||||
.and_then(|v| v.as_bool())
|
||||
.unwrap_or(true);
|
||||
(agents, None, other_fields, use_common_config)
|
||||
});
|
||||
|
||||
let merged = Self::merge_config_slim(&global, profile_data.as_ref());
|
||||
let config_path = Self::config_path_slim();
|
||||
|
||||
if let Some(parent) = config_path.parent() {
|
||||
std::fs::create_dir_all(parent).map_err(|e| AppError::io(parent, e))?;
|
||||
}
|
||||
|
||||
write_json_file(&config_path, &merged)?;
|
||||
|
||||
crate::opencode_config::add_plugin("oh-my-opencode-slim@latest")?;
|
||||
|
||||
log::info!("OMO Slim config written to {config_path:?}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn merge_config(global: &OmoGlobalConfig, profile_data: Option<&OmoProfileData>) -> Value {
|
||||
fn merge_config(
|
||||
v: &OmoVariant,
|
||||
global: &OmoGlobalConfig,
|
||||
profile_data: Option<&OmoProfileData>,
|
||||
) -> Value {
|
||||
let mut result = Map::new();
|
||||
let use_common_config = profile_data.map(|(_, _, _, v)| *v).unwrap_or(true);
|
||||
let use_common_config = profile_data.map(|(_, _, _, uc)| *uc).unwrap_or(true);
|
||||
|
||||
if use_common_config {
|
||||
if let Some(url) = &global.schema_url {
|
||||
@@ -276,141 +265,67 @@ impl OmoService {
|
||||
Self::insert_string_array(&mut result, "disabled_agents", &global.disabled_agents);
|
||||
Self::insert_string_array(&mut result, "disabled_mcps", &global.disabled_mcps);
|
||||
Self::insert_string_array(&mut result, "disabled_hooks", &global.disabled_hooks);
|
||||
Self::insert_string_array(&mut result, "disabled_skills", &global.disabled_skills);
|
||||
|
||||
if v.has_categories {
|
||||
Self::insert_string_array(&mut result, "disabled_skills", &global.disabled_skills);
|
||||
Self::insert_opt_value(&mut result, "background_task", &global.background_task);
|
||||
Self::insert_opt_value(
|
||||
&mut result,
|
||||
"browser_automation_engine",
|
||||
&global.browser_automation_engine,
|
||||
);
|
||||
Self::insert_opt_value(&mut result, "claude_code", &global.claude_code);
|
||||
}
|
||||
|
||||
Self::insert_opt_value(&mut result, "lsp", &global.lsp);
|
||||
Self::insert_opt_value(&mut result, "experimental", &global.experimental);
|
||||
Self::insert_opt_value(&mut result, "background_task", &global.background_task);
|
||||
Self::insert_opt_value(
|
||||
&mut result,
|
||||
"browser_automation_engine",
|
||||
&global.browser_automation_engine,
|
||||
);
|
||||
Self::insert_opt_value(&mut result, "claude_code", &global.claude_code);
|
||||
|
||||
Self::insert_object_entries(&mut result, global.other_fields.as_ref());
|
||||
}
|
||||
|
||||
if let Some((agents, categories, other_fields, _)) = profile_data {
|
||||
Self::insert_opt_value(&mut result, "agents", agents);
|
||||
Self::insert_opt_value(&mut result, "categories", categories);
|
||||
Self::insert_object_entries(&mut result, other_fields.as_ref());
|
||||
}
|
||||
|
||||
Value::Object(result)
|
||||
}
|
||||
|
||||
/// Merge config for Slim variant (no categories, no disabled_skills, no background_task, etc.)
|
||||
fn merge_config_slim(global: &OmoGlobalConfig, profile_data: Option<&OmoProfileData>) -> Value {
|
||||
let mut result = Map::new();
|
||||
let use_common_config = profile_data.map(|(_, _, _, v)| *v).unwrap_or(true);
|
||||
|
||||
if use_common_config {
|
||||
if let Some(url) = &global.schema_url {
|
||||
result.insert("$schema".to_string(), Value::String(url.clone()));
|
||||
if v.has_categories {
|
||||
Self::insert_opt_value(&mut result, "categories", categories);
|
||||
}
|
||||
|
||||
Self::insert_opt_value(&mut result, "sisyphus_agent", &global.sisyphus_agent);
|
||||
Self::insert_string_array(&mut result, "disabled_agents", &global.disabled_agents);
|
||||
Self::insert_string_array(&mut result, "disabled_mcps", &global.disabled_mcps);
|
||||
Self::insert_string_array(&mut result, "disabled_hooks", &global.disabled_hooks);
|
||||
// Slim does NOT support: disabled_skills, background_task, browser_automation_engine, claude_code
|
||||
Self::insert_opt_value(&mut result, "lsp", &global.lsp);
|
||||
Self::insert_opt_value(&mut result, "experimental", &global.experimental);
|
||||
|
||||
Self::insert_object_entries(&mut result, global.other_fields.as_ref());
|
||||
}
|
||||
|
||||
if let Some((agents, _categories, other_fields, _)) = profile_data {
|
||||
Self::insert_opt_value(&mut result, "agents", agents);
|
||||
// Slim does NOT have categories
|
||||
Self::insert_object_entries(&mut result, other_fields.as_ref());
|
||||
}
|
||||
|
||||
Value::Object(result)
|
||||
}
|
||||
|
||||
pub fn import_from_local(state: &AppState) -> Result<crate::provider::Provider, AppError> {
|
||||
let actual_path = Self::resolve_local_config_path()?;
|
||||
Self::import_from_path(state, &actual_path)
|
||||
}
|
||||
|
||||
fn import_from_path(
|
||||
pub fn import_from_local(
|
||||
state: &AppState,
|
||||
path: &std::path::Path,
|
||||
v: &OmoVariant,
|
||||
) -> Result<crate::provider::Provider, AppError> {
|
||||
let obj = Self::read_jsonc_object(path)?;
|
||||
|
||||
let mut settings = Map::new();
|
||||
if let Some(agents) = obj.get("agents") {
|
||||
settings.insert("agents".to_string(), agents.clone());
|
||||
}
|
||||
if let Some(categories) = obj.get("categories") {
|
||||
settings.insert("categories".to_string(), categories.clone());
|
||||
}
|
||||
settings.insert("useCommonConfig".to_string(), Value::Bool(true));
|
||||
|
||||
let other = Self::extract_other_fields(&obj);
|
||||
if !other.is_empty() {
|
||||
settings.insert("otherFields".to_string(), Value::Object(other));
|
||||
}
|
||||
|
||||
let mut global = state.db.get_omo_global_config()?;
|
||||
Self::merge_global_from_obj(&obj, &mut global);
|
||||
global.updated_at = chrono::Utc::now().to_rfc3339();
|
||||
state.db.save_omo_global_config(&global)?;
|
||||
|
||||
let provider_id = format!("omo-{}", uuid::Uuid::new_v4());
|
||||
let name = format!("Imported {}", chrono::Local::now().format("%Y-%m-%d %H:%M"));
|
||||
let settings_config =
|
||||
serde_json::to_value(&settings).unwrap_or_else(|_| serde_json::json!({}));
|
||||
|
||||
let provider = crate::provider::Provider {
|
||||
id: provider_id,
|
||||
name,
|
||||
settings_config,
|
||||
website_url: None,
|
||||
category: Some("omo".to_string()),
|
||||
created_at: Some(chrono::Utc::now().timestamp_millis()),
|
||||
sort_index: None,
|
||||
notes: None,
|
||||
meta: None,
|
||||
icon: None,
|
||||
icon_color: None,
|
||||
in_failover_queue: false,
|
||||
};
|
||||
|
||||
state.db.save_provider("opencode", &provider)?;
|
||||
state
|
||||
.db
|
||||
.set_omo_provider_current("opencode", &provider.id)?;
|
||||
Self::write_config_to_file(state)?;
|
||||
Ok(provider)
|
||||
}
|
||||
|
||||
pub fn import_from_local_slim(state: &AppState) -> Result<crate::provider::Provider, AppError> {
|
||||
let actual_path = Self::resolve_local_config_path_slim()?;
|
||||
let actual_path = Self::resolve_local_config_path(v)?;
|
||||
let obj = Self::read_jsonc_object(&actual_path)?;
|
||||
|
||||
let mut settings = Map::new();
|
||||
if let Some(agents) = obj.get("agents") {
|
||||
settings.insert("agents".to_string(), agents.clone());
|
||||
}
|
||||
// Slim has no categories
|
||||
if v.has_categories {
|
||||
if let Some(categories) = obj.get("categories") {
|
||||
settings.insert("categories".to_string(), categories.clone());
|
||||
}
|
||||
}
|
||||
settings.insert("useCommonConfig".to_string(), Value::Bool(true));
|
||||
|
||||
let other = Self::extract_other_fields_slim(&obj);
|
||||
let other = Self::extract_other_fields_with_keys(&obj, v.known_keys);
|
||||
if !other.is_empty() {
|
||||
settings.insert("otherFields".to_string(), Value::Object(other));
|
||||
}
|
||||
|
||||
let mut global = state.db.get_omo_slim_global_config()?;
|
||||
let mut global = state.db.get_omo_global_config(v.config_key)?;
|
||||
Self::merge_global_from_obj(&obj, &mut global);
|
||||
global.updated_at = chrono::Utc::now().to_rfc3339();
|
||||
state.db.save_omo_slim_global_config(&global)?;
|
||||
state.db.save_omo_global_config(v.config_key, &global)?;
|
||||
|
||||
let provider_id = format!("omo-slim-{}", uuid::Uuid::new_v4());
|
||||
let provider_id = format!("{}{}", v.provider_prefix, uuid::Uuid::new_v4());
|
||||
let name = format!(
|
||||
"Imported Slim {}",
|
||||
"{} {}",
|
||||
v.import_label,
|
||||
chrono::Local::now().format("%Y-%m-%d %H:%M")
|
||||
);
|
||||
let settings_config =
|
||||
@@ -421,7 +336,7 @@ impl OmoService {
|
||||
name,
|
||||
settings_config,
|
||||
website_url: None,
|
||||
category: Some("omo-slim".to_string()),
|
||||
category: Some(v.category.to_string()),
|
||||
created_at: Some(chrono::Utc::now().timestamp_millis()),
|
||||
sort_index: None,
|
||||
notes: None,
|
||||
@@ -434,13 +349,13 @@ impl OmoService {
|
||||
state.db.save_provider("opencode", &provider)?;
|
||||
state
|
||||
.db
|
||||
.set_omo_slim_provider_current("opencode", &provider.id)?;
|
||||
Self::write_config_to_file_slim(state)?;
|
||||
.set_omo_provider_current("opencode", &provider.id, v.category)?;
|
||||
Self::write_config_to_file(state, v)?;
|
||||
Ok(provider)
|
||||
}
|
||||
|
||||
pub fn read_local_file() -> Result<OmoLocalFileData, AppError> {
|
||||
let actual_path = Self::resolve_local_config_path()?;
|
||||
pub fn read_local_file(v: &OmoVariant) -> Result<OmoLocalFileData, AppError> {
|
||||
let actual_path = Self::resolve_local_config_path(v)?;
|
||||
let metadata = std::fs::metadata(&actual_path).ok();
|
||||
let last_modified = metadata
|
||||
.and_then(|m| m.modified().ok())
|
||||
@@ -448,38 +363,28 @@ impl OmoService {
|
||||
|
||||
let obj = Self::read_jsonc_object(&actual_path)?;
|
||||
|
||||
Ok(Self::build_local_file_data_from_obj(
|
||||
Ok(Self::build_local_file_data(
|
||||
v,
|
||||
&obj,
|
||||
actual_path.to_string_lossy().to_string(),
|
||||
last_modified,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn read_local_file_slim() -> Result<OmoLocalFileData, AppError> {
|
||||
let actual_path = Self::resolve_local_config_path_slim()?;
|
||||
let metadata = std::fs::metadata(&actual_path).ok();
|
||||
let last_modified = metadata
|
||||
.and_then(|m| m.modified().ok())
|
||||
.map(|t| chrono::DateTime::<chrono::Utc>::from(t).to_rfc3339());
|
||||
|
||||
let obj = Self::read_jsonc_object(&actual_path)?;
|
||||
|
||||
Ok(Self::build_local_file_data_slim_from_obj(
|
||||
&obj,
|
||||
actual_path.to_string_lossy().to_string(),
|
||||
last_modified,
|
||||
))
|
||||
}
|
||||
|
||||
fn build_local_file_data_from_obj(
|
||||
fn build_local_file_data(
|
||||
v: &OmoVariant,
|
||||
obj: &Map<String, Value>,
|
||||
file_path: String,
|
||||
last_modified: Option<String>,
|
||||
) -> OmoLocalFileData {
|
||||
let agents = obj.get("agents").cloned();
|
||||
let categories = obj.get("categories").cloned();
|
||||
let categories = if v.has_categories {
|
||||
obj.get("categories").cloned()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let other = Self::extract_other_fields(obj);
|
||||
let other = Self::extract_other_fields_with_keys(obj, v.known_keys);
|
||||
let other_fields = if other.is_empty() {
|
||||
None
|
||||
} else {
|
||||
@@ -500,35 +405,6 @@ impl OmoService {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_local_file_data_slim_from_obj(
|
||||
obj: &Map<String, Value>,
|
||||
file_path: String,
|
||||
last_modified: Option<String>,
|
||||
) -> OmoLocalFileData {
|
||||
let agents = obj.get("agents").cloned();
|
||||
// Slim has no categories
|
||||
|
||||
let other = Self::extract_other_fields_slim(obj);
|
||||
let other_fields = if other.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(Value::Object(other))
|
||||
};
|
||||
|
||||
let mut global = OmoGlobalConfig::default();
|
||||
Self::merge_global_from_obj(obj, &mut global);
|
||||
global.other_fields = other_fields.clone();
|
||||
|
||||
OmoLocalFileData {
|
||||
agents,
|
||||
categories: None,
|
||||
other_fields,
|
||||
global,
|
||||
file_path,
|
||||
last_modified,
|
||||
}
|
||||
}
|
||||
|
||||
fn strip_jsonc_comments(input: &str) -> String {
|
||||
let mut result = String::with_capacity(input.len());
|
||||
let mut chars = input.chars().peekable();
|
||||
@@ -608,7 +484,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_merge_config_empty() {
|
||||
let global = OmoGlobalConfig::default();
|
||||
let merged = OmoService::merge_config(&global, None);
|
||||
let merged = OmoService::merge_config(&STANDARD, &global, None);
|
||||
assert!(merged.is_object());
|
||||
}
|
||||
|
||||
@@ -625,7 +501,7 @@ mod tests {
|
||||
let categories = None;
|
||||
let other_fields = None;
|
||||
let profile_data = (agents, categories, other_fields, true);
|
||||
let merged = OmoService::merge_config(&global, Some(&profile_data));
|
||||
let merged = OmoService::merge_config(&STANDARD, &global, Some(&profile_data));
|
||||
let obj = merged.as_object().unwrap();
|
||||
|
||||
assert_eq!(obj["$schema"], "https://example.com/schema.json");
|
||||
@@ -647,7 +523,7 @@ mod tests {
|
||||
let categories = None;
|
||||
let other_fields = None;
|
||||
let profile_data = (agents, categories, other_fields, false);
|
||||
let merged = OmoService::merge_config(&global, Some(&profile_data));
|
||||
let merged = OmoService::merge_config(&STANDARD, &global, Some(&profile_data));
|
||||
let obj = merged.as_object().unwrap();
|
||||
|
||||
assert!(!obj.contains_key("$schema"));
|
||||
@@ -672,7 +548,8 @@ mod tests {
|
||||
});
|
||||
let obj_map = obj.as_object().unwrap().clone();
|
||||
|
||||
let data = OmoService::build_local_file_data_from_obj(
|
||||
let data = OmoService::build_local_file_data(
|
||||
&STANDARD,
|
||||
&obj_map,
|
||||
"/tmp/oh-my-opencode.jsonc".to_string(),
|
||||
None,
|
||||
@@ -704,11 +581,43 @@ mod tests {
|
||||
let other_fields = Some(serde_json::json!("profile_non_object"));
|
||||
let profile_data = (agents, categories, other_fields, true);
|
||||
|
||||
let merged = OmoService::merge_config(&global, Some(&profile_data));
|
||||
let merged = OmoService::merge_config(&STANDARD, &global, Some(&profile_data));
|
||||
let obj = merged.as_object().unwrap();
|
||||
|
||||
assert!(!obj.contains_key("0"));
|
||||
assert!(!obj.contains_key("global_non_object"));
|
||||
assert!(!obj.contains_key("profile_non_object"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merge_config_slim_excludes_categories_and_extra_fields() {
|
||||
let global = OmoGlobalConfig {
|
||||
schema_url: Some("https://slim.schema".to_string()),
|
||||
disabled_agents: vec!["oracle".to_string()],
|
||||
disabled_skills: vec!["playwright".to_string()],
|
||||
background_task: Some(serde_json::json!({"key": "val"})),
|
||||
browser_automation_engine: Some(serde_json::json!({"provider": "pw"})),
|
||||
claude_code: Some(serde_json::json!({"mcp": true})),
|
||||
..Default::default()
|
||||
};
|
||||
let agents = Some(serde_json::json!({"orchestrator": {"model": "k2"}}));
|
||||
let categories = Some(serde_json::json!({"code": {"model": "gpt"}}));
|
||||
let other_fields = None;
|
||||
let profile_data = (agents, categories, other_fields, true);
|
||||
|
||||
let merged = OmoService::merge_config(&SLIM, &global, Some(&profile_data));
|
||||
let obj = merged.as_object().unwrap();
|
||||
|
||||
// Slim should NOT include these
|
||||
assert!(!obj.contains_key("disabled_skills"));
|
||||
assert!(!obj.contains_key("background_task"));
|
||||
assert!(!obj.contains_key("browser_automation_engine"));
|
||||
assert!(!obj.contains_key("claude_code"));
|
||||
assert!(!obj.contains_key("categories"));
|
||||
|
||||
// Slim SHOULD include these
|
||||
assert_eq!(obj["$schema"], "https://slim.schema");
|
||||
assert!(obj.contains_key("agents"));
|
||||
assert!(obj.contains_key("disabled_agents"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,22 +208,31 @@ impl ProviderService {
|
||||
if app_type.is_additive_mode() {
|
||||
if matches!(app_type, AppType::OpenCode) && provider.category.as_deref() == Some("omo")
|
||||
{
|
||||
let is_omo_current = state
|
||||
.db
|
||||
.is_omo_provider_current(app_type.as_str(), &provider.id)?;
|
||||
let is_omo_current =
|
||||
state
|
||||
.db
|
||||
.is_omo_provider_current(app_type.as_str(), &provider.id, "omo")?;
|
||||
if is_omo_current {
|
||||
crate::services::OmoService::write_config_to_file(state)?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state,
|
||||
&crate::services::omo::STANDARD,
|
||||
)?;
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
if matches!(app_type, AppType::OpenCode)
|
||||
&& provider.category.as_deref() == Some("omo-slim")
|
||||
{
|
||||
let is_current = state
|
||||
.db
|
||||
.is_omo_slim_provider_current(app_type.as_str(), &provider.id)?;
|
||||
let is_current = state.db.is_omo_provider_current(
|
||||
app_type.as_str(),
|
||||
&provider.id,
|
||||
"omo-slim",
|
||||
)?;
|
||||
if is_current {
|
||||
crate::services::OmoService::write_config_to_file_slim(state)?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state,
|
||||
&crate::services::omo::SLIM,
|
||||
)?;
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
@@ -279,7 +288,10 @@ impl ProviderService {
|
||||
.and_then(|p| p.category);
|
||||
|
||||
if provider_category.as_deref() == Some("omo") {
|
||||
let was_current = state.db.is_omo_provider_current(app_type.as_str(), id)?;
|
||||
let was_current =
|
||||
state
|
||||
.db
|
||||
.is_omo_provider_current(app_type.as_str(), id, "omo")?;
|
||||
let omo_count = state
|
||||
.db
|
||||
.get_all_providers(app_type.as_str())?
|
||||
@@ -295,15 +307,18 @@ impl ProviderService {
|
||||
|
||||
state.db.delete_provider(app_type.as_str(), id)?;
|
||||
if was_current {
|
||||
crate::services::OmoService::delete_config_file()?;
|
||||
crate::services::OmoService::delete_config_file(
|
||||
&crate::services::omo::STANDARD,
|
||||
)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if provider_category.as_deref() == Some("omo-slim") {
|
||||
let was_current = state
|
||||
.db
|
||||
.is_omo_slim_provider_current(app_type.as_str(), id)?;
|
||||
let was_current =
|
||||
state
|
||||
.db
|
||||
.is_omo_provider_current(app_type.as_str(), id, "omo-slim")?;
|
||||
let slim_count = state
|
||||
.db
|
||||
.get_all_providers(app_type.as_str())?
|
||||
@@ -319,7 +334,9 @@ impl ProviderService {
|
||||
|
||||
state.db.delete_provider(app_type.as_str(), id)?;
|
||||
if was_current {
|
||||
crate::services::OmoService::delete_config_file_slim()?;
|
||||
crate::services::OmoService::delete_config_file(
|
||||
&crate::services::omo::SLIM,
|
||||
)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@@ -366,26 +383,40 @@ impl ProviderService {
|
||||
.and_then(|p| p.category);
|
||||
|
||||
if provider_category.as_deref() == Some("omo") {
|
||||
state.db.clear_omo_provider_current(app_type.as_str(), id)?;
|
||||
let still_has_current =
|
||||
state.db.get_current_omo_provider("opencode")?.is_some();
|
||||
state
|
||||
.db
|
||||
.clear_omo_provider_current(app_type.as_str(), id, "omo")?;
|
||||
let still_has_current = state
|
||||
.db
|
||||
.get_current_omo_provider("opencode", "omo")?
|
||||
.is_some();
|
||||
if still_has_current {
|
||||
crate::services::OmoService::write_config_to_file(state)?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state,
|
||||
&crate::services::omo::STANDARD,
|
||||
)?;
|
||||
} else {
|
||||
crate::services::OmoService::delete_config_file()?;
|
||||
crate::services::OmoService::delete_config_file(
|
||||
&crate::services::omo::STANDARD,
|
||||
)?;
|
||||
}
|
||||
} else if provider_category.as_deref() == Some("omo-slim") {
|
||||
state
|
||||
.db
|
||||
.clear_omo_slim_provider_current(app_type.as_str(), id)?;
|
||||
.clear_omo_provider_current(app_type.as_str(), id, "omo-slim")?;
|
||||
let still_has_current = state
|
||||
.db
|
||||
.get_current_omo_slim_provider("opencode")?
|
||||
.get_current_omo_provider("opencode", "omo-slim")?
|
||||
.is_some();
|
||||
if still_has_current {
|
||||
crate::services::OmoService::write_config_to_file_slim(state)?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state,
|
||||
&crate::services::omo::SLIM,
|
||||
)?;
|
||||
} else {
|
||||
crate::services::OmoService::delete_config_file_slim()?;
|
||||
crate::services::OmoService::delete_config_file(
|
||||
&crate::services::omo::SLIM,
|
||||
)?;
|
||||
}
|
||||
} else {
|
||||
remove_opencode_provider_from_live(id)?;
|
||||
@@ -507,8 +538,13 @@ impl ProviderService {
|
||||
.ok_or_else(|| AppError::Message(format!("供应商 {id} 不存在")))?;
|
||||
|
||||
if matches!(app_type, AppType::OpenCode) && provider.category.as_deref() == Some("omo") {
|
||||
state.db.set_omo_provider_current(app_type.as_str(), id)?;
|
||||
crate::services::OmoService::write_config_to_file(state)?;
|
||||
state
|
||||
.db
|
||||
.set_omo_provider_current(app_type.as_str(), id, "omo")?;
|
||||
crate::services::OmoService::write_config_to_file(
|
||||
state,
|
||||
&crate::services::omo::STANDARD,
|
||||
)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -516,8 +552,8 @@ impl ProviderService {
|
||||
{
|
||||
state
|
||||
.db
|
||||
.set_omo_slim_provider_current(app_type.as_str(), id)?;
|
||||
crate::services::OmoService::write_config_to_file_slim(state)?;
|
||||
.set_omo_provider_current(app_type.as_str(), id, "omo-slim")?;
|
||||
crate::services::OmoService::write_config_to_file(state, &crate::services::omo::SLIM)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { OpenCodeModel, OpenCodeProviderConfig } from "@/types";
|
||||
import type { OmoGlobalConfig } from "@/types/omo";
|
||||
import { parseOmoOtherFieldsObject } from "@/types/omo";
|
||||
import type { PricingModelSourceOption } from "../ProviderAdvancedConfig";
|
||||
|
||||
// ── Default configs ──────────────────────────────────────────────────
|
||||
@@ -132,28 +131,7 @@ export function toOpencodeExtraOptions(
|
||||
return extra;
|
||||
}
|
||||
|
||||
export function buildOmoProfilePreview(
|
||||
agents: Record<string, Record<string, unknown>>,
|
||||
categories: Record<string, Record<string, unknown>>,
|
||||
otherFieldsStr: string,
|
||||
): Record<string, unknown> {
|
||||
const profileOnly: Record<string, unknown> = {};
|
||||
if (Object.keys(agents).length > 0) {
|
||||
profileOnly.agents = agents;
|
||||
}
|
||||
if (Object.keys(categories).length > 0) {
|
||||
profileOnly.categories = categories;
|
||||
}
|
||||
if (otherFieldsStr.trim()) {
|
||||
try {
|
||||
const other = parseOmoOtherFieldsObject(otherFieldsStr);
|
||||
if (other) {
|
||||
Object.assign(profileOnly, other);
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
return profileOnly;
|
||||
}
|
||||
export { buildOmoProfilePreview } from "@/types/omo";
|
||||
|
||||
export const normalizePricingSource = (
|
||||
value?: string,
|
||||
|
||||
+134
-178
@@ -3,192 +3,148 @@ import { omoApi, omoSlimApi } from "@/lib/api/omo";
|
||||
import * as configApi from "@/lib/api/config";
|
||||
import type { OmoGlobalConfig } from "@/types/omo";
|
||||
|
||||
export const omoKeys = {
|
||||
all: ["omo"] as const,
|
||||
globalConfig: () => [...omoKeys.all, "global-config"] as const,
|
||||
currentProviderId: () => [...omoKeys.all, "current-provider-id"] as const,
|
||||
providerCount: () => [...omoKeys.all, "provider-count"] as const,
|
||||
};
|
||||
// ── Factory ────────────────────────────────────────────────────
|
||||
|
||||
function invalidateOmoQueries(queryClient: ReturnType<typeof useQueryClient>) {
|
||||
queryClient.invalidateQueries({ queryKey: omoKeys.globalConfig() });
|
||||
queryClient.invalidateQueries({ queryKey: ["providers"] });
|
||||
queryClient.invalidateQueries({ queryKey: omoKeys.currentProviderId() });
|
||||
queryClient.invalidateQueries({ queryKey: omoKeys.providerCount() });
|
||||
function createOmoQueryKeys(prefix: string) {
|
||||
return {
|
||||
all: [prefix] as const,
|
||||
globalConfig: () => [prefix, "global-config"] as const,
|
||||
currentProviderId: () => [prefix, "current-provider-id"] as const,
|
||||
providerCount: () => [prefix, "provider-count"] as const,
|
||||
};
|
||||
}
|
||||
|
||||
export function useOmoGlobalConfig(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: omoKeys.globalConfig(),
|
||||
enabled,
|
||||
queryFn: async (): Promise<OmoGlobalConfig> => {
|
||||
const raw = await configApi.getCommonConfigSnippet("omo");
|
||||
if (!raw) {
|
||||
return {
|
||||
id: "global",
|
||||
disabledAgents: [],
|
||||
disabledMcps: [],
|
||||
disabledHooks: [],
|
||||
disabledSkills: [],
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(raw) as OmoGlobalConfig;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
"[omo] invalid global config json, fallback to defaults",
|
||||
error,
|
||||
);
|
||||
return {
|
||||
id: "global",
|
||||
disabledAgents: [],
|
||||
disabledMcps: [],
|
||||
disabledHooks: [],
|
||||
disabledSkills: [],
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useCurrentOmoProviderId(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: omoKeys.currentProviderId(),
|
||||
queryFn: omoApi.getCurrentOmoProviderId,
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
|
||||
export function useOmoProviderCount(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: omoKeys.providerCount(),
|
||||
queryFn: omoApi.getOmoProviderCount,
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
|
||||
export function useSaveOmoGlobalConfig() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (input: OmoGlobalConfig) => {
|
||||
const jsonStr = JSON.stringify(input);
|
||||
await configApi.setCommonConfigSnippet("omo", jsonStr);
|
||||
},
|
||||
onSuccess: () => invalidateOmoQueries(queryClient),
|
||||
});
|
||||
}
|
||||
|
||||
export function useReadOmoLocalFile() {
|
||||
return useMutation({
|
||||
mutationFn: () => omoApi.readLocalFile(),
|
||||
});
|
||||
}
|
||||
|
||||
export function useDisableCurrentOmo() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: () => omoApi.disableCurrentOmo(),
|
||||
onSuccess: () => invalidateOmoQueries(queryClient),
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OMO Slim query hooks
|
||||
// ============================================================================
|
||||
|
||||
export const omoSlimKeys = {
|
||||
all: ["omo-slim"] as const,
|
||||
globalConfig: () => [...omoSlimKeys.all, "global-config"] as const,
|
||||
currentProviderId: () => [...omoSlimKeys.all, "current-provider-id"] as const,
|
||||
providerCount: () => [...omoSlimKeys.all, "provider-count"] as const,
|
||||
};
|
||||
|
||||
function invalidateOmoSlimQueries(
|
||||
queryClient: ReturnType<typeof useQueryClient>,
|
||||
function createOmoQueryHooks(
|
||||
variant: "omo" | "omo-slim",
|
||||
api: typeof omoApi | typeof omoSlimApi,
|
||||
) {
|
||||
queryClient.invalidateQueries({ queryKey: omoSlimKeys.globalConfig() });
|
||||
queryClient.invalidateQueries({ queryKey: ["providers"] });
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: omoSlimKeys.currentProviderId(),
|
||||
});
|
||||
queryClient.invalidateQueries({ queryKey: omoSlimKeys.providerCount() });
|
||||
const keys = createOmoQueryKeys(variant);
|
||||
const snippetKey = variant === "omo" ? "omo" : "omo_slim";
|
||||
|
||||
function invalidateAll(queryClient: ReturnType<typeof useQueryClient>) {
|
||||
queryClient.invalidateQueries({ queryKey: keys.globalConfig() });
|
||||
queryClient.invalidateQueries({ queryKey: ["providers"] });
|
||||
queryClient.invalidateQueries({ queryKey: keys.currentProviderId() });
|
||||
queryClient.invalidateQueries({ queryKey: keys.providerCount() });
|
||||
}
|
||||
|
||||
function useGlobalConfig(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: keys.globalConfig(),
|
||||
enabled,
|
||||
queryFn: async (): Promise<OmoGlobalConfig> => {
|
||||
const raw = await configApi.getCommonConfigSnippet(snippetKey);
|
||||
if (!raw) {
|
||||
return {
|
||||
id: "global",
|
||||
disabledAgents: [],
|
||||
disabledMcps: [],
|
||||
disabledHooks: [],
|
||||
disabledSkills: [],
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(raw) as OmoGlobalConfig;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
`[${variant}] invalid global config json, fallback to defaults`,
|
||||
error,
|
||||
);
|
||||
return {
|
||||
id: "global",
|
||||
disabledAgents: [],
|
||||
disabledMcps: [],
|
||||
disabledHooks: [],
|
||||
disabledSkills: [],
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function useCurrentProviderId(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: keys.currentProviderId(),
|
||||
queryFn:
|
||||
"getCurrentOmoProviderId" in api
|
||||
? (api as typeof omoApi).getCurrentOmoProviderId
|
||||
: (api as typeof omoSlimApi).getCurrentProviderId,
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
|
||||
function useProviderCount(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: keys.providerCount(),
|
||||
queryFn:
|
||||
"getOmoProviderCount" in api
|
||||
? (api as typeof omoApi).getOmoProviderCount
|
||||
: (api as typeof omoSlimApi).getProviderCount,
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
|
||||
function useSaveGlobalConfig() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (input: OmoGlobalConfig) => {
|
||||
const jsonStr = JSON.stringify(input);
|
||||
await configApi.setCommonConfigSnippet(snippetKey, jsonStr);
|
||||
},
|
||||
onSuccess: () => invalidateAll(queryClient),
|
||||
});
|
||||
}
|
||||
|
||||
function useReadLocalFile() {
|
||||
return useMutation({
|
||||
mutationFn: () => api.readLocalFile(),
|
||||
});
|
||||
}
|
||||
|
||||
function useDisableCurrent() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn:
|
||||
"disableCurrentOmo" in api
|
||||
? (api as typeof omoApi).disableCurrentOmo
|
||||
: (api as typeof omoSlimApi).disableCurrent,
|
||||
onSuccess: () => invalidateAll(queryClient),
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
keys,
|
||||
useGlobalConfig,
|
||||
useCurrentProviderId,
|
||||
useProviderCount,
|
||||
useSaveGlobalConfig,
|
||||
useReadLocalFile,
|
||||
useDisableCurrent,
|
||||
};
|
||||
}
|
||||
|
||||
export function useOmoSlimGlobalConfig(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: omoSlimKeys.globalConfig(),
|
||||
enabled,
|
||||
queryFn: async (): Promise<OmoGlobalConfig> => {
|
||||
const raw = await configApi.getCommonConfigSnippet("omo_slim");
|
||||
if (!raw) {
|
||||
return {
|
||||
id: "global",
|
||||
disabledAgents: [],
|
||||
disabledMcps: [],
|
||||
disabledHooks: [],
|
||||
disabledSkills: [],
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
try {
|
||||
return JSON.parse(raw) as OmoGlobalConfig;
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
"[omo-slim] invalid global config json, fallback to defaults",
|
||||
error,
|
||||
);
|
||||
return {
|
||||
id: "global",
|
||||
disabledAgents: [],
|
||||
disabledMcps: [],
|
||||
disabledHooks: [],
|
||||
disabledSkills: [],
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
// ── Instances ──────────────────────────────────────────────────
|
||||
|
||||
export function useCurrentOmoSlimProviderId(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: omoSlimKeys.currentProviderId(),
|
||||
queryFn: omoSlimApi.getCurrentProviderId,
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
const omoHooks = createOmoQueryHooks("omo", omoApi);
|
||||
const omoSlimHooks = createOmoQueryHooks("omo-slim", omoSlimApi);
|
||||
|
||||
export function useOmoSlimProviderCount(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: omoSlimKeys.providerCount(),
|
||||
queryFn: omoSlimApi.getProviderCount,
|
||||
enabled,
|
||||
});
|
||||
}
|
||||
// ── Backward-compatible exports ────────────────────────────────
|
||||
|
||||
export function useSaveOmoSlimGlobalConfig() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async (input: OmoGlobalConfig) => {
|
||||
const jsonStr = JSON.stringify(input);
|
||||
await configApi.setCommonConfigSnippet("omo_slim", jsonStr);
|
||||
},
|
||||
onSuccess: () => invalidateOmoSlimQueries(queryClient),
|
||||
});
|
||||
}
|
||||
export const omoKeys = omoHooks.keys;
|
||||
export const omoSlimKeys = omoSlimHooks.keys;
|
||||
|
||||
export function useReadOmoSlimLocalFile() {
|
||||
return useMutation({
|
||||
mutationFn: () => omoSlimApi.readLocalFile(),
|
||||
});
|
||||
}
|
||||
export const useOmoGlobalConfig = omoHooks.useGlobalConfig;
|
||||
export const useCurrentOmoProviderId = omoHooks.useCurrentProviderId;
|
||||
export const useOmoProviderCount = omoHooks.useProviderCount;
|
||||
export const useSaveOmoGlobalConfig = omoHooks.useSaveGlobalConfig;
|
||||
export const useReadOmoLocalFile = omoHooks.useReadLocalFile;
|
||||
export const useDisableCurrentOmo = omoHooks.useDisableCurrent;
|
||||
|
||||
export function useDisableCurrentOmoSlim() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: () => omoSlimApi.disableCurrent(),
|
||||
onSuccess: () => invalidateOmoSlimQueries(queryClient),
|
||||
});
|
||||
}
|
||||
export const useOmoSlimGlobalConfig = omoSlimHooks.useGlobalConfig;
|
||||
export const useCurrentOmoSlimProviderId = omoSlimHooks.useCurrentProviderId;
|
||||
export const useOmoSlimProviderCount = omoSlimHooks.useProviderCount;
|
||||
export const useSaveOmoSlimGlobalConfig = omoSlimHooks.useSaveGlobalConfig;
|
||||
export const useReadOmoSlimLocalFile = omoSlimHooks.useReadLocalFile;
|
||||
export const useDisableCurrentOmoSlim = omoSlimHooks.useDisableCurrent;
|
||||
|
||||
+62
-60
@@ -406,15 +406,22 @@ export const OMO_SLIM_DISABLEABLE_HOOKS = [
|
||||
export const OMO_SLIM_DEFAULT_SCHEMA_URL =
|
||||
"https://raw.githubusercontent.com/alvinunreal/oh-my-opencode-slim/master/assets/oh-my-opencode-slim.schema.json";
|
||||
|
||||
export function mergeOmoSlimConfigPreview(
|
||||
export function mergeOmoConfigPreview(
|
||||
global: OmoGlobalConfig | undefined,
|
||||
agents: Record<string, Record<string, unknown>>,
|
||||
categories: Record<string, Record<string, unknown>> | undefined,
|
||||
otherFieldsStr: string,
|
||||
options?: { slim?: boolean },
|
||||
): Record<string, unknown> {
|
||||
const result: Record<string, unknown> = {};
|
||||
const isSlim = options?.slim ?? false;
|
||||
|
||||
if (global) {
|
||||
if (global.schemaUrl) result["$schema"] = global.schemaUrl;
|
||||
|
||||
if (!isSlim) {
|
||||
if (global.sisyphusAgent) result["sisyphus_agent"] = global.sisyphusAgent;
|
||||
}
|
||||
if (global.disabledAgents?.length)
|
||||
result["disabled_agents"] = global.disabledAgents;
|
||||
if (global.disabledMcps?.length)
|
||||
@@ -422,6 +429,18 @@ export function mergeOmoSlimConfigPreview(
|
||||
if (global.disabledHooks?.length)
|
||||
result["disabled_hooks"] = global.disabledHooks;
|
||||
|
||||
if (!isSlim) {
|
||||
if (global.disabledSkills?.length)
|
||||
result["disabled_skills"] = global.disabledSkills;
|
||||
if (global.lsp) result["lsp"] = global.lsp;
|
||||
if (global.experimental) result["experimental"] = global.experimental;
|
||||
if (global.backgroundTask)
|
||||
result["background_task"] = global.backgroundTask;
|
||||
if (global.browserAutomationEngine)
|
||||
result["browser_automation_engine"] = global.browserAutomationEngine;
|
||||
if (global.claudeCode) result["claude_code"] = global.claudeCode;
|
||||
}
|
||||
|
||||
if (global.otherFields) {
|
||||
for (const [k, v] of Object.entries(global.otherFields)) {
|
||||
result[k] = v;
|
||||
@@ -430,6 +449,8 @@ export function mergeOmoSlimConfigPreview(
|
||||
}
|
||||
|
||||
if (Object.keys(agents).length > 0) result["agents"] = agents;
|
||||
if (!isSlim && categories && Object.keys(categories).length > 0)
|
||||
result["categories"] = categories;
|
||||
|
||||
try {
|
||||
const other = parseOmoOtherFieldsObject(otherFieldsStr);
|
||||
@@ -443,67 +464,48 @@ export function mergeOmoSlimConfigPreview(
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @deprecated Use mergeOmoConfigPreview with options.slim=true */
|
||||
export function mergeOmoSlimConfigPreview(
|
||||
global: OmoGlobalConfig | undefined,
|
||||
agents: Record<string, Record<string, unknown>>,
|
||||
otherFieldsStr: string,
|
||||
): Record<string, unknown> {
|
||||
return mergeOmoConfigPreview(global, agents, undefined, otherFieldsStr, {
|
||||
slim: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildOmoProfilePreview(
|
||||
agents: Record<string, Record<string, unknown>>,
|
||||
categories: Record<string, Record<string, unknown>> | undefined,
|
||||
otherFieldsStr: string,
|
||||
options?: { slim?: boolean },
|
||||
): Record<string, unknown> {
|
||||
const result: Record<string, unknown> = {};
|
||||
const isSlim = options?.slim ?? false;
|
||||
|
||||
if (Object.keys(agents).length > 0) result["agents"] = agents;
|
||||
if (!isSlim && categories && Object.keys(categories).length > 0)
|
||||
result["categories"] = categories;
|
||||
|
||||
try {
|
||||
const other = parseOmoOtherFieldsObject(otherFieldsStr);
|
||||
if (other) {
|
||||
for (const [k, v] of Object.entries(other)) {
|
||||
result[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @deprecated Use buildOmoProfilePreview with options.slim=true */
|
||||
export function buildOmoSlimProfilePreview(
|
||||
agents: Record<string, Record<string, unknown>>,
|
||||
otherFieldsStr: string,
|
||||
): Record<string, unknown> {
|
||||
const result: Record<string, unknown> = {};
|
||||
|
||||
if (Object.keys(agents).length > 0) result["agents"] = agents;
|
||||
|
||||
try {
|
||||
const other = parseOmoOtherFieldsObject(otherFieldsStr);
|
||||
if (other) {
|
||||
for (const [k, v] of Object.entries(other)) {
|
||||
result[k] = v;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function mergeOmoConfigPreview(
|
||||
global: OmoGlobalConfig,
|
||||
agents: Record<string, Record<string, unknown>>,
|
||||
categories: Record<string, Record<string, unknown>>,
|
||||
otherFieldsStr: string,
|
||||
): Record<string, unknown> {
|
||||
const result: Record<string, unknown> = {};
|
||||
|
||||
if (global.schemaUrl) result["$schema"] = global.schemaUrl;
|
||||
|
||||
if (global.sisyphusAgent) result["sisyphus_agent"] = global.sisyphusAgent;
|
||||
if (global.disabledAgents?.length)
|
||||
result["disabled_agents"] = global.disabledAgents;
|
||||
if (global.disabledMcps?.length)
|
||||
result["disabled_mcps"] = global.disabledMcps;
|
||||
if (global.disabledHooks?.length)
|
||||
result["disabled_hooks"] = global.disabledHooks;
|
||||
if (global.disabledSkills?.length)
|
||||
result["disabled_skills"] = global.disabledSkills;
|
||||
if (global.lsp) result["lsp"] = global.lsp;
|
||||
if (global.experimental) result["experimental"] = global.experimental;
|
||||
if (global.backgroundTask) result["background_task"] = global.backgroundTask;
|
||||
if (global.browserAutomationEngine)
|
||||
result["browser_automation_engine"] = global.browserAutomationEngine;
|
||||
if (global.claudeCode) result["claude_code"] = global.claudeCode;
|
||||
|
||||
if (global.otherFields) {
|
||||
for (const [k, v] of Object.entries(global.otherFields)) {
|
||||
result[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(agents).length > 0) result["agents"] = agents;
|
||||
if (Object.keys(categories).length > 0) result["categories"] = categories;
|
||||
try {
|
||||
const other = parseOmoOtherFieldsObject(otherFieldsStr);
|
||||
if (!other) return result;
|
||||
for (const [k, v] of Object.entries(other)) {
|
||||
result[k] = v;
|
||||
}
|
||||
} catch {}
|
||||
|
||||
return result;
|
||||
return buildOmoProfilePreview(agents, undefined, otherFieldsStr, {
|
||||
slim: true,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user