mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-15 03:41:55 +03:00
migrate AI tokens from the git-configuration to the keystore.
All AI related options are stored in the user-level git configuration file. Upon first access, they will be removed from there and placed into the keystore as part of the migration. The UI is provided with functions to store and save secrets which it will use specifically to interact with these keys. It's explicitly out of scope to *not* show the keys in plain-text anymore after entering them.
This commit is contained in:
parent
de00e4f049
commit
05506f49fa
@ -14,6 +14,7 @@ import {
|
||||
MessageRole,
|
||||
type Prompt
|
||||
} from '$lib/ai/types';
|
||||
import { invoke } from '$lib/backend/ipc';
|
||||
import { buildFailureFromAny, isFailure, ok, type Result } from '$lib/result';
|
||||
import { splitMessage } from '$lib/utils/commitMessage';
|
||||
import OpenAI from 'openai';
|
||||
@ -90,7 +91,17 @@ export class AIService {
|
||||
}
|
||||
|
||||
async getOpenAIKey() {
|
||||
return await this.gitConfig.get(GitAIConfigKey.OpenAIKey);
|
||||
const secretInConfig = await this.gitConfig.get(GitAIConfigKey.OpenAIKey);
|
||||
if (secretInConfig !== undefined) {
|
||||
await invoke('secret_set_global', {
|
||||
handle: 'aiOpenAIKey',
|
||||
secret: secretInConfig
|
||||
});
|
||||
await this.gitConfig.remove(GitAIConfigKey.OpenAIKey);
|
||||
return secretInConfig;
|
||||
} else {
|
||||
return await invoke('secret_get_global', { handle: 'aiOpenAIKey' });
|
||||
}
|
||||
}
|
||||
|
||||
async getOpenAIModleName() {
|
||||
@ -108,7 +119,17 @@ export class AIService {
|
||||
}
|
||||
|
||||
async getAnthropicKey() {
|
||||
return await this.gitConfig.get(GitAIConfigKey.AnthropicKey);
|
||||
const secretInConfig = await this.gitConfig.get(GitAIConfigKey.AnthropicKey);
|
||||
if (secretInConfig !== undefined) {
|
||||
await invoke('secret_set_global', {
|
||||
handle: 'aiAnthropicKey',
|
||||
secret: secretInConfig
|
||||
});
|
||||
await this.gitConfig.remove(GitAIConfigKey.AnthropicKey);
|
||||
return secretInConfig;
|
||||
} else {
|
||||
return await invoke('secret_get_global', { handle: 'aiAnthropicKey' });
|
||||
}
|
||||
}
|
||||
|
||||
async getAnthropicModelName() {
|
||||
|
@ -5,6 +5,10 @@ export class GitConfigService {
|
||||
return (await invoke<T | undefined>('git_get_global_config', { key })) || undefined;
|
||||
}
|
||||
|
||||
async remove(key: string): Promise<undefined> {
|
||||
return await invoke('git_remove_global_config', { key });
|
||||
}
|
||||
|
||||
async getWithDefault<T extends string>(key: string, defaultValue: T): Promise<T> {
|
||||
const value = await invoke<T | undefined>('git_get_global_config', { key });
|
||||
return value || defaultValue;
|
||||
|
@ -15,6 +15,7 @@
|
||||
import TextBox from '$lib/shared/TextBox.svelte';
|
||||
import { UserService } from '$lib/stores/user';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { invoke } from '@tauri-apps/api/tauri';
|
||||
import { onMount, tick } from 'svelte';
|
||||
|
||||
const gitConfigService = getContext(GitConfigService);
|
||||
@ -34,10 +35,17 @@
|
||||
let ollamaEndpoint: string | undefined;
|
||||
let ollamaModel: string | undefined;
|
||||
|
||||
function setConfiguration(key: GitAIConfigKey, value: string | undefined) {
|
||||
async function setConfiguration(key: GitAIConfigKey, value: string | undefined) {
|
||||
if (!initialized) return;
|
||||
|
||||
gitConfigService.set(key, value || '');
|
||||
if (key === GitAIConfigKey.OpenAIKey || key === GitAIConfigKey.AnthropicKey) {
|
||||
await invoke('secret_set_global', {
|
||||
handle: key.split('.')[1],
|
||||
secret: value
|
||||
});
|
||||
} else {
|
||||
gitConfigService.set(key, value || '');
|
||||
}
|
||||
}
|
||||
|
||||
$: setConfiguration(GitAIConfigKey.ModelProvider, modelKind);
|
||||
|
@ -79,6 +79,11 @@ impl App {
|
||||
Ok(value.to_string())
|
||||
}
|
||||
|
||||
pub fn git_remove_global_config(key: &str) -> Result<()> {
|
||||
let mut config = git2::Config::open_default()?;
|
||||
Ok(config.remove(key)?)
|
||||
}
|
||||
|
||||
pub fn git_get_global_config(key: &str) -> Result<Option<String>> {
|
||||
let config = git2::Config::open_default()?;
|
||||
let value = config.get_string(key);
|
||||
|
@ -103,6 +103,12 @@ pub async fn git_set_global_config(
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(err(Debug))]
|
||||
pub async fn git_remove_global_config(key: &str) -> Result<(), Error> {
|
||||
Ok(app::App::git_remove_global_config(key)?)
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(_handle), err(Debug))]
|
||||
pub async fn git_get_global_config(
|
||||
|
@ -27,9 +27,9 @@ pub mod github;
|
||||
pub mod keys;
|
||||
pub mod projects;
|
||||
pub mod remotes;
|
||||
pub mod secret;
|
||||
pub mod undo;
|
||||
pub mod users;
|
||||
pub mod virtual_branches;
|
||||
pub mod secret;
|
||||
|
||||
pub mod zip;
|
||||
|
@ -168,6 +168,7 @@ fn main() {
|
||||
commands::delete_all_data,
|
||||
commands::mark_resolved,
|
||||
commands::git_set_global_config,
|
||||
commands::git_remove_global_config,
|
||||
commands::git_get_global_config,
|
||||
commands::git_test_push,
|
||||
commands::git_test_fetch,
|
||||
|
Loading…
Reference in New Issue
Block a user