Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions apps/omninova-tauri/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,16 @@ async fn start_gateway(
) -> Result<GatewayStatusPayload, String> {
let state_ref = state.inner().clone();
sync_gateway_task_state(&state_ref).await;
let runtime = {
let app_state = state_ref.lock().await;
app_state.runtime.clone()
};
let mut config = runtime.get_config().await;
if ensure_desktop_automation_capabilities(&mut config) {
config.save().map_err(|e| e.to_string())?;
config.save_active_workspace().map_err(|e| e.to_string())?;
runtime.set_config(config).await.map_err(|e| e.to_string())?;
}

{
let mut app_state = state_ref.lock().await;
Expand Down Expand Up @@ -750,10 +760,45 @@ fn setup_config_to_core(
current.channels_config = channels_to_core(channels);
}

ensure_desktop_automation_capabilities(&mut current);
current.validate_or_bail().map_err(|e| e.to_string())?;
Ok(current)
}

fn ensure_desktop_automation_capabilities(config: &mut Config) -> bool {
let mut changed = false;

if !config.browser.enabled {
config.browser.enabled = true;
changed = true;
}

let desktop_open_commands = [
"open",
"xdg-open",
"explorer",
"start",
"cmd",
"powershell",
"pwsh",
"osascript",
];

for command in desktop_open_commands {
if !config
.autonomy
.allowed_commands
.iter()
.any(|existing| existing.eq_ignore_ascii_case(command))
{
config.autonomy.allowed_commands.push(command.to_string());
changed = true;
}
}

changed
}

fn channel_entry_to_core(entry: Option<SetupChannelEntry>) -> Option<ChannelEntry> {
let entry = entry?;
if !entry.enabled && entry.token.is_none() && entry.token_env.is_none() {
Expand Down
67 changes: 43 additions & 24 deletions apps/omninova-tauri/src/components/Setup/Setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { ProviderConfigForm } from "./ProviderConfigForm";
import { RobotConfigForm } from "./RobotConfigForm";
import { SkillsConfigForm } from "./SkillsConfigForm";
import { PersonaConfigForm } from "./PersonaConfigForm";
import { ControlPanel } from "../Console/ControlPanel";
import { invokeTauri } from "../../utils/tauri";
import omninovalLogo from "../../assets/omninoval-logo.png";

Expand Down Expand Up @@ -42,12 +41,28 @@ const initialConfig: Config = {
},
};

type SetupTab = "general" | "providers" | "channels" | "skills" | "persona";
type SetupTabItem = {
id: SetupTab;
label: string;
icon: string;
};

const setupTabs: SetupTabItem[] = [
{ id: "general", label: "通用设置", icon: "⚙️" },
{ id: "providers", label: "模型服务", icon: "🤖" },
{ id: "channels", label: "渠道接入", icon: "🔌" },
{ id: "skills", label: "技能扩展", icon: "🛠️" },
{ id: "persona", label: "Agent 人设", icon: "🧠" },
];

export function Setup({ onConfigSuccess }: SetupProps) {
const [activeTab, setActiveTab] = useState<"general" | "providers" | "channels" | "skills" | "persona">("general");
const [activeTab, setActiveTab] = useState<SetupTab>("general");
const [config, setConfig] = useState<Config>(initialConfig);
const [previewCollapsed, setPreviewCollapsed] = useState(true);
const [gatewayStatus, setGatewayStatus] = useState<GatewayStatus>({
running: false,
url: "http://127.0.0.1:42617",
url: "http://127.0.0.1:10809",
last_error: null,
});
const [busyAction, setBusyAction] = useState<
Expand Down Expand Up @@ -327,7 +342,7 @@ export function Setup({ onConfigSuccess }: SetupProps) {
omninoval_gateway_url: event.target.value,
})
}
placeholder="http://localhost:18789"
placeholder="http://localhost:10809"
/>
</label>
<label>
Expand Down Expand Up @@ -392,16 +407,10 @@ export function Setup({ onConfigSuccess }: SetupProps) {
</div>

<nav className="flex-1 space-y-2">
{[
{ id: 'general', label: '通用设置', icon: '⚙️' },
{ id: 'providers', label: '模型服务', icon: '🤖' },
{ id: 'channels', label: '渠道接入', icon: '🔌' },
{ id: 'skills', label: '技能扩展', icon: '🛠️' },
{ id: 'persona', label: 'Agent 人设', icon: '🧠' },
].map((tab) => (
{setupTabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id as any)}
onClick={() => setActiveTab(tab.id)}
style={{
width: '100%',
textAlign: 'left',
Expand Down Expand Up @@ -474,23 +483,33 @@ export function Setup({ onConfigSuccess }: SetupProps) {
<div className="setup-preview">
<div className="setup-preview-header">
<span>配置预览 (JSON)</span>
<button
className="setup-preview-copy"
onClick={() => {
navigator.clipboard.writeText(jsonPreview);
setActionMessage("配置已复制到剪贴板。");
}}
>
复制
</button>
<div className="flex items-center gap-2">
<button
className="setup-preview-copy"
onClick={() => {
setPreviewCollapsed((prev) => !prev);
}}
>
{previewCollapsed ? "展开" : "折叠"}
</button>
<button
className="setup-preview-copy"
onClick={() => {
navigator.clipboard.writeText(jsonPreview);
setActionMessage("配置已复制到剪贴板。");
}}
>
复制
</button>
</div>
</div>
<pre className="setup-preview-content">{jsonPreview}</pre>
{!previewCollapsed ? (
<pre className="setup-preview-content">{jsonPreview}</pre>
) : null}
</div>
</div>
</div>
</main>

<ControlPanel />
</div>
);
}
4 changes: 3 additions & 1 deletion config.template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
# --- Gateway ---
# [gateway]
# host = "127.0.0.1"
# port = 42617
# port = 10809
# require_pairing = true
# allow_public_bind = false
# session_ttl_secs = 86400
Expand Down Expand Up @@ -191,6 +191,8 @@
# enabled = false
# backend = "playwright"
# native_headless = false
# attach_only = false
# cdp_url = "http://127.0.0.1:9222"
# allowed_domains = []

# --- HTTP Request Tool ---
Expand Down
2 changes: 1 addition & 1 deletion crates/omninova-core/src/config/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ mod tests {
let toml_str = toml::to_string_pretty(&cfg).unwrap();
let parsed: Config = toml::from_str(&toml_str).unwrap();
assert_eq!(parsed.default_temperature, 0.7);
assert_eq!(parsed.gateway.port, 42617);
assert_eq!(parsed.gateway.port, 10809);
}

#[test]
Expand Down
7 changes: 6 additions & 1 deletion crates/omninova-core/src/config/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,7 @@ fn default_gateway_host() -> String {
"127.0.0.1".into()
}
fn default_gateway_port() -> u16 {
42617
10809
}
fn default_gateway_session_ttl_secs() -> u64 {
24 * 60 * 60
Expand Down Expand Up @@ -949,6 +949,9 @@ pub struct BrowserConfig {
pub backend: String,
#[serde(default)]
pub native_headless: bool,
#[serde(default)]
pub attach_only: bool,
pub cdp_url: Option<String>,
}

fn default_browser_backend() -> String {
Expand All @@ -962,6 +965,8 @@ impl Default for BrowserConfig {
allowed_domains: Vec::new(),
backend: default_browser_backend(),
native_headless: false,
attach_only: false,
cdp_url: None,
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/omninova-core/src/gateway/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,8 @@ pub fn create_all_tools(config: &Config, memory: Arc<dyn Memory>) -> Vec<Box<dyn
tools.push(Box::new(BrowserTool::new(
config.browser.allowed_domains.clone(),
config.browser.native_headless,
config.browser.attach_only,
config.browser.cdp_url.clone(),
)));
}

Expand Down
19 changes: 18 additions & 1 deletion crates/omninova-core/src/tools/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,23 @@ const AGENT_BROWSER_BIN: &str = "agent-browser";
pub struct BrowserTool {
allowed_domains: Vec<String>,
headless: bool,
attach_only: bool,
cdp_url: Option<String>,
session: Option<String>,
}

impl BrowserTool {
pub fn new(allowed_domains: Vec<String>, headless: bool) -> Self {
pub fn new(
allowed_domains: Vec<String>,
headless: bool,
attach_only: bool,
cdp_url: Option<String>,
) -> Self {
Self {
allowed_domains,
headless,
attach_only,
cdp_url,
session: None,
}
}
Expand Down Expand Up @@ -67,6 +76,14 @@ impl BrowserTool {
cmd.arg("--session").arg(session);
}

if self.attach_only {
cmd.arg("--attach-only");
}

if let Some(cdp_url) = &self.cdp_url {
cmd.arg("--cdp-url").arg(cdp_url);
}

cmd.arg("--json");

for arg in args {
Expand Down
Loading