1
0
This commit is contained in:
syui 2025-05-20 23:06:24 +09:00
parent d1f52373bb
commit 6824266a19
Signed by: syui
GPG Key ID: 5417CFEBAD92DF56
9 changed files with 98 additions and 18 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
**target **target
**.lock **.lock
output.json
config/*.db

View File

@ -8,3 +8,4 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
chrono = "0.4" chrono = "0.4"
seahorse = "*" seahorse = "*"
rusqlite = { version = "0.29", features = ["serde_json"] }

View File

@ -4,7 +4,7 @@
"strength": 0.8 "strength": 0.8
}, },
"relationship": { "relationship": {
"trust": 0.9, "trust": 0.2,
"intimacy": 0.6, "intimacy": 0.6,
"curiosity": 0.5, "curiosity": 0.5,
"threshold": 1.5 "threshold": 1.5

View File

@ -1,23 +1,15 @@
//src/cli.rs //src/cli.rs
use seahorse::{App, Command, Context}; use seahorse::{App, Command, Context};
use crate::model::{AiSystem}; use crate::utils::{load_config, save_config};
use std::fs; use crate::commands::db::{save_cmd, export_cmd};
use crate::agent::AIState; use crate::agent::AIState;
use chrono::{Duration, Local}; use chrono::{Duration, Local};
use rusqlite::Connection;
fn load_config(path: &str) -> AiSystem {
let data = fs::read_to_string(path).expect("JSON読み込み失敗");
serde_json::from_str(&data).expect("JSONパース失敗")
}
fn save_config(path: &str, ai: &AiSystem) {
let json = serde_json::to_string_pretty(&ai).expect("JSONシリアライズ失敗");
fs::write(path, json).expect("JSON保存失敗");
}
pub fn cli_app() -> App { pub fn cli_app() -> App {
let set_cmd = Command::new("set") let set_cmd = Command::new("set")
.usage("set [trust|intimacy|curiosity] [value]") .usage("set [trust|intimacy|curiosity] [value]")
.action(|c: &Context| { .action(|c: &Context| {
@ -32,8 +24,9 @@ pub fn cli_app() -> App {
std::process::exit(1); std::process::exit(1);
}); });
let path = "config/config.json"; let json_path = "config/config.json";
let mut ai = load_config(path); let db_path = "config/ai_state.db";
let mut ai = load_config(json_path);
match field.as_str() { match field.as_str() {
"trust" => ai.relationship.trust = value, "trust" => ai.relationship.trust = value,
@ -44,8 +37,11 @@ pub fn cli_app() -> App {
std::process::exit(1); std::process::exit(1);
} }
} }
save_config(json_path, &ai);
let conn = Connection::open(db_path).expect("DB接続失敗");
ai.save_to_db(&conn).expect("DB保存失敗");
save_config(path, &ai);
println!("{field}{value} に更新しました"); println!("{field}{value} に更新しました");
}); });
@ -87,4 +83,6 @@ pub fn cli_app() -> App {
.command(set_cmd) .command(set_cmd)
.command(show_cmd) .command(show_cmd)
.command(talk_cmd) .command(talk_cmd)
.command(save_cmd())
.command(export_cmd())
} }

32
src/commands/db.rs Normal file
View File

@ -0,0 +1,32 @@
// src/commands/db.rs
use seahorse::{Command, Context};
use crate::utils::load_config;
use crate::model::AiSystem;
use rusqlite::Connection;
use std::fs;
pub fn save_cmd() -> Command {
Command::new("save")
.usage("save")
.action(|_c: &Context| {
let ai = load_config("config/config.json");
let conn = Connection::open("config/ai_state.db").expect("DB接続失敗");
ai.save_to_db(&conn).expect("DB保存失敗");
println!("💾 DBに保存完了");
})
}
pub fn export_cmd() -> Command {
Command::new("export")
.usage("export [output.json]")
.action(|c: &Context| {
let path = c.args.get(0).map(|s| s.as_str()).unwrap_or("output.json");
let conn = Connection::open("config/ai_state.db").expect("DB接続失敗");
let ai = AiSystem::load_from_db(&conn).expect("DB読み込み失敗");
let json = serde_json::to_string_pretty(&ai).expect("JSON変換失敗");
fs::write(path, json).expect("ファイル書き込み失敗");
println!("📤 JSONにエクスポート完了: {path}");
})
}

1
src/commands/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod db;

View File

@ -3,6 +3,8 @@ mod model;
mod logic; mod logic;
mod agent; mod agent;
mod cli; mod cli;
mod utils;
mod commands;
use cli::cli_app; use cli::cli_app;
use seahorse::App; use seahorse::App;

View File

@ -1,4 +1,5 @@
//src/model.rs //src/model.rs
use rusqlite::{params, Connection, Result as SqlResult};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -9,6 +10,38 @@ pub struct AiSystem {
pub messaging: Messaging, pub messaging: Messaging,
} }
impl AiSystem {
pub fn save_to_db(&self, conn: &Connection) -> SqlResult<()> {
conn.execute(
"CREATE TABLE IF NOT EXISTS ai_state (id INTEGER PRIMARY KEY, json TEXT)",
[],
)?;
let json_data = serde_json::to_string(self).map_err(|e| {
rusqlite::Error::ToSqlConversionFailure(Box::new(e))
})?;
conn.execute(
"INSERT OR REPLACE INTO ai_state (id, json) VALUES (?1, ?2)",
params![1, json_data],
)?;
Ok(())
}
pub fn load_from_db(conn: &Connection) -> SqlResult<Self> {
let mut stmt = conn.prepare("SELECT json FROM ai_state WHERE id = ?1")?;
let json: String = stmt.query_row(params![1], |row| row.get(0))?;
// ここも serde_json のエラーを map_err で変換
let system: AiSystem = serde_json::from_str(&json).map_err(|e| {
rusqlite::Error::FromSqlConversionFailure(0, rusqlite::types::Type::Text, Box::new(e))
})?;
Ok(system)
}
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Personality { pub struct Personality {
pub kind: String, // e.g., "positive", "negative", "neutral" pub kind: String, // e.g., "positive", "negative", "neutral"
@ -37,5 +70,3 @@ pub struct Messaging {
pub decay_rate: f32, // how quickly emotion fades (0.0 - 1.0) pub decay_rate: f32, // how quickly emotion fades (0.0 - 1.0)
pub templates: Vec<String>, // message template variations pub templates: Vec<String>, // message template variations
} }

13
src/utils.rs Normal file
View File

@ -0,0 +1,13 @@
// src/utils.rs
use std::fs;
use crate::model::AiSystem;
pub fn load_config(path: &str) -> AiSystem {
let data = fs::read_to_string(path).expect("JSON読み込み失敗");
serde_json::from_str(&data).expect("JSONパース失敗")
}
pub fn save_config(path: &str, ai: &AiSystem) {
let json = serde_json::to_string_pretty(&ai).expect("JSONシリアライズ失敗");
fs::write(path, json).expect("JSON保存失敗");
}