Skip to content
Open
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
1 change: 1 addition & 0 deletions electron/main/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const scriptsDir = path.join(appDir, "scripts")
export const configDir = app.isPackaged ? path.join(appDir, "config") : path.join(process.cwd(), ".config")
export const hostCacheDir = path.join(appDir, "host_cache")
export const logDir = path.join(appDir, "log")
export const skillsDir = path.join(appDir, "skills")

export const binDirList = [
path.join(process.resourcesPath, "node"),
Expand Down
3 changes: 3 additions & 0 deletions electron/main/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
DEF_MCP_SERVER_NAME,
getDefMcpBinPath,
binDir,
appDir,
skillsDir,
} from "./constant.js"
import spawn from "cross-spawn"
import { ChildProcess, SpawnOptions, StdioOptions } from "node:child_process"
Expand Down Expand Up @@ -185,6 +187,7 @@ async function startHostService() {
...process.env,
DIVE_CONFIG_DIR: baseConfigDir,
RESOURCE_DIR: hostCacheDir,
DIVE_SKILL_DIR: skillsDir,
DIVE_USER_AGENT: `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Dive/${packageJson.version} (+https://github.com/OpenAgentPlatform/Dive)`,
}

Expand Down
4 changes: 3 additions & 1 deletion src-tauri/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tokio::{
io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter},
};

use crate::{dependency::{NODEJS_BIN_DIR, UV_BIN_DIR}, process::command::Command, shared::{DEF_MCP_BIN_NAME, VERSION}};
use crate::{dependency::NODEJS_BIN_DIR, process::command::Command, shared::{DEF_MCP_BIN_NAME, VERSION}};

pub const COMMAND_ALIAS_FILE: &str = "command_alias.json";
pub const CUSTOM_RULES_FILE: &str = "customrules";
Expand Down Expand Up @@ -134,6 +134,7 @@ impl HostProcess {
.env("PATH", crate::util::get_system_path().await)
.env("DIVE_CONFIG_DIR", dirs.config)
.env("RESOURCE_DIR", dirs.cache)
.env("DIVE_SKILL_DIR", dirs.skills)
.env("DIVE_USER_AGENT", format!("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Dive/{} (+https://github.com/OpenAgentPlatform/Dive)", VERSION))
.current_dir(dunce::simplified(cwd))
.stderr(Stdio::piped())
Expand All @@ -142,6 +143,7 @@ impl HostProcess {
// set bin path for builtin tools
#[cfg(not(debug_assertions))]
{
use crate::dependency::UV_BIN_DIR;
let uvx_path = if cfg!(windows) {
UV_BIN_DIR.join("uvx.exe")
} else {
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub static PROJECT_DIRS: LazyLock<Dirs> = LazyLock::new(|| {
bus: home.join(".dive/host_cache/bus"),
log: home.join(".dive/log"),
bin: home.join(".dive/bin"),
skills: home.join(".dive/skills"),

#[cfg(debug_assertions)]
config: std::env::current_dir().unwrap().join("../.config"),
Expand All @@ -54,4 +55,5 @@ pub struct Dirs {
pub bus: PathBuf,
pub log: PathBuf,
pub bin: PathBuf,
pub skills: PathBuf,
}
22 changes: 21 additions & 1 deletion src/atoms/configState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isLoggedInOAPAtom, OAPLevelAtom } from "./oapState"
import { OAP_PROXY_URL } from "../../shared/oap"
import { ModelGroupSetting, ModelProvider, ModelVerifyStatus } from "../../types/model"
import { modelSettingsAtom } from "./modelState"
import { defaultBaseModel, defaultModelGroup, intoRawModelConfig, intoRawModelConfigWithQuery, reverseQueryGroup } from "../helper/model"
import { defaultBaseModel, defaultModelGroup, GroupTerm, intoRawModelConfig, intoRawModelConfigWithQuery, ModelTerm, queryGroup, queryModel, reverseQueryGroup } from "../helper/model"
import { getVerifyKeyFromModelConfig } from "../helper/verify"
import { oapGetToken } from "../ipc"
import { fetchModels } from "../ipc/llm"
Expand Down Expand Up @@ -385,6 +385,26 @@ export const writeOapConfigAtom = atom(
}
)

export const selectModelAtom = atom(
null,
async (get, set, value: { group: GroupTerm, model: ModelTerm }) => {
const settings = get(modelSettingsAtom)
const group = queryGroup(value.group, settings.groups)
if (group.length === 0) {
throw new Error("Group not found")
}

const model = queryModel(value.model, group[0])
if (model.length === 0) {
throw new Error("Model not found")
}

const data = await set(writeRawConfigAtom, intoRawModelConfig(settings, group[0], model[0])!)
localStorage.setItem("selectedModel", JSON.stringify(value))
return data
}
)

export const reloadOapConfigAtom = atom(
null,
async (get, set) => {
Expand Down
25 changes: 23 additions & 2 deletions src/atoms/modelState.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { atom } from "jotai"
import { LLMGroup, ModelGroupSetting } from "../../types/model"
import { defaultModelGroupSetting, getGroupTerm, removeGroup, updateGroup } from "../helper/model"
import { LLMGroup, ModelGroupSetting, ModelProvider } from "../../types/model"
import { defaultModelGroupSetting, getGroupTerm, getModelNamePrefix, getModelTerm, GroupTerm, ModelTerm, removeGroup, updateGroup } from "../helper/model"

export const modelSettingsAtom = atom<ModelGroupSetting>(defaultModelGroupSetting())

Expand All @@ -24,6 +24,27 @@ export const disableModelGroupAtom = atom(
}
)

export interface ModelOption {
provider: ModelProvider
name: string
value: { group: GroupTerm, model: ModelTerm }
}

export const modelListAtom = atom<ModelOption[]>((get) => {
const settings = get(modelSettingsAtom)
return settings.groups
.filter(group => group.active)
.flatMap(group =>
group.models
.filter(m => m.active && m.verifyStatus !== "unSupportModel")
.map(m => ({
provider: group.modelProvider,
name: `${getModelNamePrefix(group) ?? ""}/${m.model}`,
value: { group: getGroupTerm(group), model: getModelTerm(m) }
}))
)
})

export const removeModelGroupAtom = atom(
null,
(get, set, group: LLMGroup) => {
Expand Down
16 changes: 16 additions & 0 deletions src/atoms/skillState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { atom } from "jotai"
import { fetchSkills, type Skill } from "../ipc/skills"

export type { Skill } from "../ipc/skills"

export const skillsAtom = atom<Skill[]>([])

export const loadSkillsAtom = atom(null, async (_get, set) => {
try {
const skills = await fetchSkills()
set(skillsAtom, skills)
} catch (error) {
console.error("Failed to load skills:", error)
set(skillsAtom, [])
}
})
Loading