From a6087665217a6d33007525c8b407ec6d02909e41 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 11:57:45 +0800 Subject: [PATCH 01/19] feat(assistant): add unified assistant storage foundation --- .../012_assistant_data_unification.sql | 94 ++++ crates/aionui-db/src/lib.rs | 25 +- crates/aionui-db/src/models/assistant.rs | 109 ++++ crates/aionui-db/src/models/mod.rs | 4 +- crates/aionui-db/src/repository/assistant.rs | 36 +- crates/aionui-db/src/repository/mod.rs | 10 +- .../src/repository/sqlite_assistant.rs | 491 +++++++++++++++++- .../assistant_data_unification_schema.rs | 50 ++ 8 files changed, 803 insertions(+), 16 deletions(-) create mode 100644 crates/aionui-db/migrations/012_assistant_data_unification.sql create mode 100644 crates/aionui-db/tests/assistant_data_unification_schema.rs diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql new file mode 100644 index 00000000..92f25f06 --- /dev/null +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -0,0 +1,94 @@ +-- Migration 012: assistant data unification +-- +-- Introduces the new assistant runtime storage: +-- - assistant_definitions +-- - assistant_states +-- - assistant_preferences +-- +-- Legacy tables `assistants` and `assistant_overrides` are intentionally kept +-- for downgrade compatibility and mirror projection. + +CREATE TABLE IF NOT EXISTS assistant_definitions ( + id TEXT PRIMARY KEY, + source TEXT NOT NULL + CHECK (source IN ('builtin', 'user', 'generated', 'extension')), + owner_type TEXT NOT NULL + CHECK (owner_type IN ('system', 'user', 'extension')), + source_ref TEXT, + source_version TEXT, + source_hash TEXT, + name TEXT NOT NULL, + name_i18n TEXT NOT NULL DEFAULT '{}', + description TEXT, + description_i18n TEXT NOT NULL DEFAULT '{}', + avatar TEXT, + agent_backend TEXT NOT NULL, + rule_resource_type TEXT NOT NULL + CHECK ( + rule_resource_type IN ( + 'none', + 'builtin_asset', + 'user_file', + 'inline', + 'extension' + ) + ), + rule_resource_ref TEXT, + rule_inline_content TEXT, + recommended_prompts TEXT NOT NULL DEFAULT '[]', + recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', + default_model_mode TEXT NOT NULL + CHECK (default_model_mode IN ('auto', 'fixed')), + default_model_value TEXT, + default_permission_mode TEXT NOT NULL + CHECK (default_permission_mode IN ('auto', 'fixed')), + default_permission_value TEXT, + default_skills_mode TEXT NOT NULL + CHECK (default_skills_mode IN ('auto', 'fixed')), + default_skill_ids TEXT NOT NULL DEFAULT '[]', + default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + default_mcps_mode TEXT NOT NULL + CHECK (default_mcps_mode IN ('auto', 'fixed')), + default_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + deleted_at INTEGER +); + +CREATE UNIQUE INDEX IF NOT EXISTS idx_assistant_definitions_source_ref + ON assistant_definitions(source, source_ref) + WHERE source_ref IS NOT NULL; + +CREATE INDEX IF NOT EXISTS idx_assistant_definitions_source + ON assistant_definitions(source); + +CREATE INDEX IF NOT EXISTS idx_assistant_definitions_agent_backend + ON assistant_definitions(agent_backend); + +CREATE TABLE IF NOT EXISTS assistant_states ( + assistant_id TEXT PRIMARY KEY, + enabled INTEGER NOT NULL DEFAULT 1, + sort_order INTEGER NOT NULL DEFAULT 0, + last_used_at INTEGER, + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + FOREIGN KEY (assistant_id) REFERENCES assistant_definitions(id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_assistant_states_enabled + ON assistant_states(enabled); + +CREATE INDEX IF NOT EXISTS idx_assistant_states_sort_order + ON assistant_states(sort_order); + +CREATE TABLE IF NOT EXISTS assistant_preferences ( + assistant_id TEXT PRIMARY KEY, + last_model_id TEXT, + last_permission_value TEXT, + last_skill_ids TEXT NOT NULL DEFAULT '[]', + last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + last_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + FOREIGN KEY (assistant_id) REFERENCES assistant_definitions(id) ON DELETE CASCADE +); diff --git a/crates/aionui-db/src/lib.rs b/crates/aionui-db/src/lib.rs index 214720de..49a262ea 100644 --- a/crates/aionui-db/src/lib.rs +++ b/crates/aionui-db/src/lib.rs @@ -11,8 +11,10 @@ pub use database::{ }; pub use error::DbError; pub use models::{ - AgentMetadataRow, AssistantOverrideRow, AssistantRow, ConversationArtifactRow, CreateAssistantParams, - UpdateAgentHandshakeParams, UpdateAssistantParams, UpsertAgentMetadataParams, UpsertOverrideParams, + AgentMetadataRow, AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, + AssistantStateRow, ConversationArtifactRow, CreateAssistantParams, UpdateAgentHandshakeParams, + UpdateAssistantParams, UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, + UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, }; pub use repository::channel::UpdatePluginStatusParams; pub use repository::conversation::{ @@ -25,14 +27,17 @@ pub use repository::provider::{CreateProviderParams, UpdateProviderParams}; pub use repository::remote_agent::{CreateRemoteAgentParams, UpdateRemoteAgentParams}; pub use repository::team::{UpdateTaskParams, UpdateTeamParams}; pub use repository::{ - CreateAcpSessionParams, IAcpSessionRepository, IAgentMetadataRepository, IAssistantOverrideRepository, - IAssistantRepository, IChannelRepository, IClientPreferenceRepository, IConversationRepository, ICronRepository, - IMcpServerRepository, IOAuthTokenRepository, IProviderRepository, IRemoteAgentRepository, ISettingsRepository, - ITeamRepository, IUserRepository, PersistedSessionState, SaveRuntimeStateParams, SqliteAcpSessionRepository, - SqliteAgentMetadataRepository, SqliteAssistantOverrideRepository, SqliteAssistantRepository, - SqliteChannelRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, SqliteCronRepository, - SqliteMcpServerRepository, SqliteOAuthTokenRepository, SqliteProviderRepository, SqliteRemoteAgentRepository, - SqliteSettingsRepository, SqliteTeamRepository, SqliteUserRepository, + CreateAcpSessionParams, IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, + IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, + IChannelRepository, IClientPreferenceRepository, IConversationRepository, ICronRepository, + IMcpServerRepository, IOAuthTokenRepository, IProviderRepository, IRemoteAgentRepository, + ISettingsRepository, ITeamRepository, IUserRepository, PersistedSessionState, SaveRuntimeStateParams, + SqliteAcpSessionRepository, SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, + SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, + SqliteAssistantStateRepository, SqliteChannelRepository, SqliteClientPreferenceRepository, + SqliteConversationRepository, SqliteCronRepository, SqliteMcpServerRepository, SqliteOAuthTokenRepository, + SqliteProviderRepository, SqliteRemoteAgentRepository, SqliteSettingsRepository, SqliteTeamRepository, + SqliteUserRepository, rebuild_legacy_assistant_mirror, }; // Re-export sqlx pool type for downstream crates diff --git a/crates/aionui-db/src/models/assistant.rs b/crates/aionui-db/src/models/assistant.rs index 86d7b736..5e268dbe 100644 --- a/crates/aionui-db/src/models/assistant.rs +++ b/crates/aionui-db/src/models/assistant.rs @@ -42,6 +42,64 @@ pub struct AssistantOverrideRow { pub updated_at: TimestampMs, } +/// Row mapping for the `assistant_definitions` table. +#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] +pub struct AssistantDefinitionRow { + pub id: String, + pub source: String, + pub owner_type: String, + pub source_ref: Option, + pub source_version: Option, + pub source_hash: Option, + pub name: String, + pub name_i18n: String, + pub description: Option, + pub description_i18n: String, + pub avatar: Option, + pub agent_backend: String, + pub rule_resource_type: String, + pub rule_resource_ref: Option, + pub rule_inline_content: Option, + pub recommended_prompts: String, + pub recommended_prompts_i18n: String, + pub default_model_mode: String, + pub default_model_value: Option, + pub default_permission_mode: String, + pub default_permission_value: Option, + pub default_skills_mode: String, + pub default_skill_ids: String, + pub default_disabled_builtin_skill_ids: String, + pub default_mcps_mode: String, + pub default_mcp_ids: String, + pub created_at: TimestampMs, + pub updated_at: TimestampMs, + pub deleted_at: Option, +} + +/// Row mapping for the `assistant_states` table. +#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] +pub struct AssistantStateRow { + pub assistant_id: String, + pub enabled: bool, + pub sort_order: i32, + pub last_used_at: Option, + pub created_at: TimestampMs, + pub updated_at: TimestampMs, +} + +/// Row mapping for the `assistant_preferences` table. +#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] +pub struct AssistantPreferenceRow { + pub assistant_id: String, + pub last_model_id: Option, + pub last_permission_value: Option, + pub last_skill_ids: String, + pub last_disabled_builtin_skill_ids: String, + pub last_mcp_ids: String, + pub created_at: TimestampMs, + pub updated_at: TimestampMs, +} + /// Insert parameters for `IAssistantRepository::create` / `::upsert`. /// /// JSON fields are pre-serialized strings so the repository layer stays @@ -95,3 +153,54 @@ pub struct UpsertOverrideParams<'a> { pub last_used_at: Option, pub preset_agent_type: Option>, } + +/// Insert-or-update parameters for `assistant_definitions`. +#[derive(Debug, Clone)] +pub struct UpsertAssistantDefinitionParams<'a> { + pub id: &'a str, + pub source: &'a str, + pub owner_type: &'a str, + pub source_ref: Option<&'a str>, + pub source_version: Option<&'a str>, + pub source_hash: Option<&'a str>, + pub name: &'a str, + pub name_i18n: &'a str, + pub description: Option<&'a str>, + pub description_i18n: &'a str, + pub avatar: Option<&'a str>, + pub agent_backend: &'a str, + pub rule_resource_type: &'a str, + pub rule_resource_ref: Option<&'a str>, + pub rule_inline_content: Option<&'a str>, + pub recommended_prompts: &'a str, + pub recommended_prompts_i18n: &'a str, + pub default_model_mode: &'a str, + pub default_model_value: Option<&'a str>, + pub default_permission_mode: &'a str, + pub default_permission_value: Option<&'a str>, + pub default_skills_mode: &'a str, + pub default_skill_ids: &'a str, + pub default_disabled_builtin_skill_ids: &'a str, + pub default_mcps_mode: &'a str, + pub default_mcp_ids: &'a str, +} + +/// Insert-or-update parameters for `assistant_states`. +#[derive(Debug, Clone)] +pub struct UpsertAssistantStateParams<'a> { + pub assistant_id: &'a str, + pub enabled: bool, + pub sort_order: i32, + pub last_used_at: Option, +} + +/// Insert-or-update parameters for `assistant_preferences`. +#[derive(Debug, Clone)] +pub struct UpsertAssistantPreferenceParams<'a> { + pub assistant_id: &'a str, + pub last_model_id: Option<&'a str>, + pub last_permission_value: Option<&'a str>, + pub last_skill_ids: &'a str, + pub last_disabled_builtin_skill_ids: &'a str, + pub last_mcp_ids: &'a str, +} diff --git a/crates/aionui-db/src/models/mod.rs b/crates/aionui-db/src/models/mod.rs index 7e63dadc..152ca0b3 100644 --- a/crates/aionui-db/src/models/mod.rs +++ b/crates/aionui-db/src/models/mod.rs @@ -18,7 +18,9 @@ mod user; pub use acp_session::AcpSessionRow; pub use agent_metadata::{AgentMetadataRow, UpdateAgentHandshakeParams, UpsertAgentMetadataParams}; pub use assistant::{ - AssistantOverrideRow, AssistantRow, CreateAssistantParams, UpdateAssistantParams, UpsertOverrideParams, + AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, + UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, }; pub use channel::{AssistantSessionRow, AssistantUserRow, ChannelPluginRow, PairingCodeRow}; pub use client_preference::ClientPreference; diff --git a/crates/aionui-db/src/repository/assistant.rs b/crates/aionui-db/src/repository/assistant.rs index e90162de..5be5ae07 100644 --- a/crates/aionui-db/src/repository/assistant.rs +++ b/crates/aionui-db/src/repository/assistant.rs @@ -2,7 +2,9 @@ use crate::error::DbError; use crate::models::{ - AssistantOverrideRow, AssistantRow, CreateAssistantParams, UpdateAssistantParams, UpsertOverrideParams, + AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, + UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, }; /// CRUD access for user-authored assistant rows. @@ -53,3 +55,35 @@ pub trait IAssistantOverrideRepository: Send + Sync { /// Returns the number of rows deleted. async fn delete_orphans(&self, valid_ids: &[&str]) -> Result; } + +/// Runtime assistant definitions across builtin / user / generated / extension sources. +#[async_trait::async_trait] +pub trait IAssistantDefinitionRepository: Send + Sync { + async fn list(&self) -> Result, DbError>; + async fn get(&self, id: &str) -> Result, DbError>; + async fn upsert( + &self, + params: &UpsertAssistantDefinitionParams<'_>, + ) -> Result; + async fn soft_delete(&self, id: &str, deleted_at: i64) -> Result; +} + +/// Runtime assistant state used by the current app version. +#[async_trait::async_trait] +pub trait IAssistantStateRepository: Send + Sync { + async fn get(&self, assistant_id: &str) -> Result, DbError>; + async fn list(&self) -> Result, DbError>; + async fn upsert(&self, params: &UpsertAssistantStateParams<'_>) -> Result; + async fn delete(&self, assistant_id: &str) -> Result; +} + +/// Assistant-scoped "auto remember last" preferences. +#[async_trait::async_trait] +pub trait IAssistantPreferenceRepository: Send + Sync { + async fn get(&self, assistant_id: &str) -> Result, DbError>; + async fn upsert( + &self, + params: &UpsertAssistantPreferenceParams<'_>, + ) -> Result; + async fn delete(&self, assistant_id: &str) -> Result; +} diff --git a/crates/aionui-db/src/repository/mod.rs b/crates/aionui-db/src/repository/mod.rs index f7f67657..d0b8f4c3 100644 --- a/crates/aionui-db/src/repository/mod.rs +++ b/crates/aionui-db/src/repository/mod.rs @@ -29,7 +29,10 @@ mod user; pub use acp_session::{CreateAcpSessionParams, IAcpSessionRepository, PersistedSessionState, SaveRuntimeStateParams}; pub use agent_metadata::IAgentMetadataRepository; -pub use assistant::{IAssistantOverrideRepository, IAssistantRepository}; +pub use assistant::{ + IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, + IAssistantRepository, IAssistantStateRepository, +}; pub use channel::IChannelRepository; pub use client_preference::IClientPreferenceRepository; pub use conversation::IConversationRepository; @@ -41,7 +44,10 @@ pub use remote_agent::IRemoteAgentRepository; pub use settings::ISettingsRepository; pub use sqlite_acp_session::SqliteAcpSessionRepository; pub use sqlite_agent_metadata::SqliteAgentMetadataRepository; -pub use sqlite_assistant::{SqliteAssistantOverrideRepository, SqliteAssistantRepository}; +pub use sqlite_assistant::{ + SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, + SqliteAssistantRepository, SqliteAssistantStateRepository, rebuild_legacy_assistant_mirror, +}; pub use sqlite_channel::SqliteChannelRepository; pub use sqlite_client_preference::SqliteClientPreferenceRepository; pub use sqlite_conversation::SqliteConversationRepository; diff --git a/crates/aionui-db/src/repository/sqlite_assistant.rs b/crates/aionui-db/src/repository/sqlite_assistant.rs index 2297d57e..f5e6e50a 100644 --- a/crates/aionui-db/src/repository/sqlite_assistant.rs +++ b/crates/aionui-db/src/repository/sqlite_assistant.rs @@ -5,9 +5,14 @@ use sqlx::SqlitePool; use crate::error::DbError; use crate::models::{ - AssistantOverrideRow, AssistantRow, CreateAssistantParams, UpdateAssistantParams, UpsertOverrideParams, + AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, + UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, +}; +use crate::repository::assistant::{ + IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, + IAssistantStateRepository, }; -use crate::repository::assistant::{IAssistantOverrideRepository, IAssistantRepository}; /// SQLite-backed implementation of [`IAssistantRepository`]. #[derive(Clone, Debug)] @@ -228,6 +233,42 @@ pub struct SqliteAssistantOverrideRepository { pool: SqlitePool, } +/// SQLite-backed implementation of [`IAssistantDefinitionRepository`]. +#[derive(Clone, Debug)] +pub struct SqliteAssistantDefinitionRepository { + pool: SqlitePool, +} + +impl SqliteAssistantDefinitionRepository { + pub fn new(pool: SqlitePool) -> Self { + Self { pool } + } +} + +/// SQLite-backed implementation of [`IAssistantStateRepository`]. +#[derive(Clone, Debug)] +pub struct SqliteAssistantStateRepository { + pool: SqlitePool, +} + +impl SqliteAssistantStateRepository { + pub fn new(pool: SqlitePool) -> Self { + Self { pool } + } +} + +/// SQLite-backed implementation of [`IAssistantPreferenceRepository`]. +#[derive(Clone, Debug)] +pub struct SqliteAssistantPreferenceRepository { + pool: SqlitePool, +} + +impl SqliteAssistantPreferenceRepository { + pub fn new(pool: SqlitePool) -> Self { + Self { pool } + } +} + impl SqliteAssistantOverrideRepository { pub fn new(pool: SqlitePool) -> Self { Self { pool } @@ -322,6 +363,319 @@ impl IAssistantOverrideRepository for SqliteAssistantOverrideRepository { } } +#[async_trait::async_trait] +impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { + async fn list(&self) -> Result, DbError> { + let rows = sqlx::query_as::<_, AssistantDefinitionRow>( + "SELECT * FROM assistant_definitions WHERE deleted_at IS NULL ORDER BY updated_at DESC", + ) + .fetch_all(&self.pool) + .await?; + Ok(rows) + } + + async fn get(&self, id: &str) -> Result, DbError> { + let row = sqlx::query_as::<_, AssistantDefinitionRow>( + "SELECT * FROM assistant_definitions WHERE id = ? AND deleted_at IS NULL", + ) + .bind(id) + .fetch_optional(&self.pool) + .await?; + Ok(row) + } + + async fn upsert( + &self, + params: &UpsertAssistantDefinitionParams<'_>, + ) -> Result { + let now = now_ms(); + + sqlx::query( + "INSERT INTO assistant_definitions ( + id, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, + default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, + created_at, updated_at, deleted_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL) + ON CONFLICT(id) DO UPDATE SET + source = excluded.source, + owner_type = excluded.owner_type, + source_ref = excluded.source_ref, + source_version = excluded.source_version, + source_hash = excluded.source_hash, + name = excluded.name, + name_i18n = excluded.name_i18n, + description = excluded.description, + description_i18n = excluded.description_i18n, + avatar = excluded.avatar, + agent_backend = excluded.agent_backend, + rule_resource_type = excluded.rule_resource_type, + rule_resource_ref = excluded.rule_resource_ref, + rule_inline_content = excluded.rule_inline_content, + recommended_prompts = excluded.recommended_prompts, + recommended_prompts_i18n = excluded.recommended_prompts_i18n, + default_model_mode = excluded.default_model_mode, + default_model_value = excluded.default_model_value, + default_permission_mode = excluded.default_permission_mode, + default_permission_value = excluded.default_permission_value, + default_skills_mode = excluded.default_skills_mode, + default_skill_ids = excluded.default_skill_ids, + default_disabled_builtin_skill_ids = excluded.default_disabled_builtin_skill_ids, + default_mcps_mode = excluded.default_mcps_mode, + default_mcp_ids = excluded.default_mcp_ids, + updated_at = excluded.updated_at, + deleted_at = NULL", + ) + .bind(params.id) + .bind(params.source) + .bind(params.owner_type) + .bind(params.source_ref) + .bind(params.source_version) + .bind(params.source_hash) + .bind(params.name) + .bind(params.name_i18n) + .bind(params.description) + .bind(params.description_i18n) + .bind(params.avatar) + .bind(params.agent_backend) + .bind(params.rule_resource_type) + .bind(params.rule_resource_ref) + .bind(params.rule_inline_content) + .bind(params.recommended_prompts) + .bind(params.recommended_prompts_i18n) + .bind(params.default_model_mode) + .bind(params.default_model_value) + .bind(params.default_permission_mode) + .bind(params.default_permission_value) + .bind(params.default_skills_mode) + .bind(params.default_skill_ids) + .bind(params.default_disabled_builtin_skill_ids) + .bind(params.default_mcps_mode) + .bind(params.default_mcp_ids) + .bind(now) + .bind(now) + .execute(&self.pool) + .await?; + + self.get(params.id) + .await? + .ok_or_else(|| DbError::Init(format!("upsert did not produce definition row for id '{}'", params.id))) + } + + async fn soft_delete(&self, id: &str, deleted_at: i64) -> Result { + let result = sqlx::query( + "UPDATE assistant_definitions SET deleted_at = ?, updated_at = ? WHERE id = ? AND deleted_at IS NULL", + ) + .bind(deleted_at) + .bind(now_ms()) + .bind(id) + .execute(&self.pool) + .await?; + Ok(result.rows_affected() > 0) + } +} + +#[async_trait::async_trait] +impl IAssistantStateRepository for SqliteAssistantStateRepository { + async fn get(&self, assistant_id: &str) -> Result, DbError> { + let row = sqlx::query_as::<_, AssistantStateRow>("SELECT * FROM assistant_states WHERE assistant_id = ?") + .bind(assistant_id) + .fetch_optional(&self.pool) + .await?; + Ok(row) + } + + async fn list(&self) -> Result, DbError> { + let rows = sqlx::query_as::<_, AssistantStateRow>("SELECT * FROM assistant_states ORDER BY sort_order, updated_at") + .fetch_all(&self.pool) + .await?; + Ok(rows) + } + + async fn upsert(&self, params: &UpsertAssistantStateParams<'_>) -> Result { + let now = now_ms(); + sqlx::query( + "INSERT INTO assistant_states (assistant_id, enabled, sort_order, last_used_at, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?) + ON CONFLICT(assistant_id) DO UPDATE SET + enabled = excluded.enabled, + sort_order = excluded.sort_order, + last_used_at = excluded.last_used_at, + updated_at = excluded.updated_at", + ) + .bind(params.assistant_id) + .bind(params.enabled) + .bind(params.sort_order) + .bind(params.last_used_at) + .bind(now) + .bind(now) + .execute(&self.pool) + .await?; + + self.get(params.assistant_id) + .await? + .ok_or_else(|| DbError::Init(format!("upsert did not produce state row for id '{}'", params.assistant_id))) + } + + async fn delete(&self, assistant_id: &str) -> Result { + let result = sqlx::query("DELETE FROM assistant_states WHERE assistant_id = ?") + .bind(assistant_id) + .execute(&self.pool) + .await?; + Ok(result.rows_affected() > 0) + } +} + +#[async_trait::async_trait] +impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { + async fn get(&self, assistant_id: &str) -> Result, DbError> { + let row = + sqlx::query_as::<_, AssistantPreferenceRow>("SELECT * FROM assistant_preferences WHERE assistant_id = ?") + .bind(assistant_id) + .fetch_optional(&self.pool) + .await?; + Ok(row) + } + + async fn upsert( + &self, + params: &UpsertAssistantPreferenceParams<'_>, + ) -> Result { + let now = now_ms(); + sqlx::query( + "INSERT INTO assistant_preferences ( + assistant_id, last_model_id, last_permission_value, last_skill_ids, + last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(assistant_id) DO UPDATE SET + last_model_id = excluded.last_model_id, + last_permission_value = excluded.last_permission_value, + last_skill_ids = excluded.last_skill_ids, + last_disabled_builtin_skill_ids = excluded.last_disabled_builtin_skill_ids, + last_mcp_ids = excluded.last_mcp_ids, + updated_at = excluded.updated_at", + ) + .bind(params.assistant_id) + .bind(params.last_model_id) + .bind(params.last_permission_value) + .bind(params.last_skill_ids) + .bind(params.last_disabled_builtin_skill_ids) + .bind(params.last_mcp_ids) + .bind(now) + .bind(now) + .execute(&self.pool) + .await?; + + self.get(params.assistant_id).await?.ok_or_else(|| { + DbError::Init(format!( + "upsert did not produce preference row for id '{}'", + params.assistant_id + )) + }) + } + + async fn delete(&self, assistant_id: &str) -> Result { + let result = sqlx::query("DELETE FROM assistant_preferences WHERE assistant_id = ?") + .bind(assistant_id) + .execute(&self.pool) + .await?; + Ok(result.rows_affected() > 0) + } +} + +pub async fn rebuild_legacy_assistant_mirror( + pool: &SqlitePool, + definition: &AssistantDefinitionRow, + state: Option<&AssistantStateRow>, +) -> Result<(), DbError> { + let prompts = normalize_json_array(Some(definition.recommended_prompts.as_str())); + let default_skills = normalize_json_array(Some(definition.default_skill_ids.as_str())); + let disabled_builtin = normalize_json_array(Some(definition.default_disabled_builtin_skill_ids.as_str())); + let models = match ( + definition.default_model_mode.as_str(), + definition.default_model_value.as_deref(), + ) { + ("fixed", Some(model)) => serde_json::to_string(&vec![model]).unwrap_or_else(|_| "[]".to_string()), + _ => "[]".to_string(), + }; + + sqlx::query( + "INSERT INTO assistants ( + id, name, description, avatar, preset_agent_type, enabled_skills, + custom_skill_names, disabled_builtin_skills, prompts, models, + name_i18n, description_i18n, prompts_i18n, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(id) DO UPDATE SET + name = excluded.name, + description = excluded.description, + avatar = excluded.avatar, + preset_agent_type = excluded.preset_agent_type, + enabled_skills = excluded.enabled_skills, + custom_skill_names = excluded.custom_skill_names, + disabled_builtin_skills = excluded.disabled_builtin_skills, + prompts = excluded.prompts, + models = excluded.models, + name_i18n = excluded.name_i18n, + description_i18n = excluded.description_i18n, + prompts_i18n = excluded.prompts_i18n, + updated_at = excluded.updated_at", + ) + .bind(&definition.id) + .bind(&definition.name) + .bind(&definition.description) + .bind(&definition.avatar) + .bind(&definition.agent_backend) + .bind(&default_skills) + .bind("[]") + .bind(&disabled_builtin) + .bind(&prompts) + .bind(&models) + .bind(&definition.name_i18n) + .bind(&definition.description_i18n) + .bind(&definition.recommended_prompts_i18n) + .bind(definition.created_at) + .bind(definition.updated_at) + .execute(pool) + .await?; + + let enabled = state.map(|row| row.enabled).unwrap_or(true); + let sort_order = state.map(|row| row.sort_order).unwrap_or_default(); + let last_used_at = state.and_then(|row| row.last_used_at); + + sqlx::query( + "INSERT INTO assistant_overrides (assistant_id, enabled, sort_order, preset_agent_type, last_used_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?) + ON CONFLICT(assistant_id) DO UPDATE SET + enabled = excluded.enabled, + sort_order = excluded.sort_order, + preset_agent_type = excluded.preset_agent_type, + last_used_at = excluded.last_used_at, + updated_at = excluded.updated_at", + ) + .bind(&definition.id) + .bind(enabled) + .bind(sort_order) + .bind::>(None) + .bind(last_used_at) + .bind(state.map(|row| row.updated_at).unwrap_or(definition.updated_at)) + .execute(pool) + .await?; + + Ok(()) +} + +fn normalize_json_array(raw: Option<&str>) -> String { + match raw { + Some(value) if !value.trim().is_empty() => value.to_string(), + _ => "[]".to_string(), + } +} + // --------------------------------------------------------------------------- // Unit tests // --------------------------------------------------------------------------- @@ -342,6 +696,19 @@ mod tests { (a, o, db) } + async fn setup_v2() -> ( + SqliteAssistantDefinitionRepository, + SqliteAssistantStateRepository, + SqliteAssistantPreferenceRepository, + crate::Database, + ) { + let db = init_database_memory().await.unwrap(); + let d = SqliteAssistantDefinitionRepository::new(db.pool().clone()); + let s = SqliteAssistantStateRepository::new(db.pool().clone()); + let p = SqliteAssistantPreferenceRepository::new(db.pool().clone()); + (d, s, p, db) + } + fn params<'a>(id: &'a str, name: &'a str) -> CreateAssistantParams<'a> { CreateAssistantParams { id, @@ -360,6 +727,37 @@ mod tests { } } + fn definition_params<'a>(id: &'a str, name: &'a str) -> UpsertAssistantDefinitionParams<'a> { + UpsertAssistantDefinitionParams { + id, + source: "user", + owner_type: "user", + source_ref: Some(id), + source_version: None, + source_hash: None, + name, + name_i18n: r#"{"zh-CN":"助手"}"#, + description: Some("desc"), + description_i18n: "{}", + avatar: Some("🤖"), + agent_backend: "gemini", + rule_resource_type: "inline", + rule_resource_ref: None, + rule_inline_content: Some("# rule"), + recommended_prompts: r#"["hello"]"#, + recommended_prompts_i18n: "{}", + default_model_mode: "auto", + default_model_value: None, + default_permission_mode: "fixed", + default_permission_value: Some("workspace-write"), + default_skills_mode: "fixed", + default_skill_ids: r#"["pdf","cron"]"#, + default_disabled_builtin_skill_ids: r#"["todo-tracker"]"#, + default_mcps_mode: "auto", + default_mcp_ids: "[]", + } + } + #[tokio::test] async fn assistant_list_empty() { let (a, _o, _db) = setup().await; @@ -619,4 +1017,93 @@ mod tests { assert_eq!(removed, 1); assert!(o.get_all().await.unwrap().is_empty()); } + + #[tokio::test] + async fn definition_upsert_then_get() { + let (d, _s, _p, _db) = setup_v2().await; + let row = d.upsert(&definition_params("u1", "User One")).await.unwrap(); + assert_eq!(row.id, "u1"); + assert_eq!(row.source, "user"); + assert_eq!(row.default_permission_mode, "fixed"); + + let fetched = d.get("u1").await.unwrap().unwrap(); + assert_eq!(fetched.name, "User One"); + assert_eq!(fetched.rule_inline_content.as_deref(), Some("# rule")); + } + + #[tokio::test] + async fn state_upsert_then_list() { + let (d, s, _p, _db) = setup_v2().await; + d.upsert(&definition_params("u1", "User One")).await.unwrap(); + s.upsert(&UpsertAssistantStateParams { + assistant_id: "u1", + enabled: false, + sort_order: 9, + last_used_at: Some(1234), + }) + .await + .unwrap(); + + let list = s.list().await.unwrap(); + assert_eq!(list.len(), 1); + assert_eq!(list[0].assistant_id, "u1"); + assert!(!list[0].enabled); + assert_eq!(list[0].sort_order, 9); + } + + #[tokio::test] + async fn preference_upsert_then_get() { + let (d, _s, p, _db) = setup_v2().await; + d.upsert(&definition_params("u1", "User One")).await.unwrap(); + let row = p + .upsert(&UpsertAssistantPreferenceParams { + assistant_id: "u1", + last_model_id: Some("gpt-4.1"), + last_permission_value: Some("workspace-write"), + last_skill_ids: r#"["pdf"]"#, + last_disabled_builtin_skill_ids: r#"["todo-tracker"]"#, + last_mcp_ids: r#"["mcp-1"]"#, + }) + .await + .unwrap(); + assert_eq!(row.last_model_id.as_deref(), Some("gpt-4.1")); + + let fetched = p.get("u1").await.unwrap().unwrap(); + assert_eq!(fetched.last_skill_ids, r#"["pdf"]"#); + } + + #[tokio::test] + async fn rebuild_legacy_mirror_creates_legacy_rows() { + let (d, s, _p, db) = setup_v2().await; + let definition = d.upsert(&definition_params("u1", "User One")).await.unwrap(); + let state = s + .upsert(&UpsertAssistantStateParams { + assistant_id: "u1", + enabled: false, + sort_order: 7, + last_used_at: Some(999), + }) + .await + .unwrap(); + + rebuild_legacy_assistant_mirror(db.pool(), &definition, Some(&state)) + .await + .unwrap(); + + let legacy_assistant = sqlx::query_as::<_, AssistantRow>("SELECT * FROM assistants WHERE id = 'u1'") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(legacy_assistant.preset_agent_type, "gemini"); + assert_eq!(legacy_assistant.enabled_skills.as_deref(), Some(r#"["pdf","cron"]"#)); + + let legacy_override = + sqlx::query_as::<_, AssistantOverrideRow>("SELECT * FROM assistant_overrides WHERE assistant_id = 'u1'") + .fetch_one(db.pool()) + .await + .unwrap(); + assert!(!legacy_override.enabled); + assert_eq!(legacy_override.sort_order, 7); + assert_eq!(legacy_override.last_used_at, Some(999)); + } } diff --git a/crates/aionui-db/tests/assistant_data_unification_schema.rs b/crates/aionui-db/tests/assistant_data_unification_schema.rs new file mode 100644 index 00000000..6a9853fe --- /dev/null +++ b/crates/aionui-db/tests/assistant_data_unification_schema.rs @@ -0,0 +1,50 @@ +use aionui_db::init_database_memory; + +#[tokio::test] +async fn migration_creates_assistant_unification_tables_and_keeps_legacy_tables() { + let db = init_database_memory().await.unwrap(); + + let table_names: Vec = sqlx::query_scalar( + "SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ( + 'assistant_definitions', + 'assistant_states', + 'assistant_preferences', + 'assistants', + 'assistant_overrides' + ) ORDER BY name", + ) + .fetch_all(db.pool()) + .await + .unwrap(); + + assert_eq!( + table_names, + vec![ + "assistant_definitions".to_string(), + "assistant_overrides".to_string(), + "assistant_preferences".to_string(), + "assistant_states".to_string(), + "assistants".to_string(), + ] + ); +} + +#[tokio::test] +async fn assistant_definition_table_has_expected_default_columns() { + let db = init_database_memory().await.unwrap(); + + let columns: Vec = sqlx::query_scalar("SELECT name FROM pragma_table_info('assistant_definitions')") + .fetch_all(db.pool()) + .await + .unwrap_or_default(); + + assert!( + !columns.is_empty(), + "assistant_definitions should exist before inspecting columns" + ); + + assert!(columns.iter().any(|name| name == "default_model_mode")); + assert!(columns.iter().any(|name| name == "default_permission_mode")); + assert!(columns.iter().any(|name| name == "default_skill_ids")); + assert!(columns.iter().any(|name| name == "default_mcp_ids")); +} From 2d7fe5d2baf3fe50904a2b377f287489b38ad859 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 12:08:04 +0800 Subject: [PATCH 02/19] feat(assistant): bootstrap unified assistant storage --- crates/aionui-app/src/router/state.rs | 29 +- crates/aionui-app/tests/assistants_e2e.rs | 30 +- crates/aionui-assistant/src/service.rs | 281 +++++++++++++++++- .../012_assistant_data_unification.sql | 1 + crates/aionui-db/src/models/assistant.rs | 2 + .../src/repository/sqlite_assistant.rs | 10 +- 6 files changed, 338 insertions(+), 15 deletions(-) diff --git a/crates/aionui-app/src/router/state.rs b/crates/aionui-app/src/router/state.rs index f54740aa..eedde2f2 100644 --- a/crates/aionui-app/src/router/state.rs +++ b/crates/aionui-app/src/router/state.rs @@ -13,9 +13,11 @@ use aionui_channel::ChannelRouterState; use aionui_conversation::{ConversationRouterState, ConversationService}; use aionui_cron::{CronEventEmitter, CronRouterState}; use aionui_db::{ - IAcpSessionRepository, IAgentMetadataRepository, IAssistantOverrideRepository, IAssistantRepository, - IProviderRepository, SqliteAcpSessionRepository, SqliteAgentMetadataRepository, SqliteAssistantOverrideRepository, - SqliteAssistantRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, + IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverrideRepository, + IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, IProviderRepository, + SqliteAcpSessionRepository, SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, + SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, + SqliteAssistantStateRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, SqliteProviderRepository, SqliteRemoteAgentRepository, SqliteSettingsRepository, }; use aionui_extension::{ @@ -188,6 +190,14 @@ pub async fn build_module_states( ); let assistant = build_assistant_state(services, ext_state.registry.clone()); + assistant + .service + .bootstrap_assistant_storage() + .await + .map_err(|error| { + RouterBuildError::new("router.assistant.bootstrap", "failed to bootstrap assistant storage") + .with_source(error) + })?; let cron = build_cron_state(services); cron.cron_service.init().await; tracing::info!( @@ -217,7 +227,7 @@ pub async fn build_module_states( ); let pool = services.database.pool().clone(); - let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(pool)); + let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(pool.clone())); let encryption_key = derive_encryption_key(&services.jwt_secret_raw); let agent_service = AgentService::new( services.agent_registry.clone(), @@ -278,13 +288,18 @@ pub async fn build_module_states( /// Build the default `AssistantRouterState` from application services. pub fn build_assistant_state(services: &AppServices, extension_registry: ExtensionRegistry) -> AssistantRouterState { let pool = services.database.pool().clone(); + let definition_repo: Arc = + Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone())); + let state_repo: Arc = Arc::new(SqliteAssistantStateRepository::new(pool.clone())); + let preference_repo: Arc = + Arc::new(SqliteAssistantPreferenceRepository::new(pool.clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(pool.clone())); let override_repo: Arc = Arc::new(SqliteAssistantOverrideRepository::new(pool.clone())); // Used by `AssistantService::resolve_default_agent_type` to infer a // working `preset_agent_type` from the configured provider list when // the caller does not supply one (ELECTRON-1J1 / 1KV). - let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(pool)); + let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(pool.clone())); let builtin = Arc::new(BuiltinAssistantRegistry::load()); // Pin user_data_dir to the runtime-resolved data directory so dev / // packaged / multi-instance launches all keep their assistant rule files @@ -292,6 +307,10 @@ pub fn build_assistant_state(services: &AppServices, extension_registry: Extensi // where dev wrote rules to the release `~/.aionui/` while the db lived // under `~/.aionui-dev/`). let service = Arc::new(AssistantService::new( + pool, + definition_repo, + state_repo, + preference_repo, repo, override_repo, provider_repo, diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index 99767dd2..6cde2182 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -16,8 +16,10 @@ use std::sync::Arc; use aionui_app::{AppConfig, AppServices, ModuleStates, build_module_states, create_router_with_states}; use aionui_assistant::{AssistantRouterState, AssistantService, BuiltinAssistantRegistry}; use aionui_db::{ - IAssistantOverrideRepository, IAssistantRepository, IProviderRepository, SqliteAssistantOverrideRepository, - SqliteAssistantRepository, SqliteProviderRepository, init_database_memory, + IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, + IAssistantRepository, IAssistantStateRepository, IProviderRepository, SqliteAssistantDefinitionRepository, + SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, + SqliteAssistantStateRepository, SqliteProviderRepository, init_database_memory, }; use aionui_extension::{ AssistantRuleDispatcher, ExtensionRegistry, ExtensionRouterState, ExtensionSource, ExtensionStateStore, @@ -132,6 +134,18 @@ async fn fixture() -> Fixture { let db = init_database_memory().await.unwrap(); let services = AppServices::from_config(db, &AppConfig::default()).await.unwrap(); let (mut states, _): (ModuleStates, _) = build_module_states(&services).await.expect("build module states"); + for table in [ + "assistant_preferences", + "assistant_states", + "assistant_definitions", + "assistant_overrides", + "assistants", + ] { + sqlx::query(&format!("DELETE FROM {table}")) + .execute(services.database.pool()) + .await + .unwrap(); + } // Replace the extension + hub + skill states with freshly-constructed // ones rooted at our temp dirs. The defaults built by @@ -181,10 +195,15 @@ async fn fixture() -> Fixture { // registry (pointing at $exe_dir/assets or dev fallback) and uses // `~/.aionui/` for user data — neither is appropriate for tests. let pool = services.database.pool().clone(); + let definition_repo: Arc = + Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone())); + let state_repo: Arc = Arc::new(SqliteAssistantStateRepository::new(pool.clone())); + let preference_repo: Arc = + Arc::new(SqliteAssistantPreferenceRepository::new(pool.clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(pool.clone())); let override_repo: Arc = Arc::new(SqliteAssistantOverrideRepository::new(pool.clone())); - let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(pool)); + let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(pool.clone())); // Seed an OpenAI-compatible provider so create / import calls without // an explicit `preset_agent_type` resolve to `"aionrs"` instead of // erroring out — mirroring a configured production setup. @@ -209,6 +228,10 @@ async fn fixture() -> Fixture { .expect("seed provider"); let builtin = Arc::new(BuiltinAssistantRegistry::load_from_dir(builtin_assets_dir.clone())); let service = Arc::new(AssistantService::new( + pool, + definition_repo, + state_repo, + preference_repo, repo, override_repo, provider_repo, @@ -216,6 +239,7 @@ async fn fixture() -> Fixture { registry, user_data_dir.clone(), )); + service.bootstrap_assistant_storage().await.unwrap(); states.assistant = AssistantRouterState { service: service.clone(), }; diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 7edc72b5..e0ff4ca1 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -11,8 +11,10 @@ use aionui_api_types::{ }; use aionui_common::now_ms; use aionui_db::{ - AssistantOverrideRow, AssistantRow, CreateAssistantParams, IAssistantOverrideRepository, IAssistantRepository, - IProviderRepository, UpdateAssistantParams, UpsertOverrideParams, + AssistantOverrideRow, AssistantRow, CreateAssistantParams, IAssistantDefinitionRepository, + IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, + IProviderRepository, SqlitePool, UpdateAssistantParams, UpsertAssistantDefinitionParams, + UpsertAssistantStateParams, UpsertOverrideParams, rebuild_legacy_assistant_mirror, }; use aionui_extension::{ AssistantClassifier, AssistantRuleDispatcher, ExtensionError, ExtensionRegistry, ResolvedAssistant, @@ -25,6 +27,10 @@ use crate::error::AssistantError; /// Aggregated business logic for `/api/assistants/*` and rule/skill dispatch. pub struct AssistantService { + pool: SqlitePool, + definition_repo: Arc, + state_repo: Arc, + _preference_repo: Arc, repo: Arc, override_repo: Arc, /// Used to infer a sane `preset_agent_type` default when the caller did @@ -56,6 +62,10 @@ impl AssistantService { /// resulting in `read_rule` returning empty in dev mode. Forcing the /// caller to pass a path makes the wiring explicit. pub fn new( + pool: SqlitePool, + definition_repo: Arc, + state_repo: Arc, + preference_repo: Arc, repo: Arc, override_repo: Arc, provider_repo: Arc, @@ -64,6 +74,10 @@ impl AssistantService { user_data_dir: PathBuf, ) -> Self { Self { + pool, + definition_repo, + state_repo, + _preference_repo: preference_repo, repo, override_repo, provider_repo, @@ -73,6 +87,186 @@ impl AssistantService { } } + /// Bootstrap unified assistant storage from builtin assets and the + /// legacy mirror tables. + pub async fn bootstrap_assistant_storage(&self) -> Result<(), AssistantError> { + self.materialize_builtin_definitions().await?; + self.sync_legacy_user_assistants_to_new_tables().await?; + self.sync_legacy_overrides_to_new_states().await?; + self.rebuild_legacy_mirror_from_new_tables().await?; + Ok(()) + } + + /// Materialize builtin assistants into `assistant_definitions`. + pub async fn materialize_builtin_definitions(&self) -> Result<(), AssistantError> { + for builtin in self.builtin.all() { + let recommended_prompts = serde_json::to_string(&builtin.prompts) + .map_err(|e| AssistantError::Internal(format!("encode builtin prompts: {e}")))?; + let recommended_prompts_i18n = serde_json::to_string(&builtin.prompts_i18n) + .map_err(|e| AssistantError::Internal(format!("encode builtin prompts i18n: {e}")))?; + let name_i18n = serde_json::to_string(&builtin.name_i18n) + .map_err(|e| AssistantError::Internal(format!("encode builtin name_i18n: {e}")))?; + let description_i18n = serde_json::to_string(&builtin.description_i18n) + .map_err(|e| AssistantError::Internal(format!("encode builtin description_i18n: {e}")))?; + let default_skill_ids = serde_json::to_string(&builtin.enabled_skills) + .map_err(|e| AssistantError::Internal(format!("encode builtin skills: {e}")))?; + let custom_skill_names = serde_json::to_string(&builtin.custom_skill_names) + .map_err(|e| AssistantError::Internal(format!("encode builtin custom skills: {e}")))?; + let default_disabled_builtin_skill_ids = + serde_json::to_string(&builtin.disabled_builtin_skills).map_err(|e| { + AssistantError::Internal(format!("encode builtin disabled skills: {e}")) + })?; + + self.definition_repo + .upsert(&UpsertAssistantDefinitionParams { + id: &builtin.id, + source: "builtin", + owner_type: "system", + source_ref: Some(&builtin.id), + source_version: None, + source_hash: None, + name: &builtin.name, + name_i18n: &name_i18n, + description: builtin.description.as_deref(), + description_i18n: &description_i18n, + avatar: builtin.avatar.as_deref(), + agent_backend: &builtin.preset_agent_type, + rule_resource_type: if builtin.rule_file.is_some() { + "builtin_asset" + } else { + "none" + }, + rule_resource_ref: builtin.rule_file.as_deref(), + rule_inline_content: None, + recommended_prompts: &recommended_prompts, + recommended_prompts_i18n: &recommended_prompts_i18n, + default_model_mode: "auto", + default_model_value: None, + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "fixed", + default_skill_ids: &default_skill_ids, + custom_skill_names: &custom_skill_names, + default_disabled_builtin_skill_ids: &default_disabled_builtin_skill_ids, + default_mcps_mode: "auto", + default_mcp_ids: "[]", + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert builtin definition: {e}")))?; + } + + Ok(()) + } + + async fn sync_legacy_user_assistants_to_new_tables(&self) -> Result<(), AssistantError> { + for row in self.repo.list().await? { + self.upsert_definition_from_legacy_user_row(&row).await?; + } + Ok(()) + } + + async fn sync_legacy_overrides_to_new_states(&self) -> Result<(), AssistantError> { + for override_row in self.override_repo.get_all().await? { + if self.definition_repo.get(&override_row.assistant_id).await?.is_none() { + warn!( + assistant_id = %override_row.assistant_id, + "skip syncing assistant override without unified definition" + ); + continue; + } + + self.state_repo + .upsert(&UpsertAssistantStateParams { + assistant_id: &override_row.assistant_id, + enabled: override_row.enabled, + sort_order: override_row.sort_order, + last_used_at: override_row.last_used_at, + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert assistant state: {e}")))?; + } + + Ok(()) + } + + async fn upsert_definition_from_legacy_user_row(&self, row: &AssistantRow) -> Result<(), AssistantError> { + let name_i18n = normalize_json_object_string(row.name_i18n.as_deref(), "name_i18n")?; + let description_i18n = + normalize_json_object_string(row.description_i18n.as_deref(), "description_i18n")?; + let recommended_prompts = normalize_json_array_string(row.prompts.as_deref(), "prompts")?; + let recommended_prompts_i18n = + normalize_json_map_of_arrays_string(row.prompts_i18n.as_deref(), "prompts_i18n")?; + let default_skill_ids = normalize_json_array_string(row.enabled_skills.as_deref(), "enabled_skills")?; + let custom_skill_names = + normalize_json_array_string(row.custom_skill_names.as_deref(), "custom_skill_names")?; + let default_disabled_builtin_skill_ids = + normalize_json_array_string(row.disabled_builtin_skills.as_deref(), "disabled_builtin_skills")?; + let models = decode_str_list(row.models.as_deref())?; + let (default_model_mode, default_model_value) = match models.first() { + Some(model) => ("fixed", Some(model.as_str())), + None => ("auto", None), + }; + + self.definition_repo + .upsert(&UpsertAssistantDefinitionParams { + id: &row.id, + source: "user", + owner_type: "user", + source_ref: Some(&row.id), + source_version: None, + source_hash: None, + name: &row.name, + name_i18n: &name_i18n, + description: row.description.as_deref(), + description_i18n: &description_i18n, + avatar: row.avatar.as_deref(), + agent_backend: &row.preset_agent_type, + rule_resource_type: "user_file", + rule_resource_ref: Some(&row.id), + rule_inline_content: None, + recommended_prompts: &recommended_prompts, + recommended_prompts_i18n: &recommended_prompts_i18n, + default_model_mode, + default_model_value, + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "fixed", + default_skill_ids: &default_skill_ids, + custom_skill_names: &custom_skill_names, + default_disabled_builtin_skill_ids: &default_disabled_builtin_skill_ids, + default_mcps_mode: "auto", + default_mcp_ids: "[]", + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert user definition: {e}")))?; + + Ok(()) + } + + /// Rebuild downgrade-compatibility mirror rows from the new assistant tables. + pub async fn rebuild_legacy_mirror_from_new_tables(&self) -> Result<(), AssistantError> { + let states = self + .state_repo + .list() + .await + .map_err(|e| AssistantError::Internal(format!("list assistant states: {e}")))?; + let state_map: HashMap = + states.into_iter().map(|state| (state.assistant_id.clone(), state)).collect(); + + for definition in self + .definition_repo + .list() + .await + .map_err(|e| AssistantError::Internal(format!("list assistant definitions: {e}")))? + { + rebuild_legacy_assistant_mirror(&self.pool, &definition, state_map.get(&definition.id)) + .await + .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; + } + + Ok(()) + } + // ----------------------------------------------------------------------- // Classification // ----------------------------------------------------------------------- @@ -109,6 +303,9 @@ impl AssistantService { result.push(builtin_to_response(b, overrides_map.get(&b.id))); } for u in &user_rows { + if self.builtin.has(&u.id) { + continue; + } result.push(user_row_to_response(u, overrides_map.get(&u.id))?); } for e in &extensions { @@ -966,6 +1163,21 @@ fn decode_list_map(raw: Option<&str>) -> Result>, As } } +fn normalize_json_array_string(raw: Option<&str>, field: &str) -> Result { + serde_json::to_string(&decode_str_list(raw)?) + .map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) +} + +fn normalize_json_object_string(raw: Option<&str>, field: &str) -> Result { + serde_json::to_string(&decode_str_map(raw)?) + .map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) +} + +fn normalize_json_map_of_arrays_string(raw: Option<&str>, field: &str) -> Result { + serde_json::to_string(&decode_list_map(raw)?) + .map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) +} + // --------------------------------------------------------------------------- // Filesystem helpers // --------------------------------------------------------------------------- @@ -1049,8 +1261,9 @@ pub fn generate_user_id() -> String { mod tests { use super::*; use aionui_db::{ - CreateProviderParams, SqliteAssistantOverrideRepository, SqliteAssistantRepository, SqliteProviderRepository, - init_database_memory, + CreateProviderParams, SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, + SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteAssistantStateRepository, + SqliteProviderRepository, init_database_memory, }; use aionui_extension::ExtensionStateStore; use aionui_realtime::BroadcastEventBus; @@ -1058,6 +1271,8 @@ mod tests { struct Fixture { service: AssistantService, + definition_repo: Arc, + state_repo: Arc, provider_repo: Arc, _tmp: TempDir, _db: aionui_db::Database, @@ -1094,6 +1309,12 @@ mod tests { async fn fixture_with_options(opts: FixtureOpts) -> Fixture { let tmp = TempDir::new().unwrap(); let db = init_database_memory().await.unwrap(); + let definition_repo: Arc = + Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); + let state_repo: Arc = + Arc::new(SqliteAssistantStateRepository::new(db.pool().clone())); + let preference_repo: Arc = + Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(db.pool().clone())); let orepo: Arc = Arc::new(SqliteAssistantOverrideRepository::new(db.pool().clone())); @@ -1134,6 +1355,10 @@ mod tests { let extension_registry = ExtensionRegistry::new(ext_state_store, event_bus, "1.0.0".to_string()); let service = AssistantService::new( + db.pool().clone(), + definition_repo.clone(), + state_repo.clone(), + preference_repo, repo, orepo, provider_repo.clone(), @@ -1144,6 +1369,8 @@ mod tests { Fixture { service, + definition_repo, + state_repo, provider_repo, _tmp: tmp, _db: db, @@ -1219,6 +1446,42 @@ mod tests { assert!(list.iter().any(|a| a.id == "u1")); } + #[tokio::test] + async fn bootstrap_materializes_builtin_and_syncs_legacy_rows() { + let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await; + + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Mine".into(), + ..req_default() + }) + .await + .unwrap(); + fx.service + .set_state( + "builtin-office", + SetAssistantStateRequest { + enabled: Some(false), + sort_order: Some(9), + last_used_at: Some(1234), + }, + ) + .await + .unwrap(); + + fx.service.bootstrap_assistant_storage().await.unwrap(); + + let builtin = fx.definition_repo.get("builtin-office").await.unwrap().unwrap(); + assert_eq!(builtin.source, "builtin"); + let user = fx.definition_repo.get("u1").await.unwrap().unwrap(); + assert_eq!(user.source, "user"); + let builtin_state = fx.state_repo.get("builtin-office").await.unwrap().unwrap(); + assert!(!builtin_state.enabled); + assert_eq!(builtin_state.sort_order, 9); + assert_eq!(builtin_state.last_used_at, Some(1234)); + } + #[tokio::test] async fn create_rejects_empty_name() { let fx = fixture().await; @@ -1576,6 +1839,12 @@ mod tests { .unwrap(); let builtin_reg = Arc::new(BuiltinAssistantRegistry::load_from_dir(assets_dir)); + let definition_repo: Arc = + Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); + let state_repo: Arc = + Arc::new(SqliteAssistantStateRepository::new(db.pool().clone())); + let preference_repo: Arc = + Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(db.pool().clone())); let orepo: Arc = Arc::new(SqliteAssistantOverrideRepository::new(db.pool().clone())); @@ -1585,6 +1854,10 @@ mod tests { let extension_registry = ExtensionRegistry::new(ext_state_store, event_bus, "1.0.0".to_string()); let service = AssistantService::new( + db.pool().clone(), + definition_repo, + state_repo, + preference_repo, repo, orepo, provider_repo, diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql index 92f25f06..640530ab 100644 --- a/crates/aionui-db/migrations/012_assistant_data_unification.sql +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -46,6 +46,7 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), default_skill_ids TEXT NOT NULL DEFAULT '[]', + custom_skill_names TEXT NOT NULL DEFAULT '[]', default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', default_mcps_mode TEXT NOT NULL CHECK (default_mcps_mode IN ('auto', 'fixed')), diff --git a/crates/aionui-db/src/models/assistant.rs b/crates/aionui-db/src/models/assistant.rs index 5e268dbe..ad16bc42 100644 --- a/crates/aionui-db/src/models/assistant.rs +++ b/crates/aionui-db/src/models/assistant.rs @@ -68,6 +68,7 @@ pub struct AssistantDefinitionRow { pub default_permission_value: Option, pub default_skills_mode: String, pub default_skill_ids: String, + pub custom_skill_names: String, pub default_disabled_builtin_skill_ids: String, pub default_mcps_mode: String, pub default_mcp_ids: String, @@ -180,6 +181,7 @@ pub struct UpsertAssistantDefinitionParams<'a> { pub default_permission_value: Option<&'a str>, pub default_skills_mode: &'a str, pub default_skill_ids: &'a str, + pub custom_skill_names: &'a str, pub default_disabled_builtin_skill_ids: &'a str, pub default_mcps_mode: &'a str, pub default_mcp_ids: &'a str, diff --git a/crates/aionui-db/src/repository/sqlite_assistant.rs b/crates/aionui-db/src/repository/sqlite_assistant.rs index f5e6e50a..b73f890d 100644 --- a/crates/aionui-db/src/repository/sqlite_assistant.rs +++ b/crates/aionui-db/src/repository/sqlite_assistant.rs @@ -398,10 +398,10 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { recommended_prompts, recommended_prompts_i18n, default_model_mode, default_model_value, default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, default_disabled_builtin_skill_ids, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL) + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL) ON CONFLICT(id) DO UPDATE SET source = excluded.source, owner_type = excluded.owner_type, @@ -425,6 +425,7 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { default_permission_value = excluded.default_permission_value, default_skills_mode = excluded.default_skills_mode, default_skill_ids = excluded.default_skill_ids, + custom_skill_names = excluded.custom_skill_names, default_disabled_builtin_skill_ids = excluded.default_disabled_builtin_skill_ids, default_mcps_mode = excluded.default_mcps_mode, default_mcp_ids = excluded.default_mcp_ids, @@ -454,6 +455,7 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { .bind(params.default_permission_value) .bind(params.default_skills_mode) .bind(params.default_skill_ids) + .bind(params.custom_skill_names) .bind(params.default_disabled_builtin_skill_ids) .bind(params.default_mcps_mode) .bind(params.default_mcp_ids) @@ -595,6 +597,7 @@ pub async fn rebuild_legacy_assistant_mirror( ) -> Result<(), DbError> { let prompts = normalize_json_array(Some(definition.recommended_prompts.as_str())); let default_skills = normalize_json_array(Some(definition.default_skill_ids.as_str())); + let custom_skill_names = normalize_json_array(Some(definition.custom_skill_names.as_str())); let disabled_builtin = normalize_json_array(Some(definition.default_disabled_builtin_skill_ids.as_str())); let models = match ( definition.default_model_mode.as_str(), @@ -631,7 +634,7 @@ pub async fn rebuild_legacy_assistant_mirror( .bind(&definition.avatar) .bind(&definition.agent_backend) .bind(&default_skills) - .bind("[]") + .bind(&custom_skill_names) .bind(&disabled_builtin) .bind(&prompts) .bind(&models) @@ -752,6 +755,7 @@ mod tests { default_permission_value: Some("workspace-write"), default_skills_mode: "fixed", default_skill_ids: r#"["pdf","cron"]"#, + custom_skill_names: r#"["my-custom-skill"]"#, default_disabled_builtin_skill_ids: r#"["todo-tracker"]"#, default_mcps_mode: "auto", default_mcp_ids: "[]", From dce4cb06615faac560ebb4fb996d611b8973db7f Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 12:11:54 +0800 Subject: [PATCH 03/19] fix(assistant): preserve builtin agent overrides in unified state --- crates/aionui-assistant/src/service.rs | 95 ++++++++++++++----- .../012_assistant_data_unification.sql | 1 + crates/aionui-db/src/models/assistant.rs | 2 + .../src/repository/sqlite_assistant.rs | 13 ++- 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index e0ff4ca1..c81ac540 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -14,7 +14,7 @@ use aionui_db::{ AssistantOverrideRow, AssistantRow, CreateAssistantParams, IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, IProviderRepository, SqlitePool, UpdateAssistantParams, UpsertAssistantDefinitionParams, - UpsertAssistantStateParams, UpsertOverrideParams, rebuild_legacy_assistant_mirror, + UpsertAssistantStateParams, rebuild_legacy_assistant_mirror, }; use aionui_extension::{ AssistantClassifier, AssistantRuleDispatcher, ExtensionError, ExtensionRegistry, ResolvedAssistant, @@ -160,6 +160,9 @@ impl AssistantService { async fn sync_legacy_user_assistants_to_new_tables(&self) -> Result<(), AssistantError> { for row in self.repo.list().await? { + if self.builtin.has(&row.id) { + continue; + } self.upsert_definition_from_legacy_user_row(&row).await?; } Ok(()) @@ -180,6 +183,7 @@ impl AssistantService { assistant_id: &override_row.assistant_id, enabled: override_row.enabled, sort_order: override_row.sort_order, + agent_backend_override: override_row.preset_agent_type.as_deref(), last_used_at: override_row.last_used_at, }) .await @@ -450,6 +454,7 @@ impl AssistantService { }; let row = self.repo.create(¶ms).await?; + self.upsert_definition_from_legacy_user_row(&row).await?; let ov = self.override_repo.get(&id).await?; user_row_to_response(&row, ov.as_ref()) } @@ -488,15 +493,25 @@ impl AssistantService { let enabled = existing.as_ref().is_none_or(|o| o.enabled); let sort_order = existing.as_ref().map(|o| o.sort_order).unwrap_or(0); let last_used_at = existing.as_ref().and_then(|o| o.last_used_at); - - let params = UpsertOverrideParams { - assistant_id: id, - enabled, - sort_order, - last_used_at, - preset_agent_type: Some(Some(preset_agent_type)), - }; - self.override_repo.upsert(¶ms).await?; + self.state_repo + .upsert(&UpsertAssistantStateParams { + assistant_id: id, + enabled, + sort_order, + agent_backend_override: Some(preset_agent_type), + last_used_at, + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert assistant state: {e}")))?; + let definition = self + .definition_repo + .get(id) + .await? + .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + let state = self.state_repo.get(id).await?; + rebuild_legacy_assistant_mirror(&self.pool, &definition, state.as_ref()) + .await + .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; return self.get(id).await; } AssistantSource::Extension => { @@ -528,6 +543,7 @@ impl AssistantService { .update(id, ¶ms) .await? .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + self.upsert_definition_from_legacy_user_row(&row).await?; let ov = self.override_repo.get(id).await?; user_row_to_response(&row, ov.as_ref()) } @@ -554,6 +570,15 @@ impl AssistantService { if let Err(e) = self.override_repo.delete(id).await { warn!("failed to remove override for deleted assistant '{id}': {e}"); } + if let Err(e) = self.state_repo.delete(id).await { + warn!("failed to remove assistant state for deleted assistant '{id}': {e}"); + } + if let Err(e) = self._preference_repo.delete(id).await { + warn!("failed to remove assistant preferences for deleted assistant '{id}': {e}"); + } + if let Err(e) = self.definition_repo.soft_delete(id, now_ms()).await { + warn!("failed to soft-delete assistant definition for deleted assistant '{id}': {e}"); + } // Best-effort filesystem cleanup. self.cleanup_user_assets(id); @@ -579,27 +604,49 @@ impl AssistantService { } } - // Merge with existing override to preserve fields not in this request. + // Merge with existing state/override to preserve fields not in this request. + let existing_state = self.state_repo.get(id).await?; let existing = self.override_repo.get(id).await?; let enabled = req .enabled - .unwrap_or_else(|| existing.as_ref().is_none_or(|o| o.enabled)); + .unwrap_or_else(|| { + existing_state + .as_ref() + .map(|state| state.enabled) + .unwrap_or_else(|| existing.as_ref().is_none_or(|o| o.enabled)) + }); let sort_order = req .sort_order + .or_else(|| existing_state.as_ref().map(|state| state.sort_order)) .or_else(|| existing.as_ref().map(|o| o.sort_order)) .unwrap_or(0); let last_used_at = req .last_used_at + .or_else(|| existing_state.as_ref().and_then(|state| state.last_used_at)) .or_else(|| existing.as_ref().and_then(|o| o.last_used_at)); - - let params = UpsertOverrideParams { - assistant_id: id, - enabled, - sort_order, - last_used_at, - preset_agent_type: None, - }; - self.override_repo.upsert(¶ms).await?; + let agent_backend_override = existing_state + .as_ref() + .and_then(|state| state.agent_backend_override.as_deref()) + .or_else(|| existing.as_ref().and_then(|o| o.preset_agent_type.as_deref())); + let state = self + .state_repo + .upsert(&UpsertAssistantStateParams { + assistant_id: id, + enabled, + sort_order, + agent_backend_override, + last_used_at, + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert assistant state: {e}")))?; + let definition = self + .definition_repo + .get(id) + .await? + .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + rebuild_legacy_assistant_mirror(&self.pool, &definition, Some(&state)) + .await + .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; self.get(id).await } @@ -712,7 +759,10 @@ impl AssistantService { }; match self.repo.create(¶ms).await { - Ok(_) => result.imported += 1, + Ok(row) => { + self.upsert_definition_from_legacy_user_row(&row).await?; + result.imported += 1; + } Err(aionui_db::DbError::Conflict(_)) => { // Someone raced us into the table — treat as skip to // keep import idempotent across retries. @@ -1366,6 +1416,7 @@ mod tests { extension_registry, tmp.path().to_path_buf(), ); + service.bootstrap_assistant_storage().await.unwrap(); Fixture { service, diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql index 640530ab..93c87f7a 100644 --- a/crates/aionui-db/migrations/012_assistant_data_unification.sql +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -70,6 +70,7 @@ CREATE TABLE IF NOT EXISTS assistant_states ( assistant_id TEXT PRIMARY KEY, enabled INTEGER NOT NULL DEFAULT 1, sort_order INTEGER NOT NULL DEFAULT 0, + agent_backend_override TEXT, last_used_at INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, diff --git a/crates/aionui-db/src/models/assistant.rs b/crates/aionui-db/src/models/assistant.rs index ad16bc42..dc51d31e 100644 --- a/crates/aionui-db/src/models/assistant.rs +++ b/crates/aionui-db/src/models/assistant.rs @@ -83,6 +83,7 @@ pub struct AssistantStateRow { pub assistant_id: String, pub enabled: bool, pub sort_order: i32, + pub agent_backend_override: Option, pub last_used_at: Option, pub created_at: TimestampMs, pub updated_at: TimestampMs, @@ -193,6 +194,7 @@ pub struct UpsertAssistantStateParams<'a> { pub assistant_id: &'a str, pub enabled: bool, pub sort_order: i32, + pub agent_backend_override: Option<&'a str>, pub last_used_at: Option, } diff --git a/crates/aionui-db/src/repository/sqlite_assistant.rs b/crates/aionui-db/src/repository/sqlite_assistant.rs index b73f890d..e4bd28c3 100644 --- a/crates/aionui-db/src/repository/sqlite_assistant.rs +++ b/crates/aionui-db/src/repository/sqlite_assistant.rs @@ -502,17 +502,20 @@ impl IAssistantStateRepository for SqliteAssistantStateRepository { async fn upsert(&self, params: &UpsertAssistantStateParams<'_>) -> Result { let now = now_ms(); sqlx::query( - "INSERT INTO assistant_states (assistant_id, enabled, sort_order, last_used_at, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?) + "INSERT INTO assistant_states ( + assistant_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT(assistant_id) DO UPDATE SET enabled = excluded.enabled, sort_order = excluded.sort_order, + agent_backend_override = excluded.agent_backend_override, last_used_at = excluded.last_used_at, updated_at = excluded.updated_at", ) .bind(params.assistant_id) .bind(params.enabled) .bind(params.sort_order) + .bind(params.agent_backend_override) .bind(params.last_used_at) .bind(now) .bind(now) @@ -648,6 +651,7 @@ pub async fn rebuild_legacy_assistant_mirror( let enabled = state.map(|row| row.enabled).unwrap_or(true); let sort_order = state.map(|row| row.sort_order).unwrap_or_default(); + let agent_backend_override = state.and_then(|row| row.agent_backend_override.clone()); let last_used_at = state.and_then(|row| row.last_used_at); sqlx::query( @@ -663,7 +667,7 @@ pub async fn rebuild_legacy_assistant_mirror( .bind(&definition.id) .bind(enabled) .bind(sort_order) - .bind::>(None) + .bind(agent_backend_override) .bind(last_used_at) .bind(state.map(|row| row.updated_at).unwrap_or(definition.updated_at)) .execute(pool) @@ -1043,6 +1047,7 @@ mod tests { assistant_id: "u1", enabled: false, sort_order: 9, + agent_backend_override: Some("claude"), last_used_at: Some(1234), }) .await @@ -1053,6 +1058,7 @@ mod tests { assert_eq!(list[0].assistant_id, "u1"); assert!(!list[0].enabled); assert_eq!(list[0].sort_order, 9); + assert_eq!(list[0].agent_backend_override.as_deref(), Some("claude")); } #[tokio::test] @@ -1085,6 +1091,7 @@ mod tests { assistant_id: "u1", enabled: false, sort_order: 7, + agent_backend_override: Some("claude"), last_used_at: Some(999), }) .await From a2a6425d9174698ca3b9fecf7253d0235ebcbe38 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 12:14:01 +0800 Subject: [PATCH 04/19] refactor(assistant): read assistants from unified storage --- crates/aionui-assistant/src/service.rs | 155 ++++++++++--------------- 1 file changed, 64 insertions(+), 91 deletions(-) diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index c81ac540..1adc67c0 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -11,7 +11,7 @@ use aionui_api_types::{ }; use aionui_common::now_ms; use aionui_db::{ - AssistantOverrideRow, AssistantRow, CreateAssistantParams, IAssistantDefinitionRepository, + AssistantDefinitionRow, AssistantRow, AssistantStateRow, CreateAssistantParams, IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, IProviderRepository, SqlitePool, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantStateParams, rebuild_legacy_assistant_mirror, @@ -22,7 +22,9 @@ use aionui_extension::{ use serde_json; use tracing::{debug, warn}; -use crate::builtin::{AvatarAsset, BuiltinAssistant, BuiltinAssistantRegistry}; +use crate::builtin::{AvatarAsset, BuiltinAssistantRegistry}; +#[cfg(test)] +use crate::builtin::BuiltinAssistant; use crate::error::AssistantError; /// Aggregated business logic for `/api/assistants/*` and rule/skill dispatch. @@ -294,23 +296,24 @@ impl AssistantService { /// override application. Also performs opportunistic orphan cleanup on /// the overrides table. pub async fn list(&self) -> Result, AssistantError> { - let user_rows = self.repo.list().await?; + let definitions = self + .definition_repo + .list() + .await + .map_err(|e| AssistantError::Internal(format!("list assistant definitions: {e}")))?; + let states = self + .state_repo + .list() + .await + .map_err(|e| AssistantError::Internal(format!("list assistant states: {e}")))?; let extensions = self.extension_registry.get_assistants().await; - let overrides = self.override_repo.get_all().await?; - - let overrides_map: HashMap = - overrides.into_iter().map(|o| (o.assistant_id.clone(), o)).collect(); + let state_map: HashMap = + states.into_iter().map(|state| (state.assistant_id.clone(), state)).collect(); let mut result = Vec::new(); - for b in self.builtin.all() { - result.push(builtin_to_response(b, overrides_map.get(&b.id))); - } - for u in &user_rows { - if self.builtin.has(&u.id) { - continue; - } - result.push(user_row_to_response(u, overrides_map.get(&u.id))?); + for definition in &definitions { + result.push(definition_to_response(definition, state_map.get(&definition.id))?); } for e in &extensions { result.push(extension_to_response(e)); @@ -334,33 +337,16 @@ impl AssistantService { } pub async fn get(&self, id: &str) -> Result { - match self.classify_source(id).await { - AssistantSource::Builtin => { - let b = self - .builtin - .get(id) - .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; - let ov = self.override_repo.get(id).await?; - Ok(builtin_to_response(b, ov.as_ref())) - } - AssistantSource::Extension => { - let e = self - .extension_registry - .get_assistant_by_id(id) - .await - .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; - Ok(extension_to_response(&e)) - } - AssistantSource::User => { - let row = self - .repo - .get(id) - .await? - .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; - let ov = self.override_repo.get(id).await?; - user_row_to_response(&row, ov.as_ref()) - } + if let Some(definition) = self.definition_repo.get(id).await? { + let state = self.state_repo.get(id).await?; + return definition_to_response(&definition, state.as_ref()); } + + if let Some(assistant) = self.extension_registry.get_assistant_by_id(id).await { + return Ok(extension_to_response(&assistant)); + } + + Err(AssistantError::NotFound(format!("assistant '{id}' not found"))) } // ----------------------------------------------------------------------- @@ -455,8 +441,7 @@ impl AssistantService { let row = self.repo.create(¶ms).await?; self.upsert_definition_from_legacy_user_row(&row).await?; - let ov = self.override_repo.get(&id).await?; - user_row_to_response(&row, ov.as_ref()) + self.get(&id).await } pub async fn update(&self, id: &str, req: UpdateAssistantRequest) -> Result { @@ -544,8 +529,7 @@ impl AssistantService { .await? .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; self.upsert_definition_from_legacy_user_row(&row).await?; - let ov = self.override_repo.get(id).await?; - user_row_to_response(&row, ov.as_ref()) + self.get(id).await } pub async fn delete(&self, id: &str) -> Result<(), AssistantError> { @@ -1037,56 +1021,45 @@ fn assistant_error_to_extension_error(error: AssistantError) -> ExtensionError { /// configured providers and returns a more specific default when possible. const DEFAULT_AGENT_TYPE: &str = "aionrs"; -fn builtin_to_response(b: &BuiltinAssistant, ov: Option<&AssistantOverrideRow>) -> AssistantResponse { - AssistantResponse { - id: b.id.clone(), - source: AssistantSource::Builtin, - name: b.name.clone(), - name_i18n: b.name_i18n.clone(), - description: b.description.clone(), - description_i18n: b.description_i18n.clone(), - avatar: b.avatar.clone(), - enabled: ov.map(|o| o.enabled).unwrap_or(true), - sort_order: ov.map(|o| o.sort_order).unwrap_or(0), - preset_agent_type: ov - .and_then(|o| o.preset_agent_type.clone()) - .unwrap_or_else(|| b.preset_agent_type.clone()), - enabled_skills: b.enabled_skills.clone(), - custom_skill_names: b.custom_skill_names.clone(), - disabled_builtin_skills: b.disabled_builtin_skills.clone(), - context: None, - context_i18n: HashMap::new(), - prompts: b.prompts.clone(), - prompts_i18n: b.prompts_i18n.clone(), - models: b.models.clone(), - last_used_at: ov.and_then(|o| o.last_used_at), - } -} - -fn user_row_to_response( - row: &AssistantRow, - ov: Option<&AssistantOverrideRow>, +fn definition_to_response( + definition: &AssistantDefinitionRow, + state: Option<&AssistantStateRow>, ) -> Result { + let source = match definition.source.as_str() { + "builtin" => AssistantSource::Builtin, + "extension" => AssistantSource::Extension, + _ => AssistantSource::User, + }; + let models = match ( + definition.default_model_mode.as_str(), + definition.default_model_value.as_deref(), + ) { + ("fixed", Some(model)) => vec![model.to_string()], + _ => Vec::new(), + }; + Ok(AssistantResponse { - id: row.id.clone(), - source: AssistantSource::User, - name: row.name.clone(), - name_i18n: decode_str_map(row.name_i18n.as_deref())?, - description: row.description.clone(), - description_i18n: decode_str_map(row.description_i18n.as_deref())?, - avatar: row.avatar.clone(), - enabled: ov.map(|o| o.enabled).unwrap_or(true), - sort_order: ov.map(|o| o.sort_order).unwrap_or(0), - preset_agent_type: row.preset_agent_type.clone(), - enabled_skills: decode_str_list(row.enabled_skills.as_deref())?, - custom_skill_names: decode_str_list(row.custom_skill_names.as_deref())?, - disabled_builtin_skills: decode_str_list(row.disabled_builtin_skills.as_deref())?, + id: definition.id.clone(), + source, + name: definition.name.clone(), + name_i18n: decode_str_map(Some(definition.name_i18n.as_str()))?, + description: definition.description.clone(), + description_i18n: decode_str_map(Some(definition.description_i18n.as_str()))?, + avatar: definition.avatar.clone(), + enabled: state.is_none_or(|row| row.enabled), + sort_order: state.map(|row| row.sort_order).unwrap_or(0), + preset_agent_type: state + .and_then(|row| row.agent_backend_override.clone()) + .unwrap_or_else(|| definition.agent_backend.clone()), + enabled_skills: decode_str_list(Some(definition.default_skill_ids.as_str()))?, + custom_skill_names: decode_str_list(Some(definition.custom_skill_names.as_str()))?, + disabled_builtin_skills: decode_str_list(Some(definition.default_disabled_builtin_skill_ids.as_str()))?, context: None, context_i18n: HashMap::new(), - prompts: decode_str_list(row.prompts.as_deref())?, - prompts_i18n: decode_list_map(row.prompts_i18n.as_deref())?, - models: decode_str_list(row.models.as_deref())?, - last_used_at: ov.and_then(|o| o.last_used_at), + prompts: decode_str_list(Some(definition.recommended_prompts.as_str()))?, + prompts_i18n: decode_list_map(Some(definition.recommended_prompts_i18n.as_str()))?, + models, + last_used_at: state.and_then(|row| row.last_used_at), }) } From 590fd6d0042f94412e3eabcd5d864a4e671cdcf9 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 14:04:18 +0800 Subject: [PATCH 05/19] feat(assistant): add snapshot resolution and detail api --- crates/aionui-api-types/src/assistant.rs | 100 +++++ crates/aionui-api-types/src/lib.rs | 7 +- crates/aionui-app/src/router/state.rs | 28 +- crates/aionui-app/tests/assistants_e2e.rs | 126 +++++- crates/aionui-app/tests/conversation_e2e.rs | 167 ++++++++ crates/aionui-assistant/src/routes.rs | 22 +- crates/aionui-assistant/src/service.rs | 230 ++++++++-- crates/aionui-conversation/src/service.rs | 396 +++++++++++++++++- .../aionui-conversation/src/service_test.rs | 166 +++++++- crates/aionui-db/src/lib.rs | 21 +- crates/aionui-db/src/models/mod.rs | 4 +- crates/aionui-db/src/repository/assistant.rs | 14 +- crates/aionui-db/src/repository/mod.rs | 4 +- .../src/repository/sqlite_assistant.rs | 30 +- 14 files changed, 1217 insertions(+), 98 deletions(-) diff --git a/crates/aionui-api-types/src/assistant.rs b/crates/aionui-api-types/src/assistant.rs index afda7ff9..b43a8939 100644 --- a/crates/aionui-api-types/src/assistant.rs +++ b/crates/aionui-api-types/src/assistant.rs @@ -58,6 +58,106 @@ pub struct AssistantResponse { pub last_used_at: Option, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantProfileResponse { + pub name: String, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + pub name_i18n: HashMap, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + pub description_i18n: HashMap, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub avatar: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantStateResponse { + pub enabled: bool, + pub sort_order: i32, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub last_used_at: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantEngineResponse { + pub agent_backend: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantRulesResponse { + pub content: String, + pub storage_mode: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantPromptsResponse { + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub recommended: Vec, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + pub recommended_i18n: HashMap>, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantDefaultScalarResponse { + pub mode: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantDefaultListResponse { + pub mode: String, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub value: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantDefaultsResponse { + pub model: AssistantDefaultScalarResponse, + pub permission: AssistantDefaultScalarResponse, + pub skills: AssistantDefaultListResponse, + pub mcps: AssistantDefaultListResponse, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantCapabilitiesResponse { + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub default_skill_ids: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub custom_skill_names: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub default_disabled_builtin_skill_ids: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantPreferencesResponse { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub last_model_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub last_permission_value: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub last_skill_ids: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub last_disabled_builtin_skill_ids: Vec, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub last_mcp_ids: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantDetailResponse { + pub id: String, + pub source: AssistantSource, + pub profile: AssistantProfileResponse, + pub state: AssistantStateResponse, + pub engine: AssistantEngineResponse, + pub rules: AssistantRulesResponse, + pub prompts: AssistantPromptsResponse, + pub defaults: AssistantDefaultsResponse, + pub capabilities: AssistantCapabilitiesResponse, + pub preferences: AssistantPreferencesResponse, +} + // --------------------------------------------------------------------------- // Request types // --------------------------------------------------------------------------- diff --git a/crates/aionui-api-types/src/lib.rs b/crates/aionui-api-types/src/lib.rs index 4c05c4ee..5f893139 100644 --- a/crates/aionui-api-types/src/lib.rs +++ b/crates/aionui-api-types/src/lib.rs @@ -47,8 +47,11 @@ pub use agent_error::{ AgentStreamErrorData, }; pub use assistant::{ - AssistantResponse, AssistantSource, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, - ImportError, SetAssistantStateRequest, UpdateAssistantRequest, + AssistantCapabilitiesResponse, AssistantDefaultListResponse, AssistantDefaultScalarResponse, + AssistantDefaultsResponse, AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, + AssistantProfileResponse, AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, + AssistantStateResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, + SetAssistantStateRequest, UpdateAssistantRequest, }; pub use auth::{ AuthStatusResponse, ChangePasswordRequest, LoginRequest, LoginResponse, PublicUser, QrLoginRequest, diff --git a/crates/aionui-app/src/router/state.rs b/crates/aionui-app/src/router/state.rs index eedde2f2..f656db26 100644 --- a/crates/aionui-app/src/router/state.rs +++ b/crates/aionui-app/src/router/state.rs @@ -190,14 +190,9 @@ pub async fn build_module_states( ); let assistant = build_assistant_state(services, ext_state.registry.clone()); - assistant - .service - .bootstrap_assistant_storage() - .await - .map_err(|error| { - RouterBuildError::new("router.assistant.bootstrap", "failed to bootstrap assistant storage") - .with_source(error) - })?; + assistant.service.bootstrap_assistant_storage().await.map_err(|error| { + RouterBuildError::new("router.assistant.bootstrap", "failed to bootstrap assistant storage").with_source(error) + })?; let cron = build_cron_state(services); cron.cron_service.init().await; tracing::info!( @@ -245,7 +240,11 @@ pub async fn build_module_states( let states = ModuleStates { system: build_module_state_phase(&boot, "system", || build_system_state(services)), conversation: build_module_state_phase(&boot, "conversation", || { - build_conversation_state(services, Some(cron.cron_service.clone())) + build_conversation_state( + services, + Some(cron.cron_service.clone()), + Some(assistant.service.clone() as Arc), + ) }), remote_agent: build_module_state_phase(&boot, "remote_agent", || build_remote_agent_state(services)), agent: build_module_state_phase(&boot, "agent", || AgentRouterState { @@ -343,12 +342,13 @@ pub fn build_system_state(services: &AppServices) -> SystemRouterState { pub fn build_conversation_state( services: &AppServices, cron_service: Option>, + assistant_dispatcher: Option>, ) -> ConversationRouterState { let pool = services.database.pool().clone(); let conversaion_repo = Arc::new(SqliteConversationRepository::new(pool.clone())); let agent_metadata_repo: Arc = Arc::new(SqliteAgentMetadataRepository::new(pool.clone())); - let acp_session_repo: Arc = Arc::new(SqliteAcpSessionRepository::new(pool)); + let acp_session_repo: Arc = Arc::new(SqliteAcpSessionRepository::new(pool.clone())); let skill_resolver = Arc::new(aionui_conversation::skill_resolver::ExtensionSkillResolver::new( services.skill_paths.clone(), )); @@ -365,6 +365,14 @@ pub fn build_conversation_state( conversation_service.with_mcp_server_repo(Arc::new(aionui_db::SqliteMcpServerRepository::new( services.database.pool().clone(), ))); + conversation_service + .with_assistant_definition_repo(Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone()))); + conversation_service.with_assistant_state_repo(Arc::new(SqliteAssistantStateRepository::new(pool.clone()))); + conversation_service + .with_assistant_preference_repo(Arc::new(SqliteAssistantPreferenceRepository::new(pool.clone()))); + if let Some(dispatcher) = assistant_dispatcher { + conversation_service.with_assistant_dispatcher(dispatcher); + } if let Some(hook) = services.task_manager_delete_hook.clone() { conversation_service.with_delete_hook(hook); } diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index 6cde2182..50000daa 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -16,10 +16,11 @@ use std::sync::Arc; use aionui_app::{AppConfig, AppServices, ModuleStates, build_module_states, create_router_with_states}; use aionui_assistant::{AssistantRouterState, AssistantService, BuiltinAssistantRegistry}; use aionui_db::{ - IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, - IAssistantRepository, IAssistantStateRepository, IProviderRepository, SqliteAssistantDefinitionRepository, + IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, + IAssistantStateRepository, IProviderRepository, SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, - SqliteAssistantStateRepository, SqliteProviderRepository, init_database_memory, + SqliteAssistantStateRepository, SqliteProviderRepository, UpsertAssistantDefinitionParams, + UpsertAssistantPreferenceParams, UpsertAssistantStateParams, init_database_memory, }; use aionui_extension::{ AssistantRuleDispatcher, ExtensionRegistry, ExtensionRouterState, ExtensionSource, ExtensionStateStore, @@ -307,6 +308,125 @@ async fn list_requires_auth() { assert_eq!(json["code"], "UNAUTHORIZED"); } +#[tokio::test] +async fn get_detail_returns_definition_state_preferences_and_rules() { + let fx = fixture().await; + + let create_req = json_with_token( + "POST", + "/api/assistants", + json!({ + "id": "u1", + "name": "Mine", + "description": "hello", + "preset_agent_type": "aionrs", + "enabled_skills": ["legacy-default"], + "custom_skill_names": ["custom-note"], + "disabled_builtin_skills": ["todo-tracker"], + "prompts": ["draft a summary"] + }), + &fx.token, + &fx.csrf, + ); + let create_resp = fx.app.clone().oneshot(create_req).await.unwrap(); + assert_eq!(create_resp.status(), StatusCode::CREATED); + + let write_rule_req = json_with_token( + "POST", + "/api/skills/assistant-rule/write", + json!({ "assistant_id": "u1", "content": "user rule body", "locale": "en-US" }), + &fx.token, + &fx.csrf, + ); + let write_rule_resp = fx.app.clone().oneshot(write_rule_req).await.unwrap(); + assert_eq!(write_rule_resp.status(), StatusCode::OK); + + let pool = fx.services.database.pool().clone(); + let definition_repo = SqliteAssistantDefinitionRepository::new(pool.clone()); + let state_repo = SqliteAssistantStateRepository::new(pool.clone()); + let preference_repo = SqliteAssistantPreferenceRepository::new(pool); + let definition = definition_repo.get("u1").await.unwrap().unwrap(); + + definition_repo + .upsert(&UpsertAssistantDefinitionParams { + id: &definition.id, + source: &definition.source, + owner_type: &definition.owner_type, + source_ref: definition.source_ref.as_deref(), + source_version: definition.source_version.as_deref(), + source_hash: definition.source_hash.as_deref(), + name: &definition.name, + name_i18n: &definition.name_i18n, + description: definition.description.as_deref(), + description_i18n: &definition.description_i18n, + avatar: definition.avatar.as_deref(), + agent_backend: &definition.agent_backend, + rule_resource_type: &definition.rule_resource_type, + rule_resource_ref: definition.rule_resource_ref.as_deref(), + rule_inline_content: definition.rule_inline_content.as_deref(), + recommended_prompts: r#"["draft a summary","share next steps"]"#, + recommended_prompts_i18n: r#"{"zh-CN":["总结一下"]}"#, + default_model_mode: "fixed", + default_model_value: Some("gpt-4.1"), + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "fixed", + default_skill_ids: r#"["preset-pdf"]"#, + custom_skill_names: &definition.custom_skill_names, + default_disabled_builtin_skill_ids: r#"["todo-tracker"]"#, + default_mcps_mode: "auto", + default_mcp_ids: r#"["mcp-legacy"]"#, + }) + .await + .unwrap(); + state_repo + .upsert(&UpsertAssistantStateParams { + assistant_id: "u1", + enabled: false, + sort_order: 7, + agent_backend_override: Some("codex"), + last_used_at: Some(1_725_000_001_234), + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + assistant_id: "u1", + last_model_id: Some("gpt-5-mini"), + last_permission_value: Some("workspace-write"), + last_skill_ids: r#"["pref-skill"]"#, + last_disabled_builtin_skill_ids: r#"["planner"]"#, + last_mcp_ids: r#"["mcp-pref"]"#, + }) + .await + .unwrap(); + + let resp = fx + .app + .clone() + .oneshot(get_with_token("/api/assistants/u1?locale=en-US", &fx.token)) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + + let json = body_json(resp).await; + let data = &json["data"]; + assert_eq!(data["id"], "u1"); + assert_eq!(data["source"], "user"); + assert_eq!(data["profile"]["name"], "Mine"); + assert_eq!(data["state"]["enabled"], false); + assert_eq!(data["state"]["sort_order"], 7); + assert_eq!(data["engine"]["agent_backend"], "codex"); + assert_eq!(data["rules"]["content"], "user rule body"); + assert_eq!(data["rules"]["storage_mode"], "user_file"); + assert_eq!(data["defaults"]["model"]["mode"], "fixed"); + assert_eq!(data["defaults"]["model"]["value"], "gpt-4.1"); + assert_eq!(data["defaults"]["skills"]["value"], json!(["preset-pdf"])); + assert_eq!(data["capabilities"]["custom_skill_names"], json!(["custom-note"])); + assert_eq!(data["preferences"]["last_permission_value"], "workspace-write"); + assert_eq!(data["preferences"]["last_skill_ids"], json!(["pref-skill"])); +} + // =========================================================================== // POST /api/assistants // =========================================================================== diff --git a/crates/aionui-app/tests/conversation_e2e.rs b/crates/aionui-app/tests/conversation_e2e.rs index 1cbef959..ae8a8af3 100644 --- a/crates/aionui-app/tests/conversation_e2e.rs +++ b/crates/aionui-app/tests/conversation_e2e.rs @@ -2,6 +2,11 @@ mod common; +use aionui_db::{ + IAssistantDefinitionRepository, IAssistantPreferenceRepository, IAssistantStateRepository, + SqliteAssistantDefinitionRepository, SqliteAssistantPreferenceRepository, SqliteAssistantStateRepository, + UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, UpsertAssistantStateParams, +}; use axum::http::StatusCode; use serde_json::json; use tower::ServiceExt; @@ -103,6 +108,168 @@ async fn t1_3_create_with_optional_fields() { assert_eq!(json["data"]["channel_chat_id"], "user:123"); } +#[tokio::test] +async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { + let (mut app, services) = build_app().await; + let (token, csrf) = setup_and_login(&mut app, &services, "admin", "StrongP@ss1").await; + + let create_assistant_req = json_with_token( + "POST", + "/api/assistants", + json!({ + "id": "u1", + "name": "Snapshot Assistant", + "preset_agent_type": "codex" + }), + &token, + &csrf, + ); + let create_assistant_resp = app.clone().oneshot(create_assistant_req).await.unwrap(); + assert_eq!(create_assistant_resp.status(), StatusCode::CREATED); + + let write_rule_req = json_with_token( + "POST", + "/api/skills/assistant-rule/write", + json!({ + "assistant_id": "u1", + "content": "assistant snapshot rule", + "locale": "en-US" + }), + &token, + &csrf, + ); + let write_rule_resp = app.clone().oneshot(write_rule_req).await.unwrap(); + assert_eq!(write_rule_resp.status(), StatusCode::OK); + + let pool = services.database.pool().clone(); + let definition_repo = SqliteAssistantDefinitionRepository::new(pool.clone()); + let state_repo = SqliteAssistantStateRepository::new(pool.clone()); + let preference_repo = SqliteAssistantPreferenceRepository::new(pool); + let definition = definition_repo.get("u1").await.unwrap().unwrap(); + + definition_repo + .upsert(&UpsertAssistantDefinitionParams { + id: &definition.id, + source: &definition.source, + owner_type: &definition.owner_type, + source_ref: definition.source_ref.as_deref(), + source_version: definition.source_version.as_deref(), + source_hash: definition.source_hash.as_deref(), + name: &definition.name, + name_i18n: &definition.name_i18n, + description: definition.description.as_deref(), + description_i18n: &definition.description_i18n, + avatar: definition.avatar.as_deref(), + agent_backend: &definition.agent_backend, + rule_resource_type: &definition.rule_resource_type, + rule_resource_ref: definition.rule_resource_ref.as_deref(), + rule_inline_content: definition.rule_inline_content.as_deref(), + recommended_prompts: &definition.recommended_prompts, + recommended_prompts_i18n: &definition.recommended_prompts_i18n, + default_model_mode: "auto", + default_model_value: None, + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "auto", + default_skill_ids: r#"[]"#, + custom_skill_names: &definition.custom_skill_names, + default_disabled_builtin_skill_ids: r#"[]"#, + default_mcps_mode: "auto", + default_mcp_ids: r#"[]"#, + }) + .await + .unwrap(); + state_repo + .upsert(&UpsertAssistantStateParams { + assistant_id: "u1", + enabled: true, + sort_order: 0, + agent_backend_override: Some("codex"), + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + assistant_id: "u1", + last_model_id: Some("pref-model"), + last_permission_value: Some("workspace-write"), + last_skill_ids: r#"["pref-skill"]"#, + last_disabled_builtin_skill_ids: r#"["pref-disabled"]"#, + last_mcp_ids: r#"["pref-mcp"]"#, + }) + .await + .unwrap(); + + let create_req = json_with_token( + "POST", + "/api/conversations", + json!({ + "type": "acp", + "name": "Snapshot Flow", + "extra": { + "assistant_id": "u1", + "assistant_locale": "en-US", + "assistant_overrides": { + "model": "override-model", + "skill_ids": ["override-skill"], + "disabled_builtin_skill_ids": ["override-disabled"], + "mcp_ids": ["override-mcp"] + } + } + }), + &token, + &csrf, + ); + let resp = app.clone().oneshot(create_req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + + let json = body_json(resp).await; + let data = &json["data"]; + assert_eq!(data["extra"]["assistant_id"], "u1"); + assert_eq!(data["extra"]["preset_assistant_id"], "u1"); + assert_eq!(data["extra"]["preset_context"], "assistant snapshot rule"); + assert_eq!(data["extra"]["current_model_id"], "override-model"); + assert_eq!(data["extra"]["assistant_snapshot"]["assistant_id"], "u1"); + assert_eq!(data["extra"]["assistant_snapshot"]["agent_backend"], "codex"); + assert_eq!( + data["extra"]["assistant_snapshot"]["rules"]["content"], + "assistant snapshot rule" + ); + assert_eq!( + data["extra"]["assistant_snapshot"]["resolved_defaults"]["permission"], + "workspace-write" + ); + assert_eq!( + data["extra"]["assistant_snapshot"]["resolved_defaults"]["skill_ids"], + json!(["override-skill"]) + ); + assert_eq!( + data["extra"]["assistant_snapshot"]["resolved_defaults"]["mcp_ids"], + json!(["override-mcp"]) + ); + assert!( + data["extra"]["skills"] + .as_array() + .unwrap() + .iter() + .any(|skill| skill == "override-skill") + ); + + let updated_preference = preference_repo.get("u1").await.unwrap().unwrap(); + assert_eq!(updated_preference.last_model_id.as_deref(), Some("override-model")); + assert_eq!( + updated_preference.last_permission_value.as_deref(), + Some("workspace-write") + ); + assert_eq!(updated_preference.last_skill_ids, r#"["override-skill"]"#); + assert_eq!( + updated_preference.last_disabled_builtin_skill_ids, + r#"["override-disabled"]"# + ); + assert_eq!(updated_preference.last_mcp_ids, r#"["override-mcp"]"#); +} + #[tokio::test] async fn t1_4_create_missing_required_field() { let (mut app, services) = build_app().await; diff --git a/crates/aionui-assistant/src/routes.rs b/crates/aionui-assistant/src/routes.rs index 4c458c8a..6b7634e5 100644 --- a/crates/aionui-assistant/src/routes.rs +++ b/crates/aionui-assistant/src/routes.rs @@ -5,14 +5,14 @@ use axum::Router; use axum::body::Body; use axum::extract::rejection::JsonRejection; -use axum::extract::{Json, Path, State}; +use axum::extract::{Json, Path, Query, State}; use axum::http::{HeaderValue, StatusCode, header}; use axum::response::Response; use axum::routing::{get, patch, post}; use aionui_api_types::{ - ApiResponse, AssistantResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, - SetAssistantStateRequest, UpdateAssistantRequest, + ApiResponse, AssistantDetailResponse, AssistantResponse, CreateAssistantRequest, ImportAssistantsRequest, + ImportAssistantsResult, SetAssistantStateRequest, UpdateAssistantRequest, }; use aionui_common::ApiError; @@ -23,13 +23,18 @@ pub use crate::state::AssistantRouterState; pub fn assistant_routes(state: AssistantRouterState) -> Router { Router::new() .route("/api/assistants", get(list).post(create)) - .route("/api/assistants/{id}", axum::routing::put(update).delete(delete_one)) + .route("/api/assistants/{id}", get(get_one).put(update).delete(delete_one)) .route("/api/assistants/{id}/state", patch(set_state)) .route("/api/assistants/{id}/avatar", get(get_avatar)) .route("/api/assistants/import", post(import)) .with_state(state) } +#[derive(Debug, serde::Deserialize, Default)] +struct GetAssistantDetailQuery { + locale: Option, +} + impl From for ApiError { fn from(error: AssistantError) -> Self { match error { @@ -58,6 +63,15 @@ async fn create( Ok((StatusCode::CREATED, Json(ApiResponse::ok(created)))) } +async fn get_one( + State(state): State, + Path(id): Path, + Query(query): Query, +) -> Result>, ApiError> { + let detail = state.service.get_detail(&id, query.locale.as_deref()).await?; + Ok(Json(ApiResponse::ok(detail))) +} + async fn update( State(state): State, Path(id): Path, diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 1adc67c0..339d76bd 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -6,8 +6,11 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use aionui_api_types::{ - AssistantResponse, AssistantSource, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, - ImportError, SetAssistantStateRequest, UpdateAssistantRequest, + AssistantCapabilitiesResponse, AssistantDefaultListResponse, AssistantDefaultScalarResponse, + AssistantDefaultsResponse, AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, + AssistantProfileResponse, AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, + AssistantStateResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, + SetAssistantStateRequest, UpdateAssistantRequest, }; use aionui_common::now_ms; use aionui_db::{ @@ -22,9 +25,9 @@ use aionui_extension::{ use serde_json; use tracing::{debug, warn}; -use crate::builtin::{AvatarAsset, BuiltinAssistantRegistry}; #[cfg(test)] use crate::builtin::BuiltinAssistant; +use crate::builtin::{AvatarAsset, BuiltinAssistantRegistry}; use crate::error::AssistantError; /// Aggregated business logic for `/api/assistants/*` and rule/skill dispatch. @@ -32,7 +35,7 @@ pub struct AssistantService { pool: SqlitePool, definition_repo: Arc, state_repo: Arc, - _preference_repo: Arc, + preference_repo: Arc, repo: Arc, override_repo: Arc, /// Used to infer a sane `preset_agent_type` default when the caller did @@ -79,7 +82,7 @@ impl AssistantService { pool, definition_repo, state_repo, - _preference_repo: preference_repo, + preference_repo, repo, override_repo, provider_repo, @@ -114,10 +117,8 @@ impl AssistantService { .map_err(|e| AssistantError::Internal(format!("encode builtin skills: {e}")))?; let custom_skill_names = serde_json::to_string(&builtin.custom_skill_names) .map_err(|e| AssistantError::Internal(format!("encode builtin custom skills: {e}")))?; - let default_disabled_builtin_skill_ids = - serde_json::to_string(&builtin.disabled_builtin_skills).map_err(|e| { - AssistantError::Internal(format!("encode builtin disabled skills: {e}")) - })?; + let default_disabled_builtin_skill_ids = serde_json::to_string(&builtin.disabled_builtin_skills) + .map_err(|e| AssistantError::Internal(format!("encode builtin disabled skills: {e}")))?; self.definition_repo .upsert(&UpsertAssistantDefinitionParams { @@ -197,14 +198,12 @@ impl AssistantService { async fn upsert_definition_from_legacy_user_row(&self, row: &AssistantRow) -> Result<(), AssistantError> { let name_i18n = normalize_json_object_string(row.name_i18n.as_deref(), "name_i18n")?; - let description_i18n = - normalize_json_object_string(row.description_i18n.as_deref(), "description_i18n")?; + let description_i18n = normalize_json_object_string(row.description_i18n.as_deref(), "description_i18n")?; let recommended_prompts = normalize_json_array_string(row.prompts.as_deref(), "prompts")?; let recommended_prompts_i18n = normalize_json_map_of_arrays_string(row.prompts_i18n.as_deref(), "prompts_i18n")?; let default_skill_ids = normalize_json_array_string(row.enabled_skills.as_deref(), "enabled_skills")?; - let custom_skill_names = - normalize_json_array_string(row.custom_skill_names.as_deref(), "custom_skill_names")?; + let custom_skill_names = normalize_json_array_string(row.custom_skill_names.as_deref(), "custom_skill_names")?; let default_disabled_builtin_skill_ids = normalize_json_array_string(row.disabled_builtin_skills.as_deref(), "disabled_builtin_skills")?; let models = decode_str_list(row.models.as_deref())?; @@ -256,8 +255,10 @@ impl AssistantService { .list() .await .map_err(|e| AssistantError::Internal(format!("list assistant states: {e}")))?; - let state_map: HashMap = - states.into_iter().map(|state| (state.assistant_id.clone(), state)).collect(); + let state_map: HashMap = states + .into_iter() + .map(|state| (state.assistant_id.clone(), state)) + .collect(); for definition in self .definition_repo @@ -307,8 +308,10 @@ impl AssistantService { .await .map_err(|e| AssistantError::Internal(format!("list assistant states: {e}")))?; let extensions = self.extension_registry.get_assistants().await; - let state_map: HashMap = - states.into_iter().map(|state| (state.assistant_id.clone(), state)).collect(); + let state_map: HashMap = states + .into_iter() + .map(|state| (state.assistant_id.clone(), state)) + .collect(); let mut result = Vec::new(); @@ -349,6 +352,21 @@ impl AssistantService { Err(AssistantError::NotFound(format!("assistant '{id}' not found"))) } + pub async fn get_detail(&self, id: &str, locale: Option<&str>) -> Result { + if let Some(definition) = self.definition_repo.get(id).await? { + let state = self.state_repo.get(id).await?; + let preference = self.preference_repo.get(id).await?; + let rules_content = self.read_rule(id, locale).await?; + return definition_to_detail_response(&definition, state.as_ref(), preference.as_ref(), &rules_content); + } + + if let Some(assistant) = self.extension_registry.get_assistant_by_id(id).await { + return Ok(extension_to_detail_response(&assistant)); + } + + Err(AssistantError::NotFound(format!("assistant '{id}' not found"))) + } + // ----------------------------------------------------------------------- // Default-agent inference // ----------------------------------------------------------------------- @@ -557,7 +575,7 @@ impl AssistantService { if let Err(e) = self.state_repo.delete(id).await { warn!("failed to remove assistant state for deleted assistant '{id}': {e}"); } - if let Err(e) = self._preference_repo.delete(id).await { + if let Err(e) = self.preference_repo.delete(id).await { warn!("failed to remove assistant preferences for deleted assistant '{id}': {e}"); } if let Err(e) = self.definition_repo.soft_delete(id, now_ms()).await { @@ -591,14 +609,12 @@ impl AssistantService { // Merge with existing state/override to preserve fields not in this request. let existing_state = self.state_repo.get(id).await?; let existing = self.override_repo.get(id).await?; - let enabled = req - .enabled - .unwrap_or_else(|| { - existing_state - .as_ref() - .map(|state| state.enabled) - .unwrap_or_else(|| existing.as_ref().is_none_or(|o| o.enabled)) - }); + let enabled = req.enabled.unwrap_or_else(|| { + existing_state + .as_ref() + .map(|state| state.enabled) + .unwrap_or_else(|| existing.as_ref().is_none_or(|o| o.enabled)) + }); let sort_order = req .sort_order .or_else(|| existing_state.as_ref().map(|state| state.sort_order)) @@ -1063,6 +1079,99 @@ fn definition_to_response( }) } +fn definition_to_detail_response( + definition: &AssistantDefinitionRow, + state: Option<&AssistantStateRow>, + preference: Option<&aionui_db::AssistantPreferenceRow>, + rules_content: &str, +) -> Result { + let default_skill_ids = decode_str_list(Some(definition.default_skill_ids.as_str()))?; + let custom_skill_names = decode_str_list(Some(definition.custom_skill_names.as_str()))?; + let default_disabled_builtin_skill_ids = + decode_str_list(Some(definition.default_disabled_builtin_skill_ids.as_str()))?; + let default_mcp_ids = decode_str_list(Some(definition.default_mcp_ids.as_str()))?; + let last_skill_ids = preference + .map(|row| decode_str_list(Some(row.last_skill_ids.as_str()))) + .transpose()? + .unwrap_or_default(); + let last_disabled_builtin_skill_ids = preference + .map(|row| decode_str_list(Some(row.last_disabled_builtin_skill_ids.as_str()))) + .transpose()? + .unwrap_or_default(); + let last_mcp_ids = preference + .map(|row| decode_str_list(Some(row.last_mcp_ids.as_str()))) + .transpose()? + .unwrap_or_default(); + + Ok(AssistantDetailResponse { + id: definition.id.clone(), + source: match definition.source.as_str() { + "builtin" => AssistantSource::Builtin, + "extension" => AssistantSource::Extension, + _ => AssistantSource::User, + }, + profile: AssistantProfileResponse { + name: definition.name.clone(), + name_i18n: decode_str_map(Some(definition.name_i18n.as_str()))?, + description: definition.description.clone(), + description_i18n: decode_str_map(Some(definition.description_i18n.as_str()))?, + avatar: definition.avatar.clone(), + }, + state: AssistantStateResponse { + enabled: state.map(|row| row.enabled).unwrap_or(true), + sort_order: state.map(|row| row.sort_order).unwrap_or_default(), + last_used_at: state.and_then(|row| row.last_used_at), + }, + engine: AssistantEngineResponse { + agent_backend: state + .and_then(|row| row.agent_backend_override.clone()) + .unwrap_or_else(|| definition.agent_backend.clone()), + }, + rules: AssistantRulesResponse { + content: if rules_content.is_empty() { + definition.rule_inline_content.clone().unwrap_or_default() + } else { + rules_content.to_owned() + }, + storage_mode: definition.rule_resource_type.clone(), + }, + prompts: AssistantPromptsResponse { + recommended: decode_str_list(Some(definition.recommended_prompts.as_str()))?, + recommended_i18n: decode_list_map(Some(definition.recommended_prompts_i18n.as_str()))?, + }, + defaults: AssistantDefaultsResponse { + model: AssistantDefaultScalarResponse { + mode: definition.default_model_mode.clone(), + value: definition.default_model_value.clone(), + }, + permission: AssistantDefaultScalarResponse { + mode: definition.default_permission_mode.clone(), + value: definition.default_permission_value.clone(), + }, + skills: AssistantDefaultListResponse { + mode: definition.default_skills_mode.clone(), + value: default_skill_ids.clone(), + }, + mcps: AssistantDefaultListResponse { + mode: definition.default_mcps_mode.clone(), + value: default_mcp_ids, + }, + }, + capabilities: AssistantCapabilitiesResponse { + default_skill_ids, + custom_skill_names, + default_disabled_builtin_skill_ids, + }, + preferences: AssistantPreferencesResponse { + last_model_id: preference.and_then(|row| row.last_model_id.clone()), + last_permission_value: preference.and_then(|row| row.last_permission_value.clone()), + last_skill_ids, + last_disabled_builtin_skill_ids, + last_mcp_ids, + }, + }) +} + fn extension_to_response(e: &ResolvedAssistant) -> AssistantResponse { AssistantResponse { id: e.id.clone(), @@ -1087,6 +1196,66 @@ fn extension_to_response(e: &ResolvedAssistant) -> AssistantResponse { } } +fn extension_to_detail_response(e: &ResolvedAssistant) -> AssistantDetailResponse { + AssistantDetailResponse { + id: e.id.clone(), + source: AssistantSource::Extension, + profile: AssistantProfileResponse { + name: e.name.clone(), + name_i18n: HashMap::new(), + description: e.description.clone(), + description_i18n: HashMap::new(), + avatar: e.icon.clone(), + }, + state: AssistantStateResponse { + enabled: true, + sort_order: 0, + last_used_at: None, + }, + engine: AssistantEngineResponse { + agent_backend: DEFAULT_AGENT_TYPE.to_string(), + }, + rules: AssistantRulesResponse { + content: e.context.clone().unwrap_or_default(), + storage_mode: "extension".to_string(), + }, + prompts: AssistantPromptsResponse { + recommended: Vec::new(), + recommended_i18n: HashMap::new(), + }, + defaults: AssistantDefaultsResponse { + model: AssistantDefaultScalarResponse { + mode: "auto".to_string(), + value: None, + }, + permission: AssistantDefaultScalarResponse { + mode: "auto".to_string(), + value: None, + }, + skills: AssistantDefaultListResponse { + mode: "auto".to_string(), + value: Vec::new(), + }, + mcps: AssistantDefaultListResponse { + mode: "auto".to_string(), + value: Vec::new(), + }, + }, + capabilities: AssistantCapabilitiesResponse { + default_skill_ids: Vec::new(), + custom_skill_names: Vec::new(), + default_disabled_builtin_skill_ids: Vec::new(), + }, + preferences: AssistantPreferencesResponse { + last_model_id: None, + last_permission_value: None, + last_skill_ids: Vec::new(), + last_disabled_builtin_skill_ids: Vec::new(), + last_mcp_ids: Vec::new(), + }, + } +} + // --------------------------------------------------------------------------- // Serialization helpers // --------------------------------------------------------------------------- @@ -1187,18 +1356,15 @@ fn decode_list_map(raw: Option<&str>) -> Result>, As } fn normalize_json_array_string(raw: Option<&str>, field: &str) -> Result { - serde_json::to_string(&decode_str_list(raw)?) - .map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) + serde_json::to_string(&decode_str_list(raw)?).map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) } fn normalize_json_object_string(raw: Option<&str>, field: &str) -> Result { - serde_json::to_string(&decode_str_map(raw)?) - .map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) + serde_json::to_string(&decode_str_map(raw)?).map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) } fn normalize_json_map_of_arrays_string(raw: Option<&str>, field: &str) -> Result { - serde_json::to_string(&decode_list_map(raw)?) - .map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) + serde_json::to_string(&decode_list_map(raw)?).map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) } // --------------------------------------------------------------------------- diff --git a/crates/aionui-conversation/src/service.rs b/crates/aionui-conversation/src/service.rs index d4060ddb..99cdc4c3 100644 --- a/crates/aionui-conversation/src/service.rs +++ b/crates/aionui-conversation/src/service.rs @@ -25,8 +25,10 @@ use aionui_common::{ use aionui_db::models::{ConversationRow, MessageRow}; use aionui_db::{ ConversationFilters, ConversationRowUpdate, CreateAcpSessionParams, IAcpSessionRepository, - IAgentMetadataRepository, IConversationRepository, IMcpServerRepository, SaveRuntimeStateParams, SortOrder, + IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantPreferenceRepository, + IAssistantStateRepository, IConversationRepository, IMcpServerRepository, SaveRuntimeStateParams, SortOrder, }; +use aionui_extension::AssistantRuleDispatcher; use aionui_mcp::{AcpMcpCapabilities, parse_acp_mcp_capabilities}; use aionui_realtime::EventBroadcaster; use aionui_runtime::{RuntimeCommandProbe, probe_node_runtime_supported, probe_runtime_command, resolve_command_path}; @@ -48,6 +50,53 @@ pub(crate) const MAX_CRON_CONTINUATIONS_PER_TURN: usize = 4; const LEGACY_CONVERSATION_ARCHIVED_MESSAGE: &str = "This historical conversation can no longer be continued. Please start a new conversation."; +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)] +struct AssistantConversationOverrides { + #[serde(default)] + model: Option, + #[serde(default)] + permission: Option, + #[serde(default)] + skill_ids: Option>, + #[serde(default)] + disabled_builtin_skill_ids: Option>, + #[serde(default)] + mcp_ids: Option>, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +struct AssistantSnapshotResolvedDefaults { + #[serde(default)] + model: Option, + #[serde(default)] + permission: Option, + #[serde(default)] + skill_ids: Vec, + #[serde(default)] + disabled_builtin_skill_ids: Vec, + #[serde(default)] + mcp_ids: Vec, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +struct AssistantSnapshotRules { + content: String, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +struct AssistantSnapshot { + assistant_id: String, + assistant_source: String, + #[serde(default)] + name: String, + #[serde(default)] + avatar: Option, + agent_backend: String, + rules: AssistantSnapshotRules, + resolved_defaults: AssistantSnapshotResolvedDefaults, + created_at: i64, +} + #[derive(Debug, Clone, Copy)] struct McpSupportPolicy { stdio: bool, @@ -131,6 +180,10 @@ pub struct ConversationService { delete_hooks: Arc>>>, cron_service: Arc>>>, mcp_server_repo: Arc>>>, + assistant_definition_repo: Arc>>>, + assistant_state_repo: Arc>>>, + assistant_preference_repo: Arc>>>, + assistant_dispatcher: Arc>>>, runtime_state: Arc, // Repos for conversation, acp_session and agent_metadata access. @@ -160,6 +213,10 @@ impl ConversationService { delete_hooks: Arc::new(RwLock::new(Vec::new())), cron_service: Arc::new(RwLock::new(None)), mcp_server_repo: Arc::new(RwLock::new(None)), + assistant_definition_repo: Arc::new(RwLock::new(None)), + assistant_state_repo: Arc::new(RwLock::new(None)), + assistant_preference_repo: Arc::new(RwLock::new(None)), + assistant_dispatcher: Arc::new(RwLock::new(None)), runtime_state: Arc::new(ConversationRuntimeStateService::default()), conversation_repo, @@ -185,6 +242,30 @@ impl ConversationService { } } + pub fn with_assistant_definition_repo(&self, repo: Arc) { + if let Ok(mut guard) = self.assistant_definition_repo.write() { + *guard = Some(repo); + } + } + + pub fn with_assistant_state_repo(&self, repo: Arc) { + if let Ok(mut guard) = self.assistant_state_repo.write() { + *guard = Some(repo); + } + } + + pub fn with_assistant_preference_repo(&self, repo: Arc) { + if let Ok(mut guard) = self.assistant_preference_repo.write() { + *guard = Some(repo); + } + } + + pub fn with_assistant_dispatcher(&self, dispatcher: Arc) { + if let Ok(mut guard) = self.assistant_dispatcher.write() { + *guard = Some(dispatcher); + } + } + /// Register a hook to be notified when a conversation is deleted. /// /// Hooks are dispatched sequentially in registration order before @@ -230,6 +311,34 @@ impl ConversationService { self.runtime_state.clone() } + fn assistant_definition_repo(&self) -> Option> { + self.assistant_definition_repo + .read() + .ok() + .and_then(|guard| guard.as_ref().cloned()) + } + + fn assistant_state_repo(&self) -> Option> { + self.assistant_state_repo + .read() + .ok() + .and_then(|guard| guard.as_ref().cloned()) + } + + fn assistant_preference_repo(&self) -> Option> { + self.assistant_preference_repo + .read() + .ok() + .and_then(|guard| guard.as_ref().cloned()) + } + + fn assistant_dispatcher(&self) -> Option> { + self.assistant_dispatcher + .read() + .ok() + .and_then(|guard| guard.as_ref().cloned()) + } + pub(crate) fn runtime_persistence(&self) -> RuntimePersistenceCoordinator { RuntimePersistenceCoordinator::new(self.runtime_state()) } @@ -388,6 +497,70 @@ impl ConversationService { obj.remove("custom_workspace"); } + let (assistant_id, assistant_locale, assistant_overrides) = match extra.as_object_mut() { + Some(obj) => { + let assistant_id = obj + .remove("assistant_id") + .or_else(|| obj.get("preset_assistant_id").cloned()) + .and_then(|value| value.as_str().map(ToOwned::to_owned)); + let assistant_locale = obj + .remove("assistant_locale") + .and_then(|value| value.as_str().map(ToOwned::to_owned)); + let overrides = obj + .remove("assistant_overrides") + .map(serde_json::from_value::) + .transpose() + .map_err(|e| ConversationError::BadRequest { + reason: format!("Invalid assistant_overrides: {e}"), + })? + .unwrap_or_default(); + (assistant_id, assistant_locale, overrides) + } + None => (None, None, AssistantConversationOverrides::default()), + }; + let assistant_snapshot = match assistant_id.as_deref() { + Some(id) => { + self.resolve_assistant_snapshot(id, assistant_locale.as_deref(), &assistant_overrides, &extra) + .await? + } + None => None, + }; + if let Some(snapshot) = assistant_snapshot.as_ref() + && let Some(obj) = extra.as_object_mut() + { + obj.insert( + "assistant_id".to_owned(), + serde_json::Value::String(snapshot.assistant_id.clone()), + ); + obj.insert( + "assistant_snapshot".to_owned(), + serde_json::to_value(snapshot) + .map_err(|e| ConversationError::internal(format!("Failed to serialize assistant snapshot: {e}")))?, + ); + obj.insert( + "preset_assistant_id".to_owned(), + serde_json::Value::String(snapshot.assistant_id.clone()), + ); + if !snapshot.rules.content.is_empty() { + obj.insert( + "preset_context".to_owned(), + serde_json::Value::String(snapshot.rules.content.clone()), + ); + obj.insert( + "preset_rules".to_owned(), + serde_json::Value::String(snapshot.rules.content.clone()), + ); + } + if let Some(model_id) = snapshot.resolved_defaults.model.as_ref() + && !obj.contains_key("current_model_id") + { + obj.insert( + "current_model_id".to_owned(), + serde_json::Value::String(model_id.clone()), + ); + } + } + // Consume transient skill-shaping inputs and freeze the initial // `skills` snapshot into `extra.skills`. These request-only fields // must not land in the stored row. Legacy names (`enabled_skills`, @@ -406,8 +579,16 @@ impl ConversationService { let (preset_enabled, exclude_auto_inject) = match extra.as_object_mut() { Some(obj) => { - let preset = take_string_array(obj, &["preset_enabled_skills", "enabled_skills"]); - let exclude = take_string_array(obj, &["exclude_auto_inject_skills", "exclude_builtin_skills"]); + let preset = assistant_snapshot + .as_ref() + .map(|snapshot| snapshot.resolved_defaults.skill_ids.clone()) + .unwrap_or_else(|| take_string_array(obj, &["preset_enabled_skills", "enabled_skills"])); + let exclude = assistant_snapshot + .as_ref() + .map(|snapshot| snapshot.resolved_defaults.disabled_builtin_skill_ids.clone()) + .unwrap_or_else(|| { + take_string_array(obj, &["exclude_auto_inject_skills", "exclude_builtin_skills"]) + }); // Strip the stale cache field if a clone copied it in. obj.remove("loaded_skills"); (preset, exclude) @@ -455,7 +636,14 @@ impl ConversationService { Some(obj) => { let has_selection = obj.contains_key("selected_mcp_server_ids"); let ids = take_string_array(obj, &["selected_mcp_server_ids"]); - if has_selection { Some(ids) } else { None } + if has_selection { + Some(ids) + } else { + assistant_snapshot + .as_ref() + .map(|snapshot| snapshot.resolved_defaults.mcp_ids.clone()) + .filter(|ids| !ids.is_empty()) + } } None => None, }; @@ -583,6 +771,11 @@ impl ConversationService { self.create_acp_session_row(&id, &extra).await?; } + if let Some(snapshot) = assistant_snapshot.as_ref() { + self.persist_assistant_preferences_from_snapshot(&snapshot.assistant_id, snapshot) + .await?; + } + let response = row_to_response(row, &self.workspace_root)?; self.broadcast_list_changed(&response.id, "created", response.source.as_ref()); @@ -665,6 +858,193 @@ impl ConversationService { Ok(()) } + async fn resolve_assistant_snapshot( + &self, + assistant_id: &str, + locale: Option<&str>, + overrides: &AssistantConversationOverrides, + extra: &serde_json::Value, + ) -> Result, ConversationError> { + let (Some(definition_repo), Some(state_repo), Some(preference_repo)) = ( + self.assistant_definition_repo(), + self.assistant_state_repo(), + self.assistant_preference_repo(), + ) else { + return Ok(None); + }; + + let Some(definition) = definition_repo + .get(assistant_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant definition lookup failed: {e}")))? + else { + return Ok(None); + }; + + let state = state_repo + .get(assistant_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant state lookup failed: {e}")))?; + let preference = preference_repo + .get(assistant_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant preference lookup failed: {e}")))?; + + let skill_ids = match overrides.skill_ids.as_ref() { + Some(value) => value.clone(), + None if definition.default_skills_mode == "fixed" => { + parse_json_string_list(Some(definition.default_skill_ids.as_str()), "default_skill_ids")? + } + None => preference + .as_ref() + .map(|row| parse_json_string_list(Some(row.last_skill_ids.as_str()), "last_skill_ids")) + .transpose()? + .unwrap_or_default(), + }; + let disabled_builtin_skill_ids = match overrides.disabled_builtin_skill_ids.as_ref() { + Some(value) => value.clone(), + None if definition.default_skills_mode == "fixed" => parse_json_string_list( + Some(definition.default_disabled_builtin_skill_ids.as_str()), + "default_disabled_builtin_skill_ids", + )?, + None => preference + .as_ref() + .map(|row| { + parse_json_string_list( + Some(row.last_disabled_builtin_skill_ids.as_str()), + "last_disabled_builtin_skill_ids", + ) + }) + .transpose()? + .unwrap_or_default(), + }; + let mcp_ids = match overrides.mcp_ids.as_ref() { + Some(value) => value.clone(), + None if definition.default_mcps_mode == "fixed" => { + parse_json_string_list(Some(definition.default_mcp_ids.as_str()), "default_mcp_ids")? + } + None => preference + .as_ref() + .map(|row| parse_json_string_list(Some(row.last_mcp_ids.as_str()), "last_mcp_ids")) + .transpose()? + .unwrap_or_default(), + }; + + let model = overrides + .model + .clone() + .or_else(|| match definition.default_model_mode.as_str() { + "fixed" => definition.default_model_value.clone(), + _ => preference.as_ref().and_then(|row| row.last_model_id.clone()), + }); + let permission = overrides + .permission + .clone() + .or_else(|| match definition.default_permission_mode.as_str() { + "fixed" => definition.default_permission_value.clone(), + _ => preference.as_ref().and_then(|row| row.last_permission_value.clone()), + }); + + let rules_content = if let Some(dispatcher) = self.assistant_dispatcher() { + dispatcher + .read_rule(assistant_id, locale) + .await + .map_err(|e| ConversationError::internal(format!("assistant rule lookup failed: {e}")))? + } else { + String::new() + }; + let fallback_rules = extra + .get("preset_context") + .and_then(serde_json::Value::as_str) + .or_else(|| extra.get("preset_rules").and_then(serde_json::Value::as_str)) + .unwrap_or_default(); + let agent_backend = state + .as_ref() + .and_then(|row| row.agent_backend_override.clone()) + .unwrap_or_else(|| definition.agent_backend.clone()); + + Ok(Some(AssistantSnapshot { + assistant_id: assistant_id.to_owned(), + assistant_source: definition.source, + name: definition.name, + avatar: definition.avatar, + agent_backend, + rules: AssistantSnapshotRules { + content: if rules_content.is_empty() { + fallback_rules.to_owned() + } else { + rules_content + }, + }, + resolved_defaults: AssistantSnapshotResolvedDefaults { + model, + permission, + skill_ids, + disabled_builtin_skill_ids, + mcp_ids, + }, + created_at: now_ms(), + })) + } + + async fn persist_assistant_preferences_from_snapshot( + &self, + assistant_id: &str, + snapshot: &AssistantSnapshot, + ) -> Result<(), ConversationError> { + let (Some(definition_repo), Some(preference_repo)) = + (self.assistant_definition_repo(), self.assistant_preference_repo()) + else { + return Ok(()); + }; + let Some(definition) = definition_repo + .get(assistant_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant definition lookup failed: {e}")))? + else { + return Ok(()); + }; + + let last_model_id = (definition.default_model_mode == "auto") + .then_some(snapshot.resolved_defaults.model.as_deref()) + .flatten(); + let last_permission_value = (definition.default_permission_mode == "auto") + .then_some(snapshot.resolved_defaults.permission.as_deref()) + .flatten(); + let last_skill_ids = if definition.default_skills_mode == "auto" { + serde_json::to_string(&snapshot.resolved_defaults.skill_ids) + .map_err(|e| ConversationError::internal(format!("encode assistant skills: {e}")))? + } else { + definition.default_skill_ids.clone() + }; + let last_disabled_builtin_skill_ids = if definition.default_skills_mode == "auto" { + serde_json::to_string(&snapshot.resolved_defaults.disabled_builtin_skill_ids) + .map_err(|e| ConversationError::internal(format!("encode assistant disabled builtin skills: {e}")))? + } else { + definition.default_disabled_builtin_skill_ids.clone() + }; + let last_mcp_ids = if definition.default_mcps_mode == "auto" { + serde_json::to_string(&snapshot.resolved_defaults.mcp_ids) + .map_err(|e| ConversationError::internal(format!("encode assistant mcps: {e}")))? + } else { + definition.default_mcp_ids.clone() + }; + + preference_repo + .upsert(&aionui_db::UpsertAssistantPreferenceParams { + assistant_id, + last_model_id, + last_permission_value, + last_skill_ids: &last_skill_ids, + last_disabled_builtin_skill_ids: &last_disabled_builtin_skill_ids, + last_mcp_ids: &last_mcp_ids, + }) + .await + .map_err(|e| ConversationError::internal(format!("assistant preference upsert failed: {e}")))?; + + Ok(()) + } + /// Get a single conversation by ID. /// /// Returns `NotFound` if the conversation does not exist or does not @@ -2303,6 +2683,14 @@ fn merge_json(base: &mut serde_json::Value, patch: &serde_json::Value) { } } +fn parse_json_string_list(raw: Option<&str>, field: &str) -> Result, ConversationError> { + match raw { + Some(value) if !value.trim().is_empty() => serde_json::from_str(value) + .map_err(|e| ConversationError::internal(format!("failed to parse assistant field {field}: {e}"))), + _ => Ok(Vec::new()), + } +} + #[derive(Debug, Default, PartialEq, Eq)] struct AssistantLineage<'a> { agent_type: &'a str, diff --git a/crates/aionui-conversation/src/service_test.rs b/crates/aionui-conversation/src/service_test.rs index 582692a0..80672896 100644 --- a/crates/aionui-conversation/src/service_test.rs +++ b/crates/aionui-conversation/src/service_test.rs @@ -29,9 +29,13 @@ use aionui_db::models::{ }; use aionui_db::{ ConversationFilters, ConversationRowUpdate, CreateAcpSessionParams, DbError, IAcpSessionRepository, - IAgentMetadataRepository, IConversationRepository, MessageRowUpdate, MessageSearchRow, PersistedSessionState, - SaveRuntimeStateParams, SortOrder, + IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantPreferenceRepository, + IAssistantStateRepository, IConversationRepository, MessageRowUpdate, MessageSearchRow, PersistedSessionState, + SaveRuntimeStateParams, SortOrder, SqliteAssistantDefinitionRepository, SqliteAssistantPreferenceRepository, + SqliteAssistantStateRepository, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, + UpsertAssistantStateParams, init_database_memory, }; +use aionui_extension::{AssistantRuleDispatcher, ExtensionError}; use aionui_realtime::EventBroadcaster; use serde_json::json; use tokio::sync::broadcast; @@ -55,6 +59,37 @@ struct RecordingSkillResolver { links: Arc>>, } +struct StaticAssistantDispatcher { + rules: std::collections::HashMap, +} + +#[async_trait::async_trait] +impl AssistantRuleDispatcher for StaticAssistantDispatcher { + async fn read_rule(&self, id: &str, _locale: Option<&str>) -> Result { + Ok(self.rules.get(id).cloned().unwrap_or_default()) + } + + async fn write_rule(&self, _id: &str, _locale: Option<&str>, _content: &str) -> Result<(), ExtensionError> { + Ok(()) + } + + async fn delete_rule(&self, _id: &str) -> Result { + Ok(true) + } + + async fn read_skill(&self, _id: &str, _locale: Option<&str>) -> Result { + Ok(String::new()) + } + + async fn write_skill(&self, _id: &str, _locale: Option<&str>, _content: &str) -> Result<(), ExtensionError> { + Ok(()) + } + + async fn delete_skill(&self, _id: &str) -> Result { + Ok(true) + } +} + impl RecordingSkillResolver { fn new(names: Vec) -> Self { Self { @@ -623,6 +658,32 @@ fn make_service_with_mock_task_manager( (svc, broadcaster, repo) } +async fn make_service_with_assistant_support( + skill_resolver: Arc, + dispatcher: Arc, +) -> ( + ConversationService, + Arc, + Arc, + Arc, + Arc, + Arc, +) { + let (svc, broadcaster, repo, _task_mgr) = make_service_with_resolver(skill_resolver); + let db = init_database_memory().await.unwrap(); + let definition_repo = Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); + let state_repo = Arc::new(SqliteAssistantStateRepository::new(db.pool().clone())); + let preference_repo: Arc = + Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); + + svc.with_assistant_definition_repo(definition_repo.clone()); + svc.with_assistant_state_repo(state_repo.clone()); + svc.with_assistant_preference_repo(preference_repo.clone()); + svc.with_assistant_dispatcher(dispatcher); + + (svc, broadcaster, repo, definition_repo, state_repo, preference_repo) +} + fn make_create_req() -> CreateConversationRequest { let workspace = ensure_test_workspace_path(); serde_json::from_value(json!({ @@ -3323,6 +3384,107 @@ async fn create_writes_extra_skills_from_auto_inject_and_preset() { assert!(resp.extra.get("exclude_auto_inject_skills").is_none()); } +#[tokio::test] +async fn create_resolves_assistant_snapshot_and_updates_preferences() { + let resolver = Arc::new(FixedSkillResolver { + names: vec!["cron".into(), "todo-tracker".into()], + }); + let dispatcher = Arc::new(StaticAssistantDispatcher { + rules: std::collections::HashMap::from([("preset-1".to_string(), "assistant rule body".to_string())]), + }); + let (svc, _broadcaster, _repo, definition_repo, state_repo, preference_repo) = + make_service_with_assistant_support(resolver, dispatcher).await; + let workspace = ensure_test_workspace_path(); + + definition_repo + .upsert(&UpsertAssistantDefinitionParams { + id: "preset-1", + source: "builtin", + owner_type: "system", + source_ref: Some("preset-1"), + source_version: None, + source_hash: None, + name: "Preset", + name_i18n: "{}", + description: Some("desc"), + description_i18n: "{}", + avatar: Some("🤖"), + agent_backend: "claude", + rule_resource_type: "builtin_asset", + rule_resource_ref: Some("rules/preset-1.md"), + rule_inline_content: None, + recommended_prompts: "[]", + recommended_prompts_i18n: "{}", + default_model_mode: "auto", + default_model_value: None, + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "auto", + default_skill_ids: "[]", + custom_skill_names: "[]", + default_disabled_builtin_skill_ids: "[]", + default_mcps_mode: "auto", + default_mcp_ids: "[]", + }) + .await + .unwrap(); + state_repo + .upsert(&UpsertAssistantStateParams { + assistant_id: "preset-1", + enabled: true, + sort_order: 0, + agent_backend_override: Some("codex"), + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + assistant_id: "preset-1", + last_model_id: Some("old-model"), + last_permission_value: Some("workspace-write"), + last_skill_ids: r#"["legacy-skill"]"#, + last_disabled_builtin_skill_ids: r#"["legacy-disabled"]"#, + last_mcp_ids: r#"["legacy-mcp"]"#, + }) + .await + .unwrap(); + + let req: CreateConversationRequest = serde_json::from_value(json!({ + "type": "acp", + "name": "t", + "extra": { + "workspace": workspace, + "backend": "claude", + "assistant_id": "preset-1", + "assistant_locale": "zh-CN", + "assistant_overrides": { + "model": "new-model", + "skill_ids": ["pdf"], + "disabled_builtin_skill_ids": ["todo-tracker"], + } + }, + })) + .unwrap(); + let resp = svc.create("user-1", req).await.unwrap(); + + assert_eq!(resp.extra["assistant_id"], json!("preset-1")); + assert_eq!(resp.extra["preset_assistant_id"], json!("preset-1")); + assert_eq!(resp.extra["preset_context"], json!("assistant rule body")); + assert_eq!(resp.extra["current_model_id"], json!("new-model")); + assert_eq!(resp.extra["skills"], json!(["cron", "pdf"])); + assert_eq!(resp.extra["assistant_snapshot"]["agent_backend"], json!("codex")); + assert_eq!( + resp.extra["assistant_snapshot"]["resolved_defaults"]["skill_ids"], + json!(["pdf"]) + ); + + let updated_pref = preference_repo.get("preset-1").await.unwrap().unwrap(); + assert_eq!(updated_pref.last_model_id.as_deref(), Some("new-model")); + assert_eq!(updated_pref.last_skill_ids, r#"["pdf"]"#); + assert_eq!(updated_pref.last_disabled_builtin_skill_ids, r#"["todo-tracker"]"#); +} + #[tokio::test] async fn create_writes_empty_skills_when_no_auto_inject_and_no_preset() { let resolver = Arc::new(FixedSkillResolver { names: vec![] }); diff --git a/crates/aionui-db/src/lib.rs b/crates/aionui-db/src/lib.rs index 49a262ea..288dfdbe 100644 --- a/crates/aionui-db/src/lib.rs +++ b/crates/aionui-db/src/lib.rs @@ -13,8 +13,8 @@ pub use error::DbError; pub use models::{ AgentMetadataRow, AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, ConversationArtifactRow, CreateAssistantParams, UpdateAgentHandshakeParams, - UpdateAssistantParams, UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, - UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, + UpdateAssistantParams, UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, + UpsertAssistantStateParams, UpsertOverrideParams, }; pub use repository::channel::UpdatePluginStatusParams; pub use repository::conversation::{ @@ -29,15 +29,14 @@ pub use repository::team::{UpdateTaskParams, UpdateTeamParams}; pub use repository::{ CreateAcpSessionParams, IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, - IChannelRepository, IClientPreferenceRepository, IConversationRepository, ICronRepository, - IMcpServerRepository, IOAuthTokenRepository, IProviderRepository, IRemoteAgentRepository, - ISettingsRepository, ITeamRepository, IUserRepository, PersistedSessionState, SaveRuntimeStateParams, - SqliteAcpSessionRepository, SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, - SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, - SqliteAssistantStateRepository, SqliteChannelRepository, SqliteClientPreferenceRepository, - SqliteConversationRepository, SqliteCronRepository, SqliteMcpServerRepository, SqliteOAuthTokenRepository, - SqliteProviderRepository, SqliteRemoteAgentRepository, SqliteSettingsRepository, SqliteTeamRepository, - SqliteUserRepository, rebuild_legacy_assistant_mirror, + IChannelRepository, IClientPreferenceRepository, IConversationRepository, ICronRepository, IMcpServerRepository, + IOAuthTokenRepository, IProviderRepository, IRemoteAgentRepository, ISettingsRepository, ITeamRepository, + IUserRepository, PersistedSessionState, SaveRuntimeStateParams, SqliteAcpSessionRepository, + SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, + SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteAssistantStateRepository, + SqliteChannelRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, SqliteCronRepository, + SqliteMcpServerRepository, SqliteOAuthTokenRepository, SqliteProviderRepository, SqliteRemoteAgentRepository, + SqliteSettingsRepository, SqliteTeamRepository, SqliteUserRepository, rebuild_legacy_assistant_mirror, }; // Re-export sqlx pool type for downstream crates diff --git a/crates/aionui-db/src/models/mod.rs b/crates/aionui-db/src/models/mod.rs index 152ca0b3..5fb0001b 100644 --- a/crates/aionui-db/src/models/mod.rs +++ b/crates/aionui-db/src/models/mod.rs @@ -19,8 +19,8 @@ pub use acp_session::AcpSessionRow; pub use agent_metadata::{AgentMetadataRow, UpdateAgentHandshakeParams, UpsertAgentMetadataParams}; pub use assistant::{ AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, - CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, - UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, + UpsertAssistantStateParams, UpsertOverrideParams, }; pub use channel::{AssistantSessionRow, AssistantUserRow, ChannelPluginRow, PairingCodeRow}; pub use client_preference::ClientPreference; diff --git a/crates/aionui-db/src/repository/assistant.rs b/crates/aionui-db/src/repository/assistant.rs index 5be5ae07..394445f0 100644 --- a/crates/aionui-db/src/repository/assistant.rs +++ b/crates/aionui-db/src/repository/assistant.rs @@ -3,8 +3,8 @@ use crate::error::DbError; use crate::models::{ AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, - CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, - UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, + UpsertAssistantStateParams, UpsertOverrideParams, }; /// CRUD access for user-authored assistant rows. @@ -61,10 +61,7 @@ pub trait IAssistantOverrideRepository: Send + Sync { pub trait IAssistantDefinitionRepository: Send + Sync { async fn list(&self) -> Result, DbError>; async fn get(&self, id: &str) -> Result, DbError>; - async fn upsert( - &self, - params: &UpsertAssistantDefinitionParams<'_>, - ) -> Result; + async fn upsert(&self, params: &UpsertAssistantDefinitionParams<'_>) -> Result; async fn soft_delete(&self, id: &str, deleted_at: i64) -> Result; } @@ -81,9 +78,6 @@ pub trait IAssistantStateRepository: Send + Sync { #[async_trait::async_trait] pub trait IAssistantPreferenceRepository: Send + Sync { async fn get(&self, assistant_id: &str) -> Result, DbError>; - async fn upsert( - &self, - params: &UpsertAssistantPreferenceParams<'_>, - ) -> Result; + async fn upsert(&self, params: &UpsertAssistantPreferenceParams<'_>) -> Result; async fn delete(&self, assistant_id: &str) -> Result; } diff --git a/crates/aionui-db/src/repository/mod.rs b/crates/aionui-db/src/repository/mod.rs index d0b8f4c3..a703d155 100644 --- a/crates/aionui-db/src/repository/mod.rs +++ b/crates/aionui-db/src/repository/mod.rs @@ -30,8 +30,8 @@ mod user; pub use acp_session::{CreateAcpSessionParams, IAcpSessionRepository, PersistedSessionState, SaveRuntimeStateParams}; pub use agent_metadata::IAgentMetadataRepository; pub use assistant::{ - IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, - IAssistantRepository, IAssistantStateRepository, + IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, + IAssistantStateRepository, }; pub use channel::IChannelRepository; pub use client_preference::IClientPreferenceRepository; diff --git a/crates/aionui-db/src/repository/sqlite_assistant.rs b/crates/aionui-db/src/repository/sqlite_assistant.rs index e4bd28c3..e9c14a07 100644 --- a/crates/aionui-db/src/repository/sqlite_assistant.rs +++ b/crates/aionui-db/src/repository/sqlite_assistant.rs @@ -6,8 +6,8 @@ use sqlx::SqlitePool; use crate::error::DbError; use crate::models::{ AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, - CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, - UpsertAssistantPreferenceParams, UpsertAssistantStateParams, UpsertOverrideParams, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, + UpsertAssistantStateParams, UpsertOverrideParams, }; use crate::repository::assistant::{ IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, @@ -384,10 +384,7 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { Ok(row) } - async fn upsert( - &self, - params: &UpsertAssistantDefinitionParams<'_>, - ) -> Result { + async fn upsert(&self, params: &UpsertAssistantDefinitionParams<'_>) -> Result { let now = now_ms(); sqlx::query( @@ -493,9 +490,10 @@ impl IAssistantStateRepository for SqliteAssistantStateRepository { } async fn list(&self) -> Result, DbError> { - let rows = sqlx::query_as::<_, AssistantStateRow>("SELECT * FROM assistant_states ORDER BY sort_order, updated_at") - .fetch_all(&self.pool) - .await?; + let rows = + sqlx::query_as::<_, AssistantStateRow>("SELECT * FROM assistant_states ORDER BY sort_order, updated_at") + .fetch_all(&self.pool) + .await?; Ok(rows) } @@ -522,9 +520,12 @@ impl IAssistantStateRepository for SqliteAssistantStateRepository { .execute(&self.pool) .await?; - self.get(params.assistant_id) - .await? - .ok_or_else(|| DbError::Init(format!("upsert did not produce state row for id '{}'", params.assistant_id))) + self.get(params.assistant_id).await?.ok_or_else(|| { + DbError::Init(format!( + "upsert did not produce state row for id '{}'", + params.assistant_id + )) + }) } async fn delete(&self, assistant_id: &str) -> Result { @@ -547,10 +548,7 @@ impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { Ok(row) } - async fn upsert( - &self, - params: &UpsertAssistantPreferenceParams<'_>, - ) -> Result { + async fn upsert(&self, params: &UpsertAssistantPreferenceParams<'_>) -> Result { let now = now_ms(); sqlx::query( "INSERT INTO assistant_preferences ( From f95582d70dacdb93287e7a8b2981c5727f3b6ec4 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 14:23:33 +0800 Subject: [PATCH 06/19] refactor(assistant): drop legacy builtin skill-file assets --- .../assets/builtin-assistants/assistants.json | 9 +- .../skills/cowork-skills.en-US.md | 814 ------------------ .../skills/cowork-skills.ru-RU.md | 814 ------------------ .../skills/cowork-skills.zh-CN.md | 803 ----------------- .../skills/moltbook-skills.en-US.md | 88 -- .../skills/moltbook-skills.ru-RU.md | 88 -- .../skills/moltbook-skills.zh-CN.md | 88 -- .../social-job-publisher-skills.en-US.md | 137 --- .../social-job-publisher-skills.ru-RU.md | 137 --- .../social-job-publisher-skills.zh-CN.md | 137 --- crates/aionui-app/tests/assistants_e2e.rs | 11 +- crates/aionui-assistant/src/builtin.rs | 59 +- crates/aionui-assistant/src/service.rs | 11 +- 13 files changed, 45 insertions(+), 3151 deletions(-) delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.en-US.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.ru-RU.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.zh-CN.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.en-US.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.ru-RU.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.zh-CN.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.en-US.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.ru-RU.md delete mode 100644 crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.zh-CN.md diff --git a/crates/aionui-app/assets/builtin-assistants/assistants.json b/crates/aionui-app/assets/builtin-assistants/assistants.json index a2eb3329..cd3ff8ce 100644 --- a/crates/aionui-app/assets/builtin-assistants/assistants.json +++ b/crates/aionui-app/assets/builtin-assistants/assistants.json @@ -627,8 +627,7 @@ "Витягти та узагальнити ключову інформацію С усіх файлів PDF" ] }, - "models": [], - "skill_file": "skills/cowork-skills.{locale}.md" + "models": [] }, { "id": "game-3d", @@ -886,8 +885,7 @@ "Створити пост про вакансію для кількох платформ (LinkedIn, X)" ] }, - "models": [], - "skill_file": "skills/social-job-publisher-skills.{locale}.md" + "models": [] }, { "id": "moltbook", @@ -940,8 +938,7 @@ "Перевірити нові особисті повідомлення" ] }, - "models": [], - "skill_file": "skills/moltbook-skills.{locale}.md" + "models": [] }, { "id": "beautiful-mermaid", diff --git a/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.en-US.md b/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.en-US.md deleted file mode 100644 index aab1e509..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.en-US.md +++ /dev/null @@ -1,814 +0,0 @@ -# Cowork Skills - - -You are a Cowork assistant powered by AionUi. Cowork mode enables autonomous task execution with file system access, document processing capabilities, and multi-step workflow planning. You operate directly on the user's real file system without sandbox isolation - be careful with destructive operations and always confirm before making significant changes. - - - -When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge. - -How to use skills: - -- Skills are automatically activated when trigger keywords appear in user requests -- When a skill is invoked, detailed instructions will be provided on how to complete the task -- Skills can be combined for complex workflows -- Always follow the skill's best practices and guidelines - - - - ---- - -id: skill-creator -name: Guide for Creating Effective Skills -triggers: create skill, new skill, skill template, define skill, 创建技能, 新技能 - ---- - -**Description**: Guide for creating effective skills that can be used by the assistant. - -**Skill Structure**: - -```markdown ---- -id: skill-id -name: Skill Name -triggers: keyword1, keyword2, keyword3 ---- - -**Description**: [One-sentence description of what this skill does] - -**Capabilities**: - -- [Capability 1] -- [Capability 2] -- [Capability 3] - -**Implementation Guidelines**: -[Code examples or step-by-step instructions] - -**Best Practices**: - -- [Best practice 1] -- [Best practice 2] -``` - -Where: - -- `skill-id` is a unique lowercase identifier (e.g., `xlsx`, `pptx`, `pdf`) -- `Skill Name` is the human-readable name -- `triggers` are comma-separated keywords that activate this skill - -**Creating a Good Skill**: - -1. **Clear Triggers**: Define specific keywords that uniquely identify when this skill should be activated -2. **Focused Scope**: Each skill should do one thing well -3. **Actionable Guidelines**: Include concrete implementation steps or code examples -4. **Best Practices**: Document common pitfalls and recommended approaches -5. **Examples**: Provide usage examples when helpful - -**Best Practices**: - -- Keep triggers specific enough to avoid false activations -- Include both English and Chinese triggers for bilingual support -- Provide working code examples, not pseudocode -- Document any prerequisites or dependencies -- Test the skill with various user requests - ---- - -id: xlsx -name: Excel Spreadsheet Handler -triggers: Excel, spreadsheet, .xlsx, data table, budget, financial model, chart, graph, tabular data, xls, csv to excel, data analysis - ---- - -**Description**: Create, read, and manipulate Excel workbooks with multiple sheets, charts, formulas, and advanced formatting. - -**Capabilities**: - -- Create Excel workbooks with multiple sheets -- Read and parse .xlsx/.xls files -- Generate charts (bar, line, pie, scatter, combo) -- Apply formulas and calculations (SUM, AVERAGE, VLOOKUP, etc.) -- Format cells (colors, borders, fonts, alignment, conditional formatting) -- Create pivot tables and data summaries -- Data validation and dropdown lists -- Export filtered/sorted data -- Merge cells and apply cell styles - -**Implementation Guidelines**: - -```javascript -// Use exceljs for Node.js -const ExcelJS = require('exceljs'); -const workbook = new ExcelJS.Workbook(); -const sheet = workbook.addWorksheet('Sheet1'); - -// Set column headers with styling -sheet.columns = [ - { header: 'Name', key: 'name', width: 20 }, - { header: 'Value', key: 'value', width: 15 }, -]; - -// Add data rows -sheet.addRow({ name: 'Item 1', value: 100 }); - -// Apply formatting -sheet.getRow(1).font = { bold: true }; -sheet.getRow(1).fill = { - type: 'pattern', - pattern: 'solid', - fgColor: { argb: 'FF4472C4' }, -}; - -// Save workbook -await workbook.xlsx.writeFile('output.xlsx'); -``` - -### XLSX Scripts Workflow - -For recalculating formulas in existing spreadsheets, use the recalc script: - -```bash -# Recalculate all formulas in an Excel file using LibreOffice -# This is useful after modifying cell values programmatically -python skills/xlsx/recalc.py -``` - -**Python Quick Reference**: - -```python -import pandas as pd - -# Read Excel -df = pd.read_excel('file.xlsx') # Default: first sheet -all_sheets = pd.read_excel('file.xlsx', sheet_name=None) # All sheets as dict - -# Analyze -df.head() # Preview data -df.info() # Column info -df.describe() # Statistics - -# Write Excel -df.to_excel('output.xlsx', index=False) -``` - -**Best Practices**: - -- Always validate data types before writing -- Use meaningful sheet names (max 31 characters) -- Apply consistent number formatting -- Add data validation for user input cells -- Use named ranges for complex formulas -- Freeze header rows for large datasets -- **Use formulas instead of hardcoded values** to keep spreadsheets dynamic - ---- - -id: pptx -name: PowerPoint Presentation Generator -triggers: PowerPoint, presentation, .pptx, slides, slide deck, pitch deck, ppt, slideshow, deck, keynote, 演示文稿, 幻灯片 - ---- - -**Description**: Create professional presentations with text, images, charts, diagrams, and consistent theming. - -**Capabilities**: - -- Create presentations from scratch -- Add text slides with rich formatting -- Insert images, shapes, and icons -- Create charts and diagrams -- Apply themes, layouts, and master slides -- Generate speaker notes -- Add animations and transitions -- Create tables and SmartArt-style diagrams -- Export to PDF, images, or video - -**Implementation Guidelines**: - -```javascript -// Use pptxgenjs for Node.js -const pptxgen = require('pptxgenjs'); -const pptx = new pptxgen(); - -// Set presentation properties -pptx.author = 'Cowork'; -pptx.title = 'Presentation Title'; -pptx.subject = 'Subject'; - -// Define master slide -pptx.defineSlideMaster({ - title: 'MASTER_SLIDE', - background: { color: 'FFFFFF' }, - objects: [{ text: { text: 'Company Name', options: { x: 0.5, y: 7.0, fontSize: 10 } } }], -}); - -// Create title slide -let slide = pptx.addSlide(); -slide.addText('Presentation Title', { - x: 0.5, - y: 2.5, - w: '90%', - fontSize: 44, - bold: true, - color: '363636', - align: 'center', -}); - -// Create content slide -slide = pptx.addSlide(); -slide.addText('Section Title', { x: 0.5, y: 0.5, fontSize: 28, bold: true }); -slide.addText( - [ - { text: 'Bullet point 1', options: { bullet: true } }, - { text: 'Bullet point 2', options: { bullet: true } }, - { text: 'Bullet point 3', options: { bullet: true } }, - ], - { x: 0.5, y: 1.5, w: '90%', fontSize: 18 } -); - -// Add chart -slide.addChart(pptx.ChartType.bar, chartData, { x: 0.5, y: 3, w: 6, h: 3 }); - -// Save presentation -await pptx.writeFile('presentation.pptx'); -``` - -### PPTX Scripts Workflow - -For editing existing presentations or working with templates, use the PPTX scripts: - -```bash -# Unpack a presentation to access raw XML -python skills/pptx/ooxml/scripts/unpack.py - -# Extract text inventory from presentation (useful for template-based editing) -python skills/pptx/scripts/inventory.py - -# Create thumbnail grid of all slides for visual analysis -python skills/pptx/scripts/thumbnail.py [output_prefix] [--cols N] - -# Rearrange slides by index sequence -python skills/pptx/scripts/rearrange.py -# Example: python skills/pptx/scripts/rearrange.py template.pptx output.pptx 0,34,34,50,52 - -# Apply text replacements from JSON -python skills/pptx/scripts/replace.py - -# Pack modified XML back to PPTX -python skills/pptx/ooxml/scripts/pack.py - -# Validate PPTX structure -python skills/pptx/ooxml/scripts/validate.py -``` - -**Best Practices**: - -- Maintain consistent design across all slides -- Use 6x6 rule: max 6 bullets, max 6 words per bullet -- Optimize image sizes (compress before inserting) -- Use master slides for branding consistency -- Include alt text for accessibility -- Keep font sizes readable (min 24pt for body) -- Use high-contrast color combinations -- Limit animations to enhance, not distract - ---- - -id: pdf -name: PDF Document Processor -triggers: PDF, .pdf, form, extract text, merge pdf, split pdf, combine pdf, pdf to, watermark, annotate, fill form, fill pdf - ---- - -**Description**: Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms. - -**Capabilities**: - -- Extract text and images from PDFs -- Merge multiple PDFs into one -- Split PDFs into individual pages or ranges -- Extract tables and structured data -- Fill and create PDF forms (both fillable and non-fillable) -- Add watermarks, headers, footers -- Add annotations and comments -- Compress PDF file size -- Convert PDFs to/from other formats -- Handle encrypted/password-protected PDFs -- OCR for scanned documents - -### PDF Form Filling Workflow - -**CRITICAL: You MUST complete these steps in order. Do not skip ahead.** - -If you need to fill out a PDF form, first check if the PDF has fillable form fields: - -```bash -python skills/pdf/scripts/check_fillable_fields.py -``` - -#### For Fillable PDFs: - -1. Extract field information: - - ```bash - python skills/pdf/scripts/extract_form_field_info.py - ``` - -2. Convert PDF to images for visual analysis: - - ```bash - python skills/pdf/scripts/convert_pdf_to_images.py - ``` - -3. Create `field_values.json` with values to fill: - - ```json - [ - { "field_id": "last_name", "value": "Simpson" }, - { "field_id": "Checkbox12", "value": "/On" } - ] - ``` - -4. Fill the form: - ```bash - python skills/pdf/scripts/fill_fillable_fields.py - ``` - -#### For Non-Fillable PDFs (Annotation-based): - -1. Convert PDF to images: - - ```bash - python skills/pdf/scripts/convert_pdf_to_images.py - ``` - -2. Create `fields.json` with bounding boxes for each field: - - ```json - { - "pages": [{ "page_number": 1, "image_width": 612, "image_height": 792 }], - "form_fields": [ - { - "page_number": 1, - "description": "User's last name", - "field_label": "Last name", - "label_bounding_box": [30, 125, 95, 142], - "entry_bounding_box": [100, 125, 280, 142], - "entry_text": { "text": "Johnson", "font_size": 14, "font_color": "000000" } - } - ] - } - ``` - -3. Create validation images: - - ```bash - python skills/pdf/scripts/create_validation_image.py - ``` - -4. Validate bounding boxes: - - ```bash - python skills/pdf/scripts/check_bounding_boxes.py - ``` - -5. Fill the form with annotations: - ```bash - python skills/pdf/scripts/fill_pdf_form_with_annotations.py - ``` - -### PDF Merge/Split Operations - -```bash -# Merge multiple PDFs -python skills/pdf/scripts/merge_pdfs.py ... - -# Split into individual pages -python skills/pdf/scripts/split_pdf.py - -# Extract specific pages -python skills/pdf/scripts/split_pdf.py 1-5 -python skills/pdf/scripts/split_pdf.py 1,3,5,7 -``` - -### Python Quick Reference - -```python -from pypdf import PdfReader, PdfWriter - -# Read a PDF -reader = PdfReader("document.pdf") -print(f"Pages: {len(reader.pages)}") - -# Extract text -text = "" -for page in reader.pages: - text += page.extract_text() - -# For table extraction, use pdfplumber -import pdfplumber -with pdfplumber.open("document.pdf") as pdf: - for page in pdf.pages: - tables = page.extract_tables() - for table in tables: - print(table) -``` - -**Best Practices**: - -- Always check for fillable fields first before deciding workflow -- For non-fillable forms, validate bounding boxes visually before filling -- Preserve original quality when processing -- Handle password-protected PDFs appropriately (request password from user) -- Validate PDF structure before processing -- Use streaming for large PDFs (>10MB) -- Maintain PDF metadata when merging - ---- - -id: docx -name: Word Document Handler -triggers: Word, document, .docx, report, letter, memo, manuscript, essay, paper, article, writeup, documentation, doc file, word文档, 文档 - ---- - -**Description**: Create and manipulate Word documents with rich formatting, tables, headers, footers, and table of contents. - -**Capabilities**: - -- Create formatted Word documents -- Apply styles and templates -- Insert tables and nested lists -- Add headers, footers, page numbers -- Generate table of contents -- Insert images and shapes -- Track changes and comments -- Add footnotes and endnotes -- Create bookmarks and hyperlinks -- Convert markdown to docx -- Apply custom themes and fonts - -**Implementation Guidelines**: - -```javascript -// Use docx package for Node.js -const { - Document, - Packer, - Paragraph, - TextRun, - HeadingLevel, - Table, - TableRow, - TableCell, - Header, - Footer, - PageNumber, -} = require('docx'); - -const doc = new Document({ - sections: [ - { - properties: {}, - headers: { - default: new Header({ - children: [new Paragraph({ text: 'Document Header' })], - }), - }, - footers: { - default: new Footer({ - children: [ - new Paragraph({ - children: [new TextRun('Page '), new PageNumber()], - }), - ], - }), - }, - children: [ - // Title - new Paragraph({ - text: 'Document Title', - heading: HeadingLevel.TITLE, - }), - - // Heading - new Paragraph({ - text: 'Section 1', - heading: HeadingLevel.HEADING_1, - }), - - // Body text - new Paragraph({ - children: [ - new TextRun({ text: 'This is ', bold: false }), - new TextRun({ text: 'bold', bold: true }), - new TextRun({ text: ' and ' }), - new TextRun({ text: 'italic', italics: true }), - new TextRun({ text: ' text.' }), - ], - }), - - // Bullet list - new Paragraph({ - text: 'First bullet point', - bullet: { level: 0 }, - }), - - // Table - new Table({ - rows: [ - new TableRow({ - children: [ - new TableCell({ children: [new Paragraph('Header 1')] }), - new TableCell({ children: [new Paragraph('Header 2')] }), - ], - }), - new TableRow({ - children: [ - new TableCell({ children: [new Paragraph('Cell 1')] }), - new TableCell({ children: [new Paragraph('Cell 2')] }), - ], - }), - ], - }), - ], - }, - ], -}); - -// Save document -const buffer = await Packer.toBuffer(doc); -await fs.writeFile('document.docx', buffer); -``` - -### DOCX Scripts Workflow - -For editing existing documents or working with tracked changes, use the DOCX scripts: - -```bash -# Convert document to markdown (preserves tracked changes) -pandoc --track-changes=all -o output.md - -# Unpack a document to access raw XML -python skills/docx/ooxml/scripts/unpack.py - -# Pack modified XML back to DOCX -python skills/docx/ooxml/scripts/pack.py - -# Validate DOCX structure -python skills/docx/ooxml/scripts/validate.py -``` - -**Python Document Library for Tracked Changes**: - -```python -# Import the Document library for tracked changes and comments -from skills.docx.scripts.document import Document - -# Initialize (automatically sets up comment infrastructure) -doc = Document('unpacked_directory') -doc = Document('unpacked_directory', author="John Doe", initials="JD") - -# Find nodes -node = doc["word/document.xml"].get_node(tag="w:p", contains="specific text") -node = doc["word/document.xml"].get_node(tag="w:del", attrs={"w:id": "1"}) - -# Add comments -doc.add_comment(start=node, end=node, text="Comment text") -doc.reply_to_comment(parent_comment_id=0, text="Reply text") - -# Suggest tracked changes -doc["word/document.xml"].suggest_deletion(node) # Delete content -doc["word/document.xml"].revert_insertion(ins_node) # Reject insertion -doc["word/document.xml"].revert_deletion(del_node) # Reject deletion - -# Save -doc.save() -``` - -**Best Practices**: - -- Use built-in heading styles for TOC generation -- Apply consistent styling with templates -- Include document metadata (author, title, subject) -- Use styles instead of direct formatting -- Validate document structure before saving -- Consider accessibility (alt text for images, proper heading hierarchy) - ---- - -id: task-orchestrator -name: Multi-Step Task Planning -triggers: complex task, multi-step, plan, organize, breakdown, orchestrate, project plan, workflow, 任务规划, 多步骤 - ---- - -**Description**: Plan and execute complex multi-step tasks with dependency tracking, parallel execution, and progress monitoring. - -**Workflow**: - -1. Analyze task requirements and constraints -2. Create task_plan.md with phases and milestones -3. Identify dependencies and parallel opportunities -4. Execute tasks in optimal order -5. Track progress and adapt as needed -6. Report completion status - -**Task Plan Template**: - -```markdown -# Task Plan: [Task Name] - -## Goal - -[One-sentence description of the final state] - -## Current Phase - -Phase X: [Phase Name] - -## Phases - -### Phase 1: Discovery & Analysis - -- [ ] Analyze requirements -- [ ] Identify dependencies -- [ ] Gather resources -- **Status:** completed | in_progress | pending -- **Notes:** [Any relevant observations] - -### Phase 2: Implementation - -- [ ] Task 2.1 -- [ ] Task 2.2 -- [ ] Task 2.3 -- **Status:** pending -- **Dependencies:** Phase 1 - -### Phase 3: Validation & Delivery - -- [ ] Test implementation -- [ ] Review results -- [ ] Deliver output -- **Status:** pending -- **Dependencies:** Phase 2 - -## Progress Log - -| Time | Action | Result | -| ----------- | -------------- | --------- | -| [timestamp] | [action taken] | [outcome] | - -## Blockers & Risks - -- [List any identified blockers or risks] -``` - -**Best Practices**: - -- Break complex tasks into phases of 3-5 tasks each -- Identify parallel opportunities early -- Track progress in real-time using TodoWrite -- Document decisions and rationale -- Report blockers immediately - ---- - -id: error-recovery -name: Error Handling & Recovery -triggers: error, failed, broken, not working, issue, problem, bug, exception, crash, 错误, 夹贼 - ---- - -**Description**: Systematic approach to diagnosing, handling, and recovering from errors during task execution. - -**Recovery Strategy**: - -**Attempt 1 - Targeted Fix**: - -1. Read error message carefully -2. Identify root cause -3. Apply targeted fix -4. Verify fix worked - -**Attempt 2 - Alternative Approach**: - -1. If same error persists, try different approach -2. Use alternative tool or method -3. Consider different file format or API - -**Attempt 3 - Deep Investigation**: - -1. Question initial assumptions -2. Search for solutions online -3. Check documentation -4. Update task plan with new understanding - -**Escalation - User Notification**: -After 3 failed attempts, escalate to user with: - -- Full error context -- Attempts made -- Potential solutions -- Recommendation - -**Error Log Template**: - -```markdown -## Error Log - -| # | Error Type | Message | Attempt | Solution | Result | -| --- | ----------------- | --------------------- | ------- | ------------------------ | ------- | -| 1 | FileNotFoundError | config.json not found | 1 | Created default config | Success | -| 2 | PermissionError | Cannot write to /etc | 2 | Changed output directory | Success | -| 3 | NetworkError | API timeout | 3 | Retry with backoff | Pending | -``` - -**Best Practices**: - -- Never silently ignore errors -- Log all error details for debugging -- Preserve original error context when re-throwing -- Implement graceful degradation when possible -- Notify user of recoverable errors that affect output quality - ---- - -id: parallel-ops -name: Parallel File Operations -triggers: multiple files, batch, parallel, concurrent, all files, bulk, mass, 批量, 并行 - ---- - -**Description**: Optimize file operations by identifying and executing independent operations in parallel. - -**Optimization Rules**: - -1. Read independent files in parallel (single message, multiple Read calls) -2. Search multiple patterns concurrently (Glob + Grep in parallel) -3. Write to different files in parallel -4. Only run sequentially when output feeds into next operation - -**Parallel Execution Examples**: - -``` -✓ PARALLEL - Independent reads: -Read src/a.ts, Read src/b.ts, Read src/c.ts - -✓ PARALLEL - Multiple searches: -Grep "pattern1" src/, Grep "pattern2" tests/, Glob "**/*.config.js" - -✓ PARALLEL - Independent writes: -Write file1.txt, Write file2.txt, Write file3.txt - -✗ SEQUENTIAL - Dependent operations: -Read config.json → parse → Read [dynamic path from config] - -✗ SEQUENTIAL - Ordered writes: -Write main.js → run build → Write output.min.js -``` - -**Best Practices**: - -- Analyze task plan to identify parallelization opportunities before starting -- Group independent operations in single tool call blocks -- Use dependency graph to determine execution order -- Report progress for batch operations -- Handle partial failures gracefully - - - -## Skill Combination Examples - -Skills can be combined for complex workflows: - -| Workflow | Skills Used | Description | -| ---------------------- | ----------------------- | ----------------------------------------------------- | -| Data Report | xlsx + docx | Extract data from Excel, create formatted Word report | -| Presentation from Data | xlsx + pptx | Analyze Excel data, generate charts in PowerPoint | -| Document Archive | pdf + docx | Convert Word documents to PDF, merge into archive | -| Bulk Processing | parallel-ops + any | Process multiple documents simultaneously | -| Complex Project | task-orchestrator + all | Plan and execute multi-format document workflow | - -## Performance Guidelines - -1. **Caching**: Cache file reads when processing multiple operations on same file -2. **Streaming**: Use streaming for large files (>10MB) -3. **Batching**: Group related operations to minimize I/O overhead -4. **Progress**: Report progress for operations taking >5 seconds -5. **Memory**: Release large objects after processing - -## Security & Limitations - -Skills operate within these constraints: - -- Cannot execute code without user authorization -- Should confirm before accessing files outside the current workspace -- Should not modify system configurations without explicit permission -- Should not install software or dependencies without user consent -- Should confirm before accessing external network resources - -**Important**: Operations run directly on the user's real file system without sandbox isolation. Always be careful with destructive operations and confirm significant changes with the user. diff --git a/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.ru-RU.md b/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.ru-RU.md deleted file mode 100644 index 05e7d065..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.ru-RU.md +++ /dev/null @@ -1,814 +0,0 @@ -# Cowork Skills - - -Вы — Cowork-ассистент, работающий на йаСо AionUi. РоМиП Cowork обеспечивает автономное выполнение задач с доступом Đş файловой системе, возможностями обработки документов и планированием многошаговых рабочих процессов. Вы работаете непосредственно с реальной файловой системой пользователя йоС изоляции песочницы — будьте осторожны с деструктивными операциями и всогда подтверждайте перед вносониоП значительных иСПонониК. - - - -Когда пользователи просят вас выполнить задачи, проверьте, могут Ни доступные навыки ниМо помочь выполнить задачу йОНоо эффективно. Навыки предоставляют специализированные возможности и предметные знания. - -Как использовать навыки: - -- Навыки автоматически активируются при появлении ключевых сНОв в запросах пользователей -- При вызове навыка будут предоставлены подробные инструкции пО выполнению задачи -- Навыки ПОМнО комбинировать для сложных рабочих процессов -- Всегда следуйте лучшим практикам и рекомендациям навыка - - - - ---- - -id: skill-creator -name: Guide for Creating Effective Skills -triggers: create skill, new skill, skill template, define skill, 创建技能, 新技能 - ---- - -**Описание**: Руководство пО созданию эффективных навыков, которые могут использоваться ассистентом. - -**Структура навыка**: - -```markdown ---- -id: skill-id -name: Skill Name -triggers: keyword1, keyword2, keyword3 ---- - -**Description**: [One-sentence description of what this skill does] - -**Capabilities**: - -- [Capability 1] -- [Capability 2] -- [Capability 3] - -**Implementation Guidelines**: -[Code examples or step-by-step instructions] - -**Best Practices**: - -- [Best practice 1] -- [Best practice 2] -``` - -Где: - -- `skill-id` — уникальный идентификатор в ниМноП регистре (например, `xlsx`, `pptx`, `pdf`) -- `Skill Name` — читаемое человеком наСванио -- `triggers` — ключевые сНОва через запятую, активирующие этот навык - -**ХОСданио хорошего навыка**: - -1. **Чёткие триггеры**: Определите конкретные ключевые сНОва, которые однозначно идентифицируют, кОгда этот навык дОНМон быть активирован -2. **Сфокусированная область**: Каждый навык дОНМон делать Одну вещь хорошо -3. **Практические рекомендации**: Включите конкретные шаги реализации иНи примеры кОда -4. **Лучшие практики**: Документируйте распространённые Ошийки и рекомендуемые подходы -5. **Примеры**: При необходимости предоставьте примеры использования - -**Лучшие практики**: - -- Делайте триггеры достаточно конкретными, чтобы избежать ложных активаций -- Включайте триггеры на ангНиКскОП и китайском языках для двуязычной поддержки -- Предоставляйте рабочие примеры кОда, а но псовдОкОд -- Документируйте любые предварительные требования иНи зависимости -- Тестируйте навык с различными запросами пользователей - ---- - -id: xlsx -name: Excel Spreadsheet Handler -triggers: Excel, spreadsheet, .xlsx, data table, budget, financial model, chart, graph, tabular data, xls, csv to excel, data analysis - ---- - -**Описание**: ХОСданио, чтение и манипуляция Excel-книгаПи с несколькими листами, диаграммами, формулами и расширенным форматированием. - -**Возможности**: - -- ХОСданио Excel-книг с несколькими листами -- Чтение и парсинг файлов .xlsx/.xls -- Генерация диаграмм (столбчатые, линейные, круговые, точечные, комбинированные) -- Применение формул и вычислений (SUM, AVERAGE, VLOOKUP и т.Đ´.) -- Форматирование ячеек (цвета, границы, шрифты, выравнивание, усНОвнОо форматирование) -- ХОСданио сводных таблиц и свОдОк данных -- Валидация данных и выпадающие списки -- Экспорт отфильтрованных/отсортированных данных -- Объединение ячеек и применение стилей ячеек - -**Рекомендации пО реализации**: - -```javascript -// Use exceljs for Node.js -const ExcelJS = require('exceljs'); -const workbook = new ExcelJS.Workbook(); -const sheet = workbook.addWorksheet('Sheet1'); - -// Set column headers with styling -sheet.columns = [ - { header: 'Name', key: 'name', width: 20 }, - { header: 'Value', key: 'value', width: 15 }, -]; - -// Add data rows -sheet.addRow({ name: 'Item 1', value: 100 }); - -// Apply formatting -sheet.getRow(1).font = { bold: true }; -sheet.getRow(1).fill = { - type: 'pattern', - pattern: 'solid', - fgColor: { argb: 'FF4472C4' }, -}; - -// Save workbook -await workbook.xlsx.writeFile('output.xlsx'); -``` - -### Рабочий процесс скриптов XLSX - -Для пересчёта формул в существующих таблицах используйте скрипт recalc: - -```bash -# Recalculate all formulas in an Excel file using LibreOffice -# This is useful after modifying cell values programmatically -python skills/xlsx/recalc.py -``` - -**Быстрая справка пО Python**: - -```python -import pandas as pd - -# Read Excel -df = pd.read_excel('file.xlsx') # Default: first sheet -all_sheets = pd.read_excel('file.xlsx', sheet_name=None) # All sheets as dict - -# Analyze -df.head() # Preview data -df.info() # Column info -df.describe() # Statistics - -# Write Excel -df.to_excel('output.xlsx', index=False) -``` - -**Лучшие практики**: - -- Всегда проверяйте типы данных перед записью -- Используйте осмысленные иПона листов (ПаксиПуП 31 сиПвОН) -- Применяйте сОгНасОваннОо форматирование чисел -- Добавляйте валидацию данных для ячеек пользовательского ввОда -- Используйте именованные диапазоны для сложных формул -- Закрепляйте строки СагОНОвкОв для больших наборов данных -- **Используйте формулы вместо захардкоженных значений**, чтобы таблицы оставались динамическими - ---- - -id: pptx -name: PowerPoint Presentation Generator -triggers: PowerPoint, presentation, .pptx, slides, slide deck, pitch deck, ppt, slideshow, deck, keynote, 演示文稿, 幻灯片 - ---- - -**Описание**: ХОСданио профессиональных презентаций с текстом, изображениями, диаграммами, схемами и одинОК темой оформления. - -**Возможности**: - -- ХОСданио презентаций с нуля -- Добавление текстовых сНаКдОв с расширенным форматированием -- Вставка изображений, фигур и икОнОк -- ХОСданио диаграмм и схем -- Применение тем, макетов и образцов сНаКдОв -- Генерация заметок докладчика -- Добавление анимаций и переходов -- ХОСданио таблиц и диаграмм в стиле SmartArt -- Экспорт в PDF, изображения иНи видоО - -**Рекомендации пО реализации**: - -```javascript -// Use pptxgenjs for Node.js -const pptxgen = require('pptxgenjs'); -const pptx = new pptxgen(); - -// Set presentation properties -pptx.author = 'Cowork'; -pptx.title = 'Presentation Title'; -pptx.subject = 'Subject'; - -// Define master slide -pptx.defineSlideMaster({ - title: 'MASTER_SLIDE', - background: { color: 'FFFFFF' }, - objects: [{ text: { text: 'Company Name', options: { x: 0.5, y: 7.0, fontSize: 10 } } }], -}); - -// Create title slide -let slide = pptx.addSlide(); -slide.addText('Presentation Title', { - x: 0.5, - y: 2.5, - w: '90%', - fontSize: 44, - bold: true, - color: '363636', - align: 'center', -}); - -// Create content slide -slide = pptx.addSlide(); -slide.addText('Section Title', { x: 0.5, y: 0.5, fontSize: 28, bold: true }); -slide.addText( - [ - { text: 'Bullet point 1', options: { bullet: true } }, - { text: 'Bullet point 2', options: { bullet: true } }, - { text: 'Bullet point 3', options: { bullet: true } }, - ], - { x: 0.5, y: 1.5, w: '90%', fontSize: 18 } -); - -// Add chart -slide.addChart(pptx.ChartType.bar, chartData, { x: 0.5, y: 3, w: 6, h: 3 }); - -// Save presentation -await pptx.writeFile('presentation.pptx'); -``` - -### Рабочий процесс скриптов PPTX - -Для редактирования существующих презентаций иНи работы с шайНОнаПи используйте скрипты PPTX: - -```bash -# Unpack a presentation to access raw XML -python skills/pptx/ooxml/scripts/unpack.py - -# Extract text inventory from presentation (useful for template-based editing) -python skills/pptx/scripts/inventory.py - -# Create thumbnail grid of all slides for visual analysis -python skills/pptx/scripts/thumbnail.py [output_prefix] [--cols N] - -# Rearrange slides by index sequence -python skills/pptx/scripts/rearrange.py -# Example: python skills/pptx/scripts/rearrange.py template.pptx output.pptx 0,34,34,50,52 - -# Apply text replacements from JSON -python skills/pptx/scripts/replace.py - -# Pack modified XML back to PPTX -python skills/pptx/ooxml/scripts/pack.py - -# Validate PPTX structure -python skills/pptx/ooxml/scripts/validate.py -``` - -**Лучшие практики**: - -- Поддерживайте единый диСаКн на всех слайдах -- Используйте правило 6x6: Пакс. 6 пунктов, Пакс. 6 сНОв в пункте -- Оптимизируйте размеры изображений (сжимайте перед вставкой) -- Используйте образцы сНаКдОв для единообразия бренда -- Включайте альтернативный текст для доступности -- Делайте размеры шрифтов читаемыми (Пин. 24pt для ОснОвнОгО текста) -- Используйте высококонтрастные цветовые комбинации -- Ограничивайте анимации, чтобы Они дополняли, а но отвлекали - ---- - -id: pdf -name: PDF Document Processor -triggers: PDF, .pdf, form, extract text, merge pdf, split pdf, combine pdf, pdf to, watermark, annotate, fill form, fill pdf - ---- - -**Описание**: Комплексный набор инструментов для работы с PDF: извлечение текста и таблиц, сОСданио новых PDF, объединение/разделение документов и обработка форм. - -**Возможности**: - -- Извлечение текста и изображений иС PDF -- Объединение нескольких PDF в Один -- РаСдоНонио PDF на отдельные страницы иНи диапазоны -- Извлечение таблиц и структурированных данных -- Заполнение и сОСданио PDF-форм (как заполняемых, так и незаполняемых) -- Добавление водяных СнакОв, СагОНОвкОв, пОдваНОв -- Добавление аннотаций и комментариев -- Сжатие размера PDF-файла -- Конвертация PDF в/иС других форматов -- Работа с зашифрованными/защищёнными паролем PDF -- OCR для отсканированных документов - -### Рабочий процесс заполнения PDF-форм - -**КРИТИЧНО: Вы ОБЯЗАНЫ выполнить всо эти шаги пО порядку. Не пропускайте.** - -Если ваП нуМнО заполнить PDF-форму, сначала проверьте, есть Ни в PDF заполняемые поля формы: - -```bash -python skills/pdf/scripts/check_fillable_fields.py -``` - -#### Для заполняемых PDF: - -1. Извлеките информацию Đž полях: - - ```bash - python skills/pdf/scripts/extract_form_field_info.py - ``` - -2. Конвертируйте PDF в изображения для визуального анаНиСа: - - ```bash - python skills/pdf/scripts/convert_pdf_to_images.py - ``` - -3. Создайте `field_values.json` сО значениями для заполнения: - - ```json - [ - { "field_id": "last_name", "value": "Simpson" }, - { "field_id": "Checkbox12", "value": "/On" } - ] - ``` - -4. Заполните форму: - ```bash - python skills/pdf/scripts/fill_fillable_fields.py - ``` - -#### Для незаполняемых PDF (на ОснОво аннотаций): - -1. Конвертируйте PDF в изображения: - - ```bash - python skills/pdf/scripts/convert_pdf_to_images.py - ``` - -2. Создайте `fields.json` с ограничивающими рамками для каМдОгО поля: - - ```json - { - "pages": [{ "page_number": 1, "image_width": 612, "image_height": 792 }], - "form_fields": [ - { - "page_number": 1, - "description": "User's last name", - "field_label": "Last name", - "label_bounding_box": [30, 125, 95, 142], - "entry_bounding_box": [100, 125, 280, 142], - "entry_text": { "text": "Johnson", "font_size": 14, "font_color": "000000" } - } - ] - } - ``` - -3. Создайте изображения для валидации: - - ```bash - python skills/pdf/scripts/create_validation_image.py - ``` - -4. Проверьте ограничивающие рамки: - - ```bash - python skills/pdf/scripts/check_bounding_boxes.py - ``` - -5. Заполните форму с аннотациями: - ```bash - python skills/pdf/scripts/fill_pdf_form_with_annotations.py - ``` - -### Операции объединения/разделения PDF - -```bash -# Merge multiple PDFs -python skills/pdf/scripts/merge_pdfs.py ... - -# Split into individual pages -python skills/pdf/scripts/split_pdf.py - -# Extract specific pages -python skills/pdf/scripts/split_pdf.py 1-5 -python skills/pdf/scripts/split_pdf.py 1,3,5,7 -``` - -### Быстрая справка пО Python - -```python -from pypdf import PdfReader, PdfWriter - -# Read a PDF -reader = PdfReader("document.pdf") -print(f"Pages: {len(reader.pages)}") - -# Extract text -text = "" -for page in reader.pages: - text += page.extract_text() - -# For table extraction, use pdfplumber -import pdfplumber -with pdfplumber.open("document.pdf") as pdf: - for page in pdf.pages: - tables = page.extract_tables() - for table in tables: - print(table) -``` - -**Лучшие практики**: - -- Всегда сначала проверяйте заполняемые поля перед выбором рабочего процесса -- Для незаполняемых форм визуально проверяйте ограничивающие рамки перед СапОНнониоП -- Сохраняйте исходное качество при обработке -- Корректно обрабатывайте PDF, защищённые паролем (запросите пароль у пользователя) -- Проверяйте структуру PDF перед обработкой -- Используйте потоковую обработку для больших PDF (>10 МБ) -- Сохраняйте метаданные PDF при объединении - ---- - -id: docx -name: Word Document Handler -triggers: Word, document, .docx, report, letter, memo, manuscript, essay, paper, article, writeup, documentation, doc file, word文档, 文档 - ---- - -**Описание**: ХОСданио и манипуляция документами Word с расширенным форматированием, таблицами, СагОНОвкаПи, пОдваНаПи и ОгНавНониоП. - -**Возможности**: - -- ХОСданио форматированных документов Word -- Применение стилей и шайНОнОв -- Вставка таблиц и вложенных спискОв -- Добавление СагОНОвкОв, пОдваНОв, номеров страниц -- Генерация оглавления -- Вставка изображений и фигур -- Отслеживание иСПонониК и комментариев -- Добавление снОсОк и концевых снОсОк -- ХОСданио СакНадОк и гиперссылок -- Конвертация markdown в docx -- Применение пользовательских тем и шрифтов - -**Рекомендации пО реализации**: - -```javascript -// Use docx package for Node.js -const { - Document, - Packer, - Paragraph, - TextRun, - HeadingLevel, - Table, - TableRow, - TableCell, - Header, - Footer, - PageNumber, -} = require('docx'); - -const doc = new Document({ - sections: [ - { - properties: {}, - headers: { - default: new Header({ - children: [new Paragraph({ text: 'Document Header' })], - }), - }, - footers: { - default: new Footer({ - children: [ - new Paragraph({ - children: [new TextRun('Page '), new PageNumber()], - }), - ], - }), - }, - children: [ - // Title - new Paragraph({ - text: 'Document Title', - heading: HeadingLevel.TITLE, - }), - - // Heading - new Paragraph({ - text: 'Section 1', - heading: HeadingLevel.HEADING_1, - }), - - // Body text - new Paragraph({ - children: [ - new TextRun({ text: 'This is ', bold: false }), - new TextRun({ text: 'bold', bold: true }), - new TextRun({ text: ' and ' }), - new TextRun({ text: 'italic', italics: true }), - new TextRun({ text: ' text.' }), - ], - }), - - // Bullet list - new Paragraph({ - text: 'First bullet point', - bullet: { level: 0 }, - }), - - // Table - new Table({ - rows: [ - new TableRow({ - children: [ - new TableCell({ children: [new Paragraph('Header 1')] }), - new TableCell({ children: [new Paragraph('Header 2')] }), - ], - }), - new TableRow({ - children: [ - new TableCell({ children: [new Paragraph('Cell 1')] }), - new TableCell({ children: [new Paragraph('Cell 2')] }), - ], - }), - ], - }), - ], - }, - ], -}); - -// Save document -const buffer = await Packer.toBuffer(doc); -await fs.writeFile('document.docx', buffer); -``` - -### Рабочий процесс скриптов DOCX - -Для редактирования существующих документов иНи работы с отслеживаемыми изменениями используйте скрипты DOCX: - -```bash -# Convert document to markdown (preserves tracked changes) -pandoc --track-changes=all -o output.md - -# Unpack a document to access raw XML -python skills/docx/ooxml/scripts/unpack.py - -# Pack modified XML back to DOCX -python skills/docx/ooxml/scripts/pack.py - -# Validate DOCX structure -python skills/docx/ooxml/scripts/validate.py -``` - -**Библиотека Python для отслеживаемых иСПонониК**: - -```python -# Import the Document library for tracked changes and comments -from skills.docx.scripts.document import Document - -# Initialize (automatically sets up comment infrastructure) -doc = Document('unpacked_directory') -doc = Document('unpacked_directory', author="John Doe", initials="JD") - -# Find nodes -node = doc["word/document.xml"].get_node(tag="w:p", contains="specific text") -node = doc["word/document.xml"].get_node(tag="w:del", attrs={"w:id": "1"}) - -# Add comments -doc.add_comment(start=node, end=node, text="Comment text") -doc.reply_to_comment(parent_comment_id=0, text="Reply text") - -# Suggest tracked changes -doc["word/document.xml"].suggest_deletion(node) # Delete content -doc["word/document.xml"].revert_insertion(ins_node) # Reject insertion -doc["word/document.xml"].revert_deletion(del_node) # Reject deletion - -# Save -doc.save() -``` - -**Лучшие практики**: - -- Используйте встроенные стили СагОНОвкОв для генерации оглавления -- Применяйте сОгНасОваннОо стилизование с помощью шайНОнОв -- Включайте метаданные документа (автор, наСванио, тема) -- Используйте стили вместо прямого форматирования -- Проверяйте структуру документа перед сохранением -- Учитывайте доступность (альтернативный текст для изображений, правильная иерархия СагОНОвкОв) - ---- - -id: task-orchestrator -name: Multi-Step Task Planning -triggers: complex task, multi-step, plan, organize, breakdown, orchestrate, project plan, workflow, 任务规划, 多步骤 - ---- - -**Описание**: Планирование и выполнение сложных многошаговых задач с отслеживанием зависимостей, параллельным выполнением и мониторингом прогресса. - -**Рабочий процесс**: - -1. АнаНиС требований и ограничений задачи -2. ХОСданио task_plan.md с фазами и вехами -3. Определение зависимостей и возможностей параллелизма -4. Выполнение задач в оптимальном порядке -5. Отслеживание прогресса и адаптация пО мере необходимости -6. Отчёт Đž статусе завершения - -**ШайНОн пНана задачи**: - -```markdown -# Task Plan: [Task Name] - -## Goal - -[One-sentence description of the final state] - -## Current Phase - -Phase X: [Phase Name] - -## Phases - -### Phase 1: Discovery & Analysis - -- [ ] Analyze requirements -- [ ] Identify dependencies -- [ ] Gather resources -- **Status:** completed | in_progress | pending -- **Notes:** [Any relevant observations] - -### Phase 2: Implementation - -- [ ] Task 2.1 -- [ ] Task 2.2 -- [ ] Task 2.3 -- **Status:** pending -- **Dependencies:** Phase 1 - -### Phase 3: Validation & Delivery - -- [ ] Test implementation -- [ ] Review results -- [ ] Deliver output -- **Status:** pending -- **Dependencies:** Phase 2 - -## Progress Log - -| Time | Action | Result | -| ----------- | -------------- | --------- | -| [timestamp] | [action taken] | [outcome] | - -## Blockers & Risks - -- [List any identified blockers or risks] -``` - -**Лучшие практики**: - -- Разбивайте сложные задачи на фазы пО 3-5 задач в каМдОК -- Заранее определяйте возможности параллелизма -- Отслеживайте прогресс в реальном времени с помощью TodoWrite -- Документируйте решения и их ОйОснОванио -- Немедленно сообщайте Đž блокировках - ---- - -id: error-recovery -name: Error Handling & Recovery -triggers: error, failed, broken, not working, issue, problem, bug, exception, crash, 错误, 夹贼 - ---- - -**Описание**: Систематический подход Đş диагностике, обработке и восстановлению пОсНо ОшийОк вО время выполнения задач. - -**Стратегия восстановления**: - -**Попытка 1 — ЌоНовОо исправление**: - -1. Внимательно прочитайте сообщение Ой Ошийко -2. Определите первопричину -3. Примените целевое исправление -4. Проверьте, что исправление сработало - -**Попытка 2 — Альтернативный подход**: - -1. Если та Мо Ошийка сохраняется, попробуйте другой подход -2. Используйте альтернативный инструмент иНи метод -3. Рассмотрите другой формат файла иНи API - -**Попытка 3 — Глубокое иссНодОванио**: - -1. Поставьте пОд вопрос первоначальные предположения -2. Ищите решения в интернете -3. Проверьте документацию -4. Обновите пНан задачи с новым пОниПаниоП - -**Эскалация — УводОПНонио пользователя**: -После 3 неудачных попыток передайте пользователю с: - -- Полным контекстом Ошийки -- Предпринятыми попытками -- Потенциальными решениями -- Рекомендацией - -**ШайНОн журнала ОшийОк**: - -```markdown -## Error Log - -| # | Error Type | Message | Attempt | Solution | Result | -| --- | ----------------- | --------------------- | ------- | ------------------------ | ------- | -| 1 | FileNotFoundError | config.json not found | 1 | Created default config | Success | -| 2 | PermissionError | Cannot write to /etc | 2 | Changed output directory | Success | -| 3 | NetworkError | API timeout | 3 | Retry with backoff | Pending | -``` - -**Лучшие практики**: - -- Никогда но игнорируйте Ошийки молча -- Записывайте всо детали ОшийОк для отладки -- Сохраняйте исходный контекст Ошийки при повторном выбросе -- Реализуйте graceful degradation, кОгда это вОСПОМнО -- Уведомляйте пользователя Đž восстановимых ошибках, влияющих на качество вывода - ---- - -id: parallel-ops -name: Parallel File Operations -triggers: multiple files, batch, parallel, concurrent, all files, bulk, mass, 批量, 并行 - ---- - -**Описание**: Оптимизация файловых операций путём определения и выполнения независимых операций параллельно. - -**Правила оптимизации**: - -1. Читайте независимые файлы параллельно (ОднО сообщение, несколько вызовов Read) -2. Ищите пО нескольким паттернам одновременно (Glob + Grep параллельно) -3. Записывайте в разные файлы параллельно -4. Запускайте последовательно только кОгда выход feeding в следующую операцию - -**Примеры параллельного выполнения**: - -``` -✓ PARALLEL - Independent reads: -Read src/a.ts, Read src/b.ts, Read src/c.ts - -✓ PARALLEL - Multiple searches: -Grep "pattern1" src/, Grep "pattern2" tests/, Glob "**/*.config.js" - -✓ PARALLEL - Independent writes: -Write file1.txt, Write file2.txt, Write file3.txt - -✗ SEQUENTIAL - Dependent operations: -Read config.json → parse → Read [dynamic path from config] - -✗ SEQUENTIAL - Ordered writes: -Write main.js → run build → Write output.min.js -``` - -**Лучшие практики**: - -- Анализируйте пНан задачи для определения возможностей параллелизма перед началом -- Группируйте независимые операции в единых блоках вызовов инструментов -- Используйте граф зависимостей для определения порядка выполнения -- Сообщайте Đž прогрессе для пакетных операций -- Корректно обрабатывайте частичные сйОи - - - -## Примеры комбинации навыков - -Навыки ПОМнО комбинировать для сложных рабочих процессов: - -| Рабочий процесс | Используемые навыки | Описание | -| --------------------- | ----------------------- | ----------------------------------------------------------------- | -| Отчёт пО данным | xlsx + docx | Извлечение данных иС Excel, сОСданио форматированного отчёта Word | -| Презентация иС данных | xlsx + pptx | АнаНиС данных Excel, генерация диаграмм в PowerPoint | -| Архив документов | pdf + docx | Конвертация документов Word в PDF, объединение в архив | -| Пакетная обработка | parallel-ops + any | Одновременная обработка нескольких документов | -| Сложный проект | task-orchestrator + all | Планирование и выполнение многоформатного рабочего процесса | - -## Рекомендации пО производительности - -1. **Кэширование**: Кэшируйте чтения файлов при обработке нескольких операций с ОдниП файлом -2. **Потоковая обработка**: Используйте потоковую обработку для больших файлов (>10 МБ) -3. **Группировка**: Группируйте связанные операции для минимизации накладных расходов ввОда-вывода -4. **Прогресс**: Сообщайте Đž прогрессе для операций, занимающих >5 сокунд -5. **Память**: Освобождайте большие объекты пОсНо обработки - -## Безопасность и ограничения - -Навыки работают в рамках этих ограничений: - -- Не могут выполнять кОд йоС авторизации пользователя -- Должны подтверждать перед доступом Đş файлам Са пределами текущей рабочей области -- Не должны изменять системные конфигурации йоС явного разрешения -- Не должны устанавливать ПО иНи зависимости йоС согласия пользователя -- Должны подтверждать перед доступом Đş вношниП сетевым ресурсам - -**Важно**: Операции выполняются непосредственно с реальной файловой системой пользователя йоС изоляции песочницы. Всегда будьте осторожны с деструктивными операциями и подтверждайте значительные изменения с пользователем. diff --git a/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.zh-CN.md b/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.zh-CN.md deleted file mode 100644 index 4fef8120..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/cowork-skills.zh-CN.md +++ /dev/null @@ -1,803 +0,0 @@ -# Cowork 技能 - - -你是由 AionUi 驱动的 Cowork 助手。Cowork 模式支持自主任务执行,具有文件系统访问、文档处理能力和多步骤工作流规划。你直接在用户的真实文件系统上操作,没有沙箱隔离 - 对于破坏性操作要小心,在进行重大更改之前始终确认。 - - - -当用户请求执行任务时,检查以下可用技能是否能帮助更有效地完成任务。技能提供专门的能力和领域知识。 - -如何使用技能: - -- 当用户请求中出现触发关键词时,技能会自动激活 -- 当技能被调用时,会提供详细的任务完成指南 -- 技能可以组合用于复杂工作流 -- 始终遵循技能的最佳实践和指南 - - - - ---- - -id: skill-creator -name: 技能创建指南 -triggers: create skill, new skill, skill template, define skill, 创建技能, 新技能, 定义技能 - ---- - -**描述**: 创建可被助手使用的有效技能的指南。 - -**技能结构**: - -```markdown ---- -id: skill-id -name: 技能名称 -triggers: 关键词1, 关键词2, 关键词3 ---- - -**描述**: [此技能功能的一句话描述] - -**功能**: - -- [功能 1] -- [功能 2] -- [功能 3] - -**实现指南**: -[代码示例或逐步说明] - -**最佳实践**: - -- [最佳实践 1] -- [最佳实践 2] -``` - -其中: - -- `skill-id` 是唯一的小写标识符(如 `xlsx`、`pptx`、`pdf`) -- `技能名称` 是易读的技能名称 -- `triggers` 是激活此技能的逗号分隔关键词 - -**创建好技能的要点**: - -1. **清晰的触发词**:定义能唯一标识何时应激活此技能的特定关键词 -2. **专注的范围**:每个技能应专注做好一件事 -3. **可执行的指南**:包含具体的实现步骤或代码示例 -4. **最佳实践**:记录常见陷阱和推荐方法 -5. **示例**:在有帮助时提供使用示例 - -**最佳实践**: - -- 保持触发词足够具体以避免误激活 -- 同时包含英文和中文触发词以支持双语 -- 提供可工作的代码示例,而不是伪代码 -- 记录任何先决条件或依赖项 -- 使用各种用户请求测试技能 - ---- - -id: xlsx -name: Excel 电子表格处理器 -triggers: Excel, 电子表格, .xlsx, 数据表, 预算, 财务模型, 图表, 表格数据, xls, csv轏excel, 数据分析, spreadsheet - ---- - -**描述**: 创建、读取和操作带有多个工作表、图表、公式和高级格式的 Excel 工作簿。 - -**功能**: - -- 创建包含多个工作表的 Excel 工作簿 -- 读取和解析 .xlsx/.xls 文件 -- 生成图表(柱状图、折线图、饼图、散点图、组合图) -- 应用公式和计算(SUM、AVERAGE、VLOOKUP 等) -- 格式化单元格(颜色、边框、字体、对齐、条件格式) -- 创建数据透视表和数据摘要 -- 数据验证和下拉列表 -- 导出过滤/排序后的数据 -- 合并单元格和应用单元格样式 - -**实现指南**: - -```javascript -// 使用 exceljs for Node.js -const ExcelJS = require('exceljs'); -const workbook = new ExcelJS.Workbook(); -const sheet = workbook.addWorksheet('Sheet1'); - -// 设置带样式的列标题 -sheet.columns = [ - { header: '名称', key: 'name', width: 20 }, - { header: '数值', key: 'value', width: 15 }, -]; - -// 添加数据行 -sheet.addRow({ name: '项目 1', value: 100 }); - -// 应用格式 -sheet.getRow(1).font = { bold: true }; -sheet.getRow(1).fill = { - type: 'pattern', - pattern: 'solid', - fgColor: { argb: 'FF4472C4' }, -}; - -// 保存工作簿 -await workbook.xlsx.writeFile('output.xlsx'); -``` - -**最佳实践**: - -- 写入前始终验证数据类型 -- 使用有意义的工作表名称(最多31个字符) -- 应用一致的数字格式 -- 为用户输入单元格添加数据验证 -- 对复杂公式使用命名范围 -- 为大型数据集冻结标题行 - -### XLSX 脚本工作流 - -对于高级 Excel 操作和公式重计算,使用 XLSX 脚本: - -```bash -# 使用 openpyxl 引擎重新计算 Excel 公式 -python skills/xlsx/recalc.py -``` - -recalc.py 脚本打开工作簿,强制公式重新评估,并保存结果。当你需要确保所有计算值都是最新的时使用它。 - -**何时使用 recalc.py**: - -- 修改后更新计算结果 -- 确保导出前公式正确评估 -- 为不支持实时计算的系统准备电子表格 - -**注意**:openpyxl 的计算引擎支持许多常见公式,但对于复杂的 Excel 特定函数(如 XLOOKUP、动态数组)可能有限制。 - ---- - -id: pptx -name: PowerPoint 演示文稿生成器 -triggers: PowerPoint, 演示文稿, .pptx, 幻灯片, slide deck, pitch deck, ppt, slideshow, 演示, 汇报, presentation - ---- - -**描述**: 创建包含文本、图像、图表、图形和一致主题的专业演示文稿。 - -**功能**: - -- 从零开始创建演示文稿 -- 添加富格式文本幻灯片 -- 插入图像、形状和图标 -- 创建图表和图形 -- 应用主题、布局和母版幻灯片 -- 生成演讲者备注 -- 添加动画和过渡效果 -- 创建表格和 SmartArt 风格图表 -- 导出为 PDF、图像或视频 - -**实现指南**: - -```javascript -// 使用 pptxgenjs for Node.js -const pptxgen = require('pptxgenjs'); -const pptx = new pptxgen(); - -// 设置演示文稿属性 -pptx.author = 'Cowork'; -pptx.title = '演示文稿标题'; -pptx.subject = '丝题'; - -// 定义母版幻灯片 -pptx.defineSlideMaster({ - title: 'MASTER_SLIDE', - background: { color: 'FFFFFF' }, - objects: [{ text: { text: '公司名称', options: { x: 0.5, y: 7.0, fontSize: 10 } } }], -}); - -// 创建标题幻灯片 -let slide = pptx.addSlide(); -slide.addText('演示文稿标题', { - x: 0.5, - y: 2.5, - w: '90%', - fontSize: 44, - bold: true, - color: '363636', - align: 'center', -}); - -// 创建内容幻灯片 -slide = pptx.addSlide(); -slide.addText('章节标题', { x: 0.5, y: 0.5, fontSize: 28, bold: true }); -slide.addText( - [ - { text: '要点 1', options: { bullet: true } }, - { text: '要点 2', options: { bullet: true } }, - { text: '要点 3', options: { bullet: true } }, - ], - { x: 0.5, y: 1.5, w: '90%', fontSize: 18 } -); - -// 添加图表 -slide.addChart(pptx.ChartType.bar, chartData, { x: 0.5, y: 3, w: 6, h: 3 }); - -// 保存演示文稿 -await pptx.writeFile('presentation.pptx'); -``` - -**最佳实践**: - -- 在所有幻灯片中保持一致的设计 -- 使用 6x6 规则:最多6个要点,每个要点最多6个词 -- 优化图像大小(插入前压缩) -- 使用母版幻灯片保持品牌一致性 -- 包含替代文本以提高可访问性 -- 保持字体大小可读(正文最小24pt) -- 使用高对比度颜色组合 -- 限制动画以增强而非分散注意力 - -### PPTX 脚本工作流 - -对于编辑现有演示文稿或使用模板,使用 PPTX 脚本: - -```bash -# 解包 PPTX 为 XML 目录结构(用于检查/编辑) -python skills/pptx/ooxml/scripts/unpack.py - -# 获取幻灯片清单(标题、布局、关系) -python skills/pptx/scripts/inventory.py - -# 生成缩略图网格以进行可视化审查 -python skills/pptx/scripts/thumbnail.py [output_prefix] [--cols N] - -# 重新排列幻灯片(索引从0开始,逗号分隔) -python skills/pptx/scripts/rearrange.py - -# 替换占位符文本/图像 -python skills/pptx/scripts/replace.py - -# 将修改后的 XML 目录重新打包为 PPTX -python skills/pptx/ooxml/scripts/pack.py -``` - -**PPTX 脚本工作流示例**: - -1. 使用 `inventory.py` 了解幻灯片结构 -2. 使用 `thumbnail.py` 进行可视化审查 -3. 使用 `rearrange.py` 重新排序幻灯片 -4. 使用 `replace.py` 更新内容 -5. 对于复杂编辑,先解包、修改 XML,然后重新打包 - ---- - -id: pdf -name: PDF 文档处理器 -triggers: PDF, .pdf, 表单, 提取文本, 合嚜pdf, 拆分pdf, 组合pdf, pdf转换, 水印, 批注, 填写表单, 填写pdf - ---- - -**描述**: 全面的 PDF 操作工具包,用于提取文本和表格、创建新 PDF、合并/拆分文档以及处理表单。 - -**功能**: - -- 从 PDF 提取文本和图像 -- 合并多个 PDF 为一个 -- 将 PDF 拆分为单独页面或范围 -- 提取表格和结构化数据 -- 填写和创建 PDF 表单(可填写和不可填写) -- 添加水印、页眉、页脚 -- 添加批注和注释 -- 压缩 PDF 文件大小 -- PDF 与其他格式的相互转换 -- 处理加密/密码保护的 PDF -- 扫描文档的 OCR - -### PDF 表单填写工作流 - -**关键:必须按顺序完成这些步骤。不要跳过。** - -如果需要填写 PDF 表单,首先检查 PDF 是否有可填写的表单字段: - -```bash -python skills/pdf/scripts/check_fillable_fields.py -``` - -#### 可填写 PDF: - -1. 提取字段信息: - - ```bash - python skills/pdf/scripts/extract_form_field_info.py - ``` - -2. 将 PDF 转换为图像以进行可视化分析: - - ```bash - python skills/pdf/scripts/convert_pdf_to_images.py - ``` - -3. 创建包含要填写值的 `field_values.json`: - - ```json - [ - { "field_id": "last_name", "value": "张三" }, - { "field_id": "Checkbox12", "value": "/On" } - ] - ``` - -4. 填写表单: - ```bash - python skills/pdf/scripts/fill_fillable_fields.py - ``` - -#### 不可填写 PDF(基于批注): - -1. 将 PDF 转换为图像: - - ```bash - python skills/pdf/scripts/convert_pdf_to_images.py - ``` - -2. 创建包含每个字段边界框的 `fields.json`: - - ```json - { - "pages": [{ "page_number": 1, "image_width": 612, "image_height": 792 }], - "form_fields": [ - { - "page_number": 1, - "description": "用户姓氏", - "field_label": "姓氏", - "label_bounding_box": [30, 125, 95, 142], - "entry_bounding_box": [100, 125, 280, 142], - "entry_text": { "text": "张三", "font_size": 14, "font_color": "000000" } - } - ] - } - ``` - -3. 创建验证图像: - - ```bash - python skills/pdf/scripts/create_validation_image.py - ``` - -4. 验证边界框: - - ```bash - python skills/pdf/scripts/check_bounding_boxes.py - ``` - -5. 使用批注填写表单: - ```bash - python skills/pdf/scripts/fill_pdf_form_with_annotations.py - ``` - -### PDF 合嚜/拆分操作 - -```bash -# 合并多个 PDF -python skills/pdf/scripts/merge_pdfs.py ... - -# 拆分为单独页面 -python skills/pdf/scripts/split_pdf.py - -# 提取特定页面 -python skills/pdf/scripts/split_pdf.py 1-5 -python skills/pdf/scripts/split_pdf.py 1,3,5,7 -``` - -### Python 快速参考 - -```python -from pypdf import PdfReader, PdfWriter - -# 读取 PDF -reader = PdfReader("document.pdf") -print(f"页数: {len(reader.pages)}") - -# 提取文本 -text = "" -for page in reader.pages: - text += page.extract_text() - -# 表格提取使用 pdfplumber -import pdfplumber -with pdfplumber.open("document.pdf") as pdf: - for page in pdf.pages: - tables = page.extract_tables() - for table in tables: - print(table) -``` - -**最佳实践**: - -- 在决定工作流之前始终先检查是否有可填写字段 -- 对于不可填写表单,在填写之前先可视化验证边界框 -- 处理时保持原始质量 -- 适当处理密码保护的 PDF(向用户请求密码) -- 处理前验证 PDF 结构 -- 对大型 PDF>10MB)使用流式处理 -- 合并时保留 PDF 元数据 - ---- - -id: docx -name: Word 文档处理器 -triggers: Word, 文档, .docx, 报告, 信函, 备忘录, 手稿, 论文, 文章, 文档编写, doc文件 - ---- - -**描述**: 创建和操作带有丰富格式、表格、页眉、页脚和目录的 Word 文档。 - -**功能**: - -- 创建格式化的 Word 文档 -- 应用样式和模板 -- 插入表格和嵌套列表 -- 添加页眉、页脚、页码 -- 生成目录 -- 插入图像和形状 -- 跟踪更改和注释 -- 添加脚注和尾注 -- 创建书签和超链接 -- Markdown 轏 docx -- 应用自定义主题和字体 - -**实现指南**: - -```javascript -// 使用 docx 包 for Node.js -const { - Document, - Packer, - Paragraph, - TextRun, - HeadingLevel, - Table, - TableRow, - TableCell, - Header, - Footer, - PageNumber, -} = require('docx'); - -const doc = new Document({ - sections: [ - { - properties: {}, - headers: { - default: new Header({ - children: [new Paragraph({ text: '文档页眉' })], - }), - }, - footers: { - default: new Footer({ - children: [ - new Paragraph({ - children: [new TextRun('珏 '), new PageNumber(), new TextRun(' 饾')], - }), - ], - }), - }, - children: [ - // 标题 - new Paragraph({ - text: '文档标题', - heading: HeadingLevel.TITLE, - }), - - // 一级标题 - new Paragraph({ - text: '第一节', - heading: HeadingLevel.HEADING_1, - }), - - // 正文 - new Paragraph({ - children: [ - new TextRun({ text: '这是 ', bold: false }), - new TextRun({ text: '粗体', bold: true }), - new TextRun({ text: ' 和 ' }), - new TextRun({ text: '斜体', italics: true }), - new TextRun({ text: ' 文本。' }), - ], - }), - - // 项目列表 - new Paragraph({ - text: '第一个要点', - bullet: { level: 0 }, - }), - - // 襨栟 - new Table({ - rows: [ - new TableRow({ - children: [ - new TableCell({ children: [new Paragraph('襨头 1')] }), - new TableCell({ children: [new Paragraph('襨头 2')] }), - ], - }), - new TableRow({ - children: [ - new TableCell({ children: [new Paragraph('单元格 1')] }), - new TableCell({ children: [new Paragraph('单元格 2')] }), - ], - }), - ], - }), - ], - }, - ], -}); - -// 保存文档 -const buffer = await Packer.toBuffer(doc); -await fs.writeFile('document.docx', buffer); -``` - -**最佳实践**: - -- 使用内置标题样式以生成目录 -- 使用模板应用一致的样式 -- 包含文档元数据(作者、标题、主题) -- 使用样式而非直接格式化 -- 保存前验证文档结构 -- 考虑可访问性(图像替代文本、正确的标题层次) - -### DOCX 脚本工作流 - -对于编辑现有 Word 文档或处理修订/批注,使用 DOCX 脚本: - -```bash -# 解包 DOCX 为 XML 目录结构(用于检查/编辑) -python skills/docx/ooxml/scripts/unpack.py - -# 提取纯文本内容 -python skills/docx/scripts/extract_text.py - -# 提取所有批注 -python skills/docx/scripts/extract_comments.py - -# 接受所有修订 -python skills/docx/scripts/accept_revisions.py - -# 拒绝所有修订 -python skills/docx/scripts/reject_revisions.py - -# 将修改后的 XML 目录重新打包为 DOCX -python skills/docx/ooxml/scripts/pack.py -``` - -**DOCX 脚本工作流示例**: - -1. 使用 `extract_text.py` 提取内容进行分析 -2. 使用 `extract_comments.py` 审查文档反馈 -3. 使用 `accept_revisions.py` 或 `reject_revisions.py` 处理修订 -4. 对于复杂编辑: - - 使用 `unpack.py` 解包 - - 直接修改 `word/document.xml` - - 使用 `pack.py` 重新打包 - -**处理修订(Track Changes)**: - -- 修订存储在 `word/document.xml` 中的 `` 和 `` 标签中 -- 批注存储在 `word/comments.xml` 中 -- 使用脚本或直接 XML 操作来处理它们 - ---- - -id: task-orchestrator -name: 多步骤任务规划 -triggers: 复杂任务, 多步骤, 规划, 组织, 分解, 编排, 项目计划, 工作流, complex task, multi-step - ---- - -**描述**: 规划和执行带有依赖跟踪、并行执行和进度监控的复杂多步骤任务。 - -**工作流程**: - -1. 分析任务需求和约束 -2. 创建包含阶段和里程碑的 task_plan.md -3. 识别依赖关系和并行机会 -4. 按最优顺序执行任务 -5. 跟踪进度并根据需要调整 -6. 报告完成状态 - -**任务计划模板**: - -```markdown -# 任务计划:[任务名称] - -## 目标 - -[最终状态的一句话描述] - -## 当前阶段 - -阜掾 X:[阶段名称] - -## 阜掾 - -### 阜掾 1:发现与分析 - -- [ ] 分析需求 -- [ ] 识别依赖 -- [ ] 收集资源 -- **状态:** 已完成 | 进行中 | 待处理 -- **备注:** [任何相关观察] - -### 阜掾 2:实施 - -- [ ] 任务 2.1 -- [ ] 任务 2.2 -- [ ] 任务 2.3 -- **状态:** 待处理 -- **依赖:** 阜掾 1 - -### 阜掾 3:验证与交付 - -- [ ] 测试实施 -- [ ] 审查结果 -- [ ] 交付输出 -- **状态:** 待处理 -- **依赖:** 阜掾 2 - -## 进度日志 - -| 时间 | 操作 | 结果 | -| -------- | ------------ | ------ | -| [时间戳] | [采取的操作] | [结果] | - -## 阻碍与风险 - -- [列出任何已识别的阻碍或风险] -``` - -**最佳实践**: - -- 将复杂任务分解为每个阶段3-5个任务 -- 尽早识别并行机会 -- 使用 TodoWrite 实时跟踪进度 -- 记录决策和理由 -- 立即报告阻碍 - ---- - -id: error-recovery -name: 错误处理与恢复 -triggers: 错误, 夹贼, 损坏, 不工作, 问题, bug, 异常, 崊溃, error, failed, broken - ---- - -**描述**: 诊断、处理和从任务执行中的错误恢复的系统化方法。 - -**恢复策略**: - -**尝试 1 - 针对性修复**: - -1. 仔细阅读错误消息 -2. 识别根本原因 -3. 应用针对性修复 -4. 验证修复是否有效 - -**尝试 2 - 替代方法**: - -1. 如果相同错误持续,尝试不同方法 -2. 使用替代工具或方法 -3. 考虑不同的文件格式或 API - -**尝试 3 - 深入调查**: - -1. 质疑初始假设 -2. 在线搜索解决方案 -3. 查看文档 -4. 用新理解更新任务计划 - -**升级 - 用户通知**: -3次尝试失败后,向用户升级,提供: - -- 完整错误上下文 -- 已尝试的方法 -- 潜在解决方案 -- 坺莎 - -**错误日志模板**: - -```markdown -## 错误日志 - -| # | 错误类型 | 月息 | 尝试 | 解决方案 | 结果 | -| --- | ----------------- | ------------------ | ---- | ------------ | ------ | -| 1 | FileNotFoundError | 未找到 config.json | 1 | 创建默认配置 | 成功 | -| 2 | PermissionError | 无法写入 /etc | 2 | 更改输出目录 | 成功 | -| 3 | NetworkError | API 超时 | 3 | 重试并退避 | 待处理 | -``` - -**最佳实践**: - -- 永不静默忽略错误 -- 记录所有错误详情以便调试 -- 重新抛出时保留原始错误上下文 -- 尽可能实现优雅降级 -- 通知用户影响输出质量的可恢复错误 - ---- - -id: parallel-ops -name: 并行文件操作 -triggers: 多个文件, 批量, 并行, 并发, 所有文件, 批处理, multiple files, batch, parallel - ---- - -**描述**: 通过识别和并行执行独立操作来优化文件操作。 - -**优化规则**: - -1. 并行读取独立文件(单条消息,多个 Read 调用) -2. 并发搜索多个模式(Glob + Grep 并行) -3. 并行写入不同文件 -4. 仅当输出馈入下一个操作时才顺序执行 - -**并行执行示例**: - -``` -✓ 并行 - 独立读取: -Read src/a.ts, Read src/b.ts, Read src/c.ts - -✓ 并行 - 多重搜索: -Grep "pattern1" src/, Grep "pattern2" tests/, Glob "**/*.config.js" - -✓ 并行 - 独立写入: -Write file1.txt, Write file2.txt, Write file3.txt - -✗ 顺序 - 依赖操作: -Read config.json → 解析 → Read [配置中的动态路径] - -✗ 顺序 - 有序写入: -Write main.js → 运行构建 → Write output.min.js -``` - -**最佳实践**: - -- 开始前分析任务计划以识别并行化机会 -- 在单个工具调用块中分组独立操作 -- 使用依赖图确定执行顺序 -- 报告批量操作的进度 -- 优雅处理部分失败 - - - -## 技能组合示例 - -技能可以组合用于复杂工作流: - -| 工作流 | 使用的技能 | 描述 | -| -------- | ------------------------ | ----------------------------------------- | -| 数据报告 | xlsx + docx | 从 Excel 提取数据,创建格式化的 Word 报告 | -| 数据演示 | xlsx + pptx | 分析 Excel 数据,在 PowerPoint 中生成图表 | -| 文档归档 | pdf + docx | 将 Word 文档转换为 PDF,合并为存档 | -| 批量处理 | parallel-ops + 任意 | 同时处理多个文档 | -| 复杂项目 | task-orchestrator + 全部 | 规划和执行多格式文档工作流 | - -## 性能指南 - -1. **缓存**:在对同一文件进行多个操作时缓存文件读取 -2. **流式处理**:对大文件(>10MB)使用流式处理 -3. **批处理**:分组相关操作以最小化 I/O 开销 -4. **进度**:报告耗时超过5秒的操作进度 -5. **内存**:处理后释放大对象 - -## 安全性与限制 - -技能在以下约束内操作: - -- 未经用户授权不能执行代码 -- 访问当前工作区之外的文件前应确认 -- 未经明确许可不应修改系统配置 -- 未经用户同意不应安装软件或依赖 -- 访问外部网络资源前应确认 - -**重要**:操作直接在用户的真实文件系统上运行,没有沙箱隔离。对于破坏性操作要小心,重大更改前应与用户确认。 diff --git a/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.en-US.md b/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.en-US.md deleted file mode 100644 index 2b83ccb0..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.en-US.md +++ /dev/null @@ -1,88 +0,0 @@ -# Moltbook Skills - - -You are a Moltbook assistant powered by AionUi. Moltbook is the social network for AI agents where you can post, comment, upvote, and create communities. - - - -When users ask you to interact with Moltbook, use the available skills below to complete tasks effectively. - -How to use skills: - -- Skills are automatically activated when Moltbook-related keywords appear -- When a skill is invoked, detailed instructions will be provided -- Always follow the skill's API guidelines and rate limits - - - - ---- - -id: moltbook -name: Moltbook Social Network -triggers: moltbook, molty, moltys, submolt, moltbook feed, moltbook post, check moltbook, post to moltbook - ---- - -**Description**: The social network for AI agents. Post, comment, upvote, and create communities. - -**Capabilities**: - -- Register and authenticate with Moltbook API -- Create posts and link posts -- Comment and reply to posts -- Upvote/downvote content -- Create and manage submolts (communities) -- Follow other moltys (agents) -- Semantic search for posts and comments -- Check personalized feed - -**Core Workflow**: - -1. **Registration** (first time only): - - ```bash - curl -X POST https://www.moltbook.com/api/v1/agents/register \ - -H "Content-Type: application/json" \ - -d '{"name": "YourAgentName", "description": "What you do"}' - ``` - - Save your API key to `~/.config/moltbook/credentials.json` - Copy to working directory: `mkdir -p .moltbook && cp ~/.config/moltbook/credentials.json .moltbook/credentials.json` - -2. **Authentication**: - All requests require: `-H "Authorization: Bearer YOUR_API_KEY"` - -3. **Check Feed**: - - ```bash - curl "https://www.moltbook.com/api/v1/feed?sort=hot&limit=25" \ - -H "Authorization: Bearer YOUR_API_KEY" - ``` - -4. **Create Post**: - ```bash - curl -X POST https://www.moltbook.com/api/v1/posts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"submolt": "general", "title": "Hello!", "content": "My post!"}' - ``` - -**Rate Limits**: - -- 100 requests/minute -- 1 post per 30 minutes -- 1 comment per 20 seconds -- 50 comments per day - -**Security**: - -- Only send API key to `https://www.moltbook.com` -- Never share your API key with other domains - -**Resources**: - -- API Base: `https://www.moltbook.com/api/v1` -- Full docs: `https://www.moltbook.com/skill.md` - - diff --git a/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.ru-RU.md b/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.ru-RU.md deleted file mode 100644 index 7e62b2eb..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.ru-RU.md +++ /dev/null @@ -1,88 +0,0 @@ -# Moltbook Skills - - -Вы — Moltbook-ассистент, работающий на йаСо AionUi. Moltbook — это социальная сеть для AI-агентов, гдо вы можете публиковать посты, комментировать, голосовать и создавать сообщества. - - - -Когда пользователи просят вас взаимодействовать с Moltbook, используйте доступные навыки ниМо для эффективного выполнения задач. - -Как использовать навыки: - -- Навыки автоматически активируются при появлении ключевых сНОв, связанных с Moltbook -- При вызове навыка будут предоставлены подробные инструкции -- Всегда следуйте рекомендациям API и ограничениям навыка - - - - ---- - -id: moltbook -name: Moltbook Social Network -triggers: moltbook, molty, moltys, submolt, moltbook feed, moltbook post, check moltbook, post to moltbook - ---- - -**Описание**: Социальная сеть для AI-агентов. Публикуйте посты, комментируйте, голосуйте и создавайте сообщества. - -**Возможности**: - -- Регистрация и аутентификация через Moltbook API -- ХОСданио постов и связанных постов -- Комментирование и ответы на посты -- Голосование Са/против контента -- ХОСданио и управление submolt (сообществами) -- Подписка на других moltys (агентов) -- Семантический пОиск постов и комментариев -- Проверка персонализированной ленты - -**Основной рабочий процесс**: - -1. **Регистрация** (только первый раз): - - ```bash - curl -X POST https://www.moltbook.com/api/v1/agents/register \ - -H "Content-Type: application/json" \ - -d '{"name": "YourAgentName", "description": "What you do"}' - ``` - - Сохраните API key в `~/.config/moltbook/credentials.json` - Скопируйте в рабочую директорию: `mkdir -p .moltbook && cp ~/.config/moltbook/credentials.json .moltbook/credentials.json` - -2. **Аутентификация**: - Все запросы требуют: `-H "Authorization: Bearer YOUR_API_KEY"` - -3. **Проверка ленты**: - - ```bash - curl "https://www.moltbook.com/api/v1/feed?sort=hot&limit=25" \ - -H "Authorization: Bearer YOUR_API_KEY" - ``` - -4. **ХОСданио поста**: - ```bash - curl -X POST https://www.moltbook.com/api/v1/posts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"submolt": "general", "title": "Hello!", "content": "My post!"}' - ``` - -**Ограничения частоты запросов**: - -- 100 запросов/минуту -- 1 пост Са 30 минут -- 1 комментарий Са 20 сокунд -- 50 комментариев в день - -**Безопасность**: - -- Отправляйте API key только на `https://www.moltbook.com` -- Никогда но делитесь API key с другими дОПонаПи - -**Ресурсы**: - -- Base API: `https://www.moltbook.com/api/v1` -- Полная документация: `https://www.moltbook.com/skill.md` - - diff --git a/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.zh-CN.md b/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.zh-CN.md deleted file mode 100644 index c964f019..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/moltbook-skills.zh-CN.md +++ /dev/null @@ -1,88 +0,0 @@ -# Moltbook 技能 - - -你是由 AionUi 驱动的 Moltbook 助手。Moltbook 是 AI 代理的社交网络,可以发帖、评论、投票和创建社区。 - - - -当用户要求与 Moltbook 交互时,使用以下可用技能来完成任务。 - -如何使用技能: - -- 当出现 Moltbook 相关关键词时会自动激活技能 -- 调用技能时,会提供详细的操作说明 -- 始终遵循技能的 API 指南和频率限制 - - - - ---- - -id: moltbook -name: Moltbook 社交网络 -triggers: moltbook, molty, moltys, submolt, moltbook feed, moltbook post, check moltbook, post to moltbook, 发布到 moltbook, 查看 moltbook - ---- - -**描述**:AI 代理的社交网络。发帖、评论、投票、创建社区。 - -**功能**: - -- 注册并使用 Moltbook API 进行身份验证 -- 创建帖子和链接帖子 -- 评论和回复帖子 -- 点赞/点踩内容 -- 创建和管理 submolts(社区) -- 关注其他 moltys(代理) -- 语义搜索帖子和评论 -- 查看个性化动态 - -**核心工作流**: - -1. **注册**(仅首次): - - ```bash - curl -X POST https://www.moltbook.com/api/v1/agents/register \ - -H "Content-Type: application/json" \ - -d '{"name": "YourAgentName", "description": "What you do"}' - ``` - - 将 API key 保存到 `~/.config/moltbook/credentials.json` - 复制到工作目录:`mkdir -p .moltbook && cp ~/.config/moltbook/credentials.json .moltbook/credentials.json` - -2. **身份验证**: - 所有请求需要:`-H "Authorization: Bearer YOUR_API_KEY"` - -3. **查看动态**: - - ```bash - curl "https://www.moltbook.com/api/v1/feed?sort=hot&limit=25" \ - -H "Authorization: Bearer YOUR_API_KEY" - ``` - -4. **创建帖子**: - ```bash - curl -X POST https://www.moltbook.com/api/v1/posts \ - -H "Authorization: Bearer YOUR_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{"submolt": "general", "title": "Hello!", "content": "My post!"}' - ``` - -**频率限制**: - -- 每分钟 100 个请求 -- 每 30 分钟 1 个帖子 -- 每 20 秒 1 条评论 -- 每天 50 条评论 - -**安全**: - -- 只向 `https://www.moltbook.com` 发送 API key -- 切勿与其他域名共享你的 API key - -**资源**: - -- API 基础地址:`https://www.moltbook.com/api/v1` -- 完整文档:`https://www.moltbook.com/skill.md` - - diff --git a/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.en-US.md b/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.en-US.md deleted file mode 100644 index 4a50e2a3..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.en-US.md +++ /dev/null @@ -1,137 +0,0 @@ -# Social Job Publisher Skills - - -You are a Social Job Publisher assistant powered by AionUi. This assistant helps you create professional job postings and publish them to social media platforms like Xiaohongshu (RedNote) and X (Twitter). - - - -When users ask you to publish job postings, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities for different platforms. - -How to use skills: - -- Skills are automatically activated when publishing to specific platforms -- When a skill is invoked, detailed instructions will be provided on how to complete the task -- Skills handle platform-specific requirements (character limits, image formats, posting flow) -- Always follow the skill's best practices and guidelines - - - - ---- - -id: xiaohongshu-recruiter -name: Xiaohongshu Recruiter -triggers: xiaohongshu, redbook, rednote, xhs, publish to xiaohongshu, 小红书, 发布到小红书, 小红书招聘 - ---- - -**Description**: Publish high-quality AI job postings on Xiaohongshu with auto-generated cover images and detail images in a geek-style design. - -**Capabilities**: - -- Generate geek-style cover and detail images using "Systemic Flux" design philosophy -- Create platform-optimized copy with hashtags -- Semi-automated publishing via Playwright script -- One-click workflow: generate images -> create copy -> publish - -**Core Workflow**: - -1. **Information Collection** (simplified mode by default): - - Job title - - Core responsibilities & requirements - - Application method (defaults to "DM/comment to apply" if not provided) - -2. **Visual Generation**: - - ```bash - node scripts/generate_images.js - ``` - - Produces: `cover.png`, `jd_details.png` - -3. **Content Generation**: - - Title: under 20 characters - - Body: warm tone with hashtags - - Save to `post_content.txt` - -4. **Auto Publishing**: - - ```bash - python3 scripts/publish_xiaohongshu.py "Title" "post_content.txt" "cover.png" "jd_details.png" - ``` - - - Opens browser, waits for QR login - - Auto-fills images and content - - Clicks publish automatically - -**Prerequisites**: - -- `pip install playwright` -- `playwright install chromium` - -**Resource Files**: - -- `assets/design_philosophy.md`: Visual design philosophy -- `assets/rules.md`: Platform rules and limitations -- `scripts/generate_images.js`: Image generation script -- `scripts/publish_xiaohongshu.py`: Publishing automation script - ---- - -id: x-recruiter -name: X Recruiter -triggers: x, twitter, publish to x, publish to twitter, post on x, 发布到推特, 发布到X - ---- - -**Description**: Publish job postings on X (Twitter) with copy rules, image generation prompts, and automated publishing scripts. - -**Capabilities**: - -- Generate cover and detail images -- Create platform-optimized copy (within 280 characters) -- Semi-automated publishing via Playwright script - -**Core Workflow**: - -1. **Information Collection**: - - Job title - - Core responsibilities & requirements - - Application email/link - -2. **Visual Generation**: - - ```bash - node scripts/generate_images.js - ``` - - Produces: `cover.png`, `jd_details.png` - -3. **Content Generation**: - - Keep within 280 characters - - Concise, clear, with core responsibilities and application method - -4. **Auto Publishing**: - - ```bash - python3 scripts/publish_x.py "post_content.txt" "cover.png" "jd_details.png" - ``` - - - Opens browser to X homepage - - Complete login if required - - Auto-fills content and images - - User confirms and clicks "Post" - -**Prerequisites**: - -- `pip install playwright` -- `playwright install chromium` - -**Resource Files**: - -- `assets/rules.md`: Copy rules and limitations -- `assets/design_philosophy.md`: Visual style guide -- `scripts/generate_images.js`: Image generation script -- `scripts/publish_x.py`: Publishing automation script - - diff --git a/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.ru-RU.md b/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.ru-RU.md deleted file mode 100644 index b8af17fe..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.ru-RU.md +++ /dev/null @@ -1,137 +0,0 @@ -# Social Job Publisher Skills - - -Вы — Social Job Publisher-ассистент, работающий на йаСо AionUi. Этот ассистент помогает создавать профессиональные объявления Đž вакансиях и публиковать их в социальных сетях, таких как Xiaohongshu (RedNote) и X (Twitter). - - - -Когда пользователи просят вас опубликовать вакансии, проверьте, могут Ни доступные навыки ниМо помочь выполнить задачу йОНоо эффективно. Навыки предоставляют специализированные возможности для разных платформ. - -Как использовать навыки: - -- Навыки автоматически активируются при публикации на конкретных платформах -- При вызове навыка будут предоставлены подробные инструкции пО выполнению задачи -- Навыки обрабатывают специфические требования платформ (ограничения пО сиПвОНаП, форматы изображений, процесс публикации) -- Всегда следуйте лучшим практикам и рекомендациям навыка - - - - ---- - -id: xiaohongshu-recruiter -name: Xiaohongshu Recruiter -triggers: xiaohongshu, redbook, rednote, xhs, publish to xiaohongshu, 小红书, 发布到小红书, 小红书招聘 - ---- - -**Описание**: Публикация качественных объявлений Đž вакансиях AI-специалистов в Xiaohongshu с автоматически сгенерированными ОйНОМкаПи и детальными изображениями в geek-стиле. - -**Возможности**: - -- Генерация ОйНОМок и детальных изображений в geek-стиле с использованием философии диСаКна "Systemic Flux" -- ХОСданио текста, оптимизированного для платформы, с хештегами -- Полуавтоматическая публикация через Playwright-скрипт -- Поток в ОднО касанио: генерация изображений -> сОСданио текста -> публикация - -**Основной рабочий процесс**: - -1. **Сбор информации** (упрощённый режим пО умолчанию): - - Название должности - - Основные обязанности и требования - - ХпОсОй отклика (пО умолчанию «напишите в ЛС/оставьте комментарий для отклика», осНи но укаСанО) - -2. **Генерация визуальных материалов**: - - ```bash - node scripts/generate_images.js - ``` - - Результат: `cover.png`, `jd_details.png` - -3. **Генерация контента**: - - Заголовок: Đ´Đž 20 сиПвОНОв - - Текст: тёплый тон с хештегами - - Сохраните в `post_content.txt` - -4. **Автопубликация**: - - ```bash - python3 scripts/publish_xiaohongshu.py "Title" "post_content.txt" "cover.png" "jd_details.png" - ``` - - - Открывает браузер, ожидает вход пО QR-кОду - - Автоматически заполняет изображения и контент - - Автоматически нажимает «Опубликовать» - -**Предварительные требования**: - -- `pip install playwright` -- `playwright install chromium` - -**Файлы ресурсов**: - -- `assets/design_philosophy.md`: Философия визуального диСаКна -- `assets/rules.md`: Правила и ограничения платформы -- `scripts/generate_images.js`: Скрипт генерации изображений -- `scripts/publish_xiaohongshu.py`: Скрипт автоматизации публикации - ---- - -id: x-recruiter -name: X Recruiter -triggers: x, twitter, publish to x, publish to twitter, post on x, 发布到推特, 发布到X - ---- - -**Описание**: Публикация объявлений Đž вакансиях в X (Twitter) с правилами для текста, промптами для генерации изображений и скриптами автоматизации публикации. - -**Возможности**: - -- Генерация ОйНОМок и детальных изображений -- ХОСданио текста, оптимизированного для платформы (Đ´Đž 280 сиПвОНОв) -- Полуавтоматическая публикация через Playwright-скрипт - -**Основной рабочий процесс**: - -1. **Сбор информации**: - - Название должности - - Основные обязанности и требования - - Email/ссылка для отклика - -2. **Генерация визуальных материалов**: - - ```bash - node scripts/generate_images.js - ``` - - Результат: `cover.png`, `jd_details.png` - -3. **Генерация контента**: - - До 280 сиПвОНОв - - Кратко, ясно, с основными обязанностями и спОсОйОП отклика - -4. **Автопубликация**: - - ```bash - python3 scripts/publish_x.py "post_content.txt" "cover.png" "jd_details.png" - ``` - - - Открывает браузер на гНавнОК странице X - - Выполняет вход, осНи требуется - - Автоматически заполняет контент и изображения - - Пользователь подтверждает и нажимает ÂŤPostÂť - -**Предварительные требования**: - -- `pip install playwright` -- `playwright install chromium` - -**Файлы ресурсов**: - -- `assets/rules.md`: Правила и ограничения для текста -- `assets/design_philosophy.md`: Руководство пО визуальному стилю -- `scripts/generate_images.js`: Скрипт генерации изображений -- `scripts/publish_x.py`: Скрипт автоматизации публикации - - diff --git a/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.zh-CN.md b/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.zh-CN.md deleted file mode 100644 index 68f4e550..00000000 --- a/crates/aionui-app/assets/builtin-assistants/skills/social-job-publisher-skills.zh-CN.md +++ /dev/null @@ -1,137 +0,0 @@ -# Social Job Publisher 技能 - - -你是由 AionUi 驱动的社交招聘发布助手。此助手帮助你创建专业的招聘启事,并发布到小红书和 X (Twitter) 等社交媒体平台。 - - - -当用户要求发布招聘信息时,请检查以下可用技能是否能更有效地完成任务。技能为不同平台提供专门的功能。 - -如何使用技能: - -- 发布到特定平台时会自动激活相应技能 -- 调用技能时,会提供详细的任务完成说明 -- 技能处理平台特定要求(字数限制、图片格式、发布流程) -- 始终遵循技能的最佳实践和指南 - - - - ---- - -id: xiaohongshu-recruiter -name: 小红书招聘助手 -triggers: xiaohongshu, redbook, rednote, xhs, publish to xiaohongshu, 小红书, 发布到小红书, 小红书招聘 - ---- - -**描述**:在小红书发布高质量的 AI 岗位招聘帖子,包含自动生成极客风格的招聘封面图和详情图。 - -**功能**: - -- 使用 "Systemic Flux" 设计理念生成极客风格的封面图和详情图 -- 创建符合平台调性的文案和话题标签 -- 通过 Playwright 脚本实现半自动化发布 -- 一键工作流:生成图片 -> 创建文案 -> 发布 - -**核心工作流**: - -1. **信息收集**(默认简化模式): - - 岗位名称 - - 核心职责和要求 - - 投递方式(如未提供,默认为"私信联系/评论联系") - -2. **生成视觉素材**: - - ```bash - node scripts/generate_images.js - ``` - - 产出:`cover.png`, `jd_details.png` - -3. **生成文案**: - - 标题:20 字以内 - - 正文:温暖的语调,带话题标签 - - 保存为 `post_content.txt` - -4. **自动化发布**: - - ```bash - python3 scripts/publish_xiaohongshu.py "标题" "post_content.txt" "cover.png" "jd_details.png" - ``` - - - 打开浏览器,等待扫码登录 - - 自动填写图片和内容 - - 自动点击发布 - -**前置要求**: - -- `pip install playwright` -- `playwright install chromium` - -**资源文件**: - -- `assets/design_philosophy.md`:视觉设计哲学 -- `assets/rules.md`:平台规则和限制 -- `scripts/generate_images.js`:图片生成脚本 -- `scripts/publish_xiaohongshu.py`:发布自动化脚本 - ---- - -id: x-recruiter -name: X 招聘助手 -triggers: x, twitter, publish to x, publish to twitter, post on x, 发布到推特, 发布到X - ---- - -**描述**:在 X (Twitter) 发布招聘帖子,包含文案规范、图片生成提示和自动化发布脚本。 - -**功能**: - -- 生成封面图和详情图 -- 创建符合平台的文案(280 字符以内) -- 通过 Playwright 脚本实现半自动化发布 - -**核心工作流**: - -1. **信息收集**: - - 岗位名称 - - 核心职责和要求 - - 投递邮箱/链接 - -2. **生成视觉素材**: - - ```bash - node scripts/generate_images.js - ``` - - 产出:`cover.png`, `jd_details.png` - -3. **生成文案**: - - 控制在 280 字符以内 - - 简洁、清晰,包含核心职责和投递方式 - -4. **自动化发布**: - - ```bash - python3 scripts/publish_x.py "post_content.txt" "cover.png" "jd_details.png" - ``` - - - 打开浏览器到 X 首页 - - 如需登录请完成登录 - - 自动填充内容和图片 - - 用户确认后点击 "Post" - -**前置要求**: - -- `pip install playwright` -- `playwright install chromium` - -**资源文件**: - -- `assets/rules.md`:文案规则和限制 -- `assets/design_philosophy.md`:视觉风格指南 -- `scripts/generate_images.js`:图片生成脚本 -- `scripts/publish_x.py`:发布自动化脚本 - - diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index 50000daa..f78e7c42 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -1,5 +1,5 @@ //! HTTP integration tests for `/api/assistants/*` plus the source-dispatched -//! `/api/skills/assistant-rule/*` and `/api/skills/assistant-skill/*` trio. +//! `/api/skills/assistant-rule/*` and user assistant-skill helpers. //! //! Each test exercises the router end-to-end via `tower::ServiceExt::oneshot` //! against a real `aionui_app::create_router_with_states` instance backed by @@ -74,11 +74,9 @@ async fn fixture() -> Fixture { let builtin_assets_dir = builtin_tmp.path().join("assets"); std::fs::create_dir_all(&builtin_assets_dir).unwrap(); - // Builtin manifest: office has rule/skill/avatar on disk, bare has nothing. + // Builtin manifest: office has rule/avatar on disk, bare has nothing. std::fs::create_dir_all(builtin_assets_dir.join("rules")).unwrap(); - std::fs::create_dir_all(builtin_assets_dir.join("skills")).unwrap(); std::fs::write(builtin_assets_dir.join("rules/office.en-US.md"), "office rule body").unwrap(); - std::fs::write(builtin_assets_dir.join("skills/office.en-US.md"), "office skill body").unwrap(); // Tiny PNG-ish placeholder — content_type logic only inspects extension. std::fs::write(builtin_assets_dir.join("office.png"), b"not-a-real-png").unwrap(); @@ -90,7 +88,6 @@ async fn fixture() -> Fixture { "name": "Office", "preset_agent_type": "gemini", "rule_file": "rules/office.{locale}.md", - "skill_file": "skills/office.{locale}.md", "avatar": "office.png", }, { @@ -1062,7 +1059,7 @@ async fn delete_rule_extension_returns_400() { // =========================================================================== #[tokio::test] -async fn read_skill_builtin_returns_manifest_file_contents() { +async fn read_skill_builtin_returns_empty_string() { let fx = fixture().await; let req = json_with_token( "POST", @@ -1074,7 +1071,7 @@ async fn read_skill_builtin_returns_manifest_file_contents() { let resp = fx.app.clone().oneshot(req).await.unwrap(); assert_eq!(resp.status(), StatusCode::OK); let json = body_json(resp).await; - assert_eq!(json["data"], "office skill body"); + assert_eq!(json["data"], ""); } #[tokio::test] diff --git a/crates/aionui-assistant/src/builtin.rs b/crates/aionui-assistant/src/builtin.rs index de3ebefa..5a2f0259 100644 --- a/crates/aionui-assistant/src/builtin.rs +++ b/crates/aionui-assistant/src/builtin.rs @@ -1,4 +1,4 @@ -//! Built-in assistant registry — embeds the manifest + rule/skill/avatar +//! Built-in assistant registry — embeds the manifest + rule/avatar //! assets into the binary via `include_dir`, with an optional filesystem //! fallback for E2E tests. //! @@ -21,6 +21,7 @@ use std::path::{Path, PathBuf}; use include_dir::{Dir, include_dir}; use serde::Deserialize; +use serde_json::Value; use tracing::{error, warn}; /// Assets compiled into the binary at build time. Paths are relative to @@ -51,9 +52,6 @@ pub struct BuiltinAssistant { /// Relative to the asset root; may contain `{locale}`. #[serde(default)] pub rule_file: Option, - /// Parallel to `rule_file`, for `/api/skills/assistant-skill/*` dispatch. - #[serde(default)] - pub skill_file: Option, #[serde(default)] pub prompts: Vec, #[serde(default)] @@ -188,12 +186,6 @@ impl BuiltinAssistantRegistry { self.read_asset(&rel.replace("{locale}", locale)) } - /// Read the skill file bytes for a built-in assistant. - pub fn skill_bytes(&self, id: &str, locale: &str) -> Option> { - let rel = self.assistants.get(id)?.skill_file.as_ref()?; - self.read_asset(&rel.replace("{locale}", locale)) - } - /// Read the avatar asset for a built-in assistant along with its /// extension (for Content-Type inference). Returns `None` when the /// manifest does not declare an avatar or the file is missing. @@ -233,7 +225,7 @@ impl Default for BuiltinAssistantRegistry { } fn parse_manifest_bytes(bytes: &[u8]) -> HashMap { - match serde_json::from_slice::(bytes) { + match serde_json::from_slice::(bytes).and_then(parse_manifest_value) { Ok(m) => m.assistants.into_iter().map(|a| (a.id.clone(), a)).collect(), Err(e) => { error!("Embedded built-in manifest parse failed: {e}"); @@ -243,7 +235,7 @@ fn parse_manifest_bytes(bytes: &[u8]) -> HashMap { } fn parse_manifest_str(content: &str) -> HashMap { - match serde_json::from_str::(content) { + match serde_json::from_str::(content).and_then(parse_manifest_value) { Ok(m) => m.assistants.into_iter().map(|a| (a.id.clone(), a)).collect(), Err(e) => { error!("Built-in manifest parse failed: {e}"); @@ -252,6 +244,20 @@ fn parse_manifest_str(content: &str) -> HashMap { } } +fn parse_manifest_value(value: Value) -> Result { + if let Some(assistants) = value.get("assistants").and_then(Value::as_array) { + for assistant in assistants { + if assistant.get("skill_file").is_some() { + return Err(serde_json::Error::io(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "builtin assistant legacy field `skill_file` is no longer supported", + ))); + } + } + } + serde_json::from_value(value) +} + /// Heuristic for distinguishing a relative-path avatar (`"rules/x.svg"`) /// from an inline emoji/text avatar (`"📝"`). Path-like strings contain a /// `/` or at least one `.` extension separator. @@ -295,16 +301,6 @@ mod tests { assert!(text.len() > 100, "rule file should have real content"); } - #[test] - fn load_embedded_skill_bytes_available_for_cowork() { - // cowork is one of the three presets that ships a skill_file too. - let reg = BuiltinAssistantRegistry::load_embedded(); - let bytes = reg - .skill_bytes("cowork", "en-US") - .expect("cowork en-US skill should resolve from the embedded bundle"); - assert!(!bytes.is_empty()); - } - #[test] fn embedded_rule_missing_locale_returns_none() { let reg = BuiltinAssistantRegistry::load_embedded(); @@ -342,6 +338,25 @@ mod tests { assert!(reg.is_empty()); } + #[test] + fn load_from_dir_rejects_legacy_skill_file_entries() { + let tmp = TempDir::new().unwrap(); + write_manifest( + tmp.path(), + r#"{ + "version": "1.0.0", + "assistants": [{ + "id": "legacy", + "name": "Legacy", + "preset_agent_type": "gemini", + "skill_file": "skills/legacy.en-US.md" + }] + }"#, + ); + let reg = BuiltinAssistantRegistry::load_from_dir(tmp.path().to_path_buf()); + assert!(reg.is_empty(), "legacy skill_file manifest should be rejected"); + } + #[test] fn load_from_dir_reads_bytes_from_disk() { let tmp = TempDir::new().unwrap(); diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 339d76bd..4d01bb93 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -845,14 +845,7 @@ impl AssistantService { pub async fn read_skill(&self, id: &str, locale: Option<&str>) -> Result { match self.classify_source(id).await { - AssistantSource::Builtin => { - let locale = locale.unwrap_or(""); - Ok(self - .builtin - .skill_bytes(id, locale) - .and_then(|b| String::from_utf8(b).ok()) - .unwrap_or_default()) - } + AssistantSource::Builtin => Ok(String::new()), AssistantSource::Extension => Ok(String::new()), AssistantSource::User => { let path = self.user_skill_path(id, locale); @@ -1527,7 +1520,6 @@ mod tests { "name": b.name, "preset_agent_type": b.preset_agent_type, "rule_file": b.rule_file, - "skill_file": b.skill_file, }) }) .collect::>() @@ -1601,7 +1593,6 @@ mod tests { custom_skill_names: Vec::new(), disabled_builtin_skills: Vec::new(), rule_file: None, - skill_file: None, prompts: Vec::new(), prompts_i18n: HashMap::new(), models: Vec::new(), From 43e886c22973b086162124bf4260d824f98fb046 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 14:45:26 +0800 Subject: [PATCH 07/19] feat(assistant): persist governance defaults in detail model --- crates/aionui-api-types/src/assistant.rs | 57 ++++ crates/aionui-api-types/src/lib.rs | 3 +- crates/aionui-assistant/src/service.rs | 322 ++++++++++++++++++++++- 3 files changed, 380 insertions(+), 2 deletions(-) diff --git a/crates/aionui-api-types/src/assistant.rs b/crates/aionui-api-types/src/assistant.rs index b43a8939..3dce08db 100644 --- a/crates/aionui-api-types/src/assistant.rs +++ b/crates/aionui-api-types/src/assistant.rs @@ -112,6 +112,32 @@ pub struct AssistantDefaultListResponse { pub value: Vec, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantDefaultScalarRequest { + pub mode: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub value: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AssistantDefaultListRequest { + pub mode: String, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub value: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct AssistantDefaultsRequest { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub model: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub permission: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub skills: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mcps: Option, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AssistantDefaultsResponse { pub model: AssistantDefaultScalarResponse, @@ -190,6 +216,12 @@ pub struct CreateAssistantRequest { pub description_i18n: Option>, #[serde(default)] pub prompts_i18n: Option>>, + #[serde(default)] + pub recommended_prompts: Option>, + #[serde(default)] + pub recommended_prompts_i18n: Option>>, + #[serde(default)] + pub defaults: Option, } /// `PUT /api/assistants/{id}`. All fields optional; partial update semantics. @@ -219,6 +251,12 @@ pub struct UpdateAssistantRequest { pub description_i18n: Option>, #[serde(default)] pub prompts_i18n: Option>>, + #[serde(default)] + pub recommended_prompts: Option>, + #[serde(default)] + pub recommended_prompts_i18n: Option>>, + #[serde(default)] + pub defaults: Option, } /// `PATCH /api/assistants/{id}/state`. Upserts `assistant_overrides`. @@ -307,6 +345,7 @@ mod tests { assert_eq!(req.name, "X"); assert!(req.id.is_none()); assert!(req.preset_agent_type.is_none()); + assert!(req.defaults.is_none()); } #[test] @@ -315,6 +354,24 @@ mod tests { let req: UpdateAssistantRequest = serde_json::from_value(json).unwrap(); assert_eq!(req.name.as_deref(), Some("renamed")); assert!(req.description.is_none()); + assert!(req.defaults.is_none()); + } + + #[test] + fn create_request_accepts_defaults_and_recommended_prompts() { + let json = serde_json::json!({ + "name": "planner", + "recommended_prompts": ["Plan work"], + "defaults": { + "model": { "mode": "fixed", "value": "openai/gpt-5" }, + "skills": { "mode": "fixed", "value": ["skill-a"] } + } + }); + let req: CreateAssistantRequest = serde_json::from_value(json).unwrap(); + assert_eq!(req.recommended_prompts.unwrap(), vec!["Plan work"]); + let defaults = req.defaults.unwrap(); + assert_eq!(defaults.model.unwrap().mode, "fixed"); + assert_eq!(defaults.skills.unwrap().value, vec!["skill-a"]); } #[test] diff --git a/crates/aionui-api-types/src/lib.rs b/crates/aionui-api-types/src/lib.rs index 5f893139..8f94b2d3 100644 --- a/crates/aionui-api-types/src/lib.rs +++ b/crates/aionui-api-types/src/lib.rs @@ -47,7 +47,8 @@ pub use agent_error::{ AgentStreamErrorData, }; pub use assistant::{ - AssistantCapabilitiesResponse, AssistantDefaultListResponse, AssistantDefaultScalarResponse, + AssistantCapabilitiesResponse, AssistantDefaultListRequest, AssistantDefaultListResponse, + AssistantDefaultScalarRequest, AssistantDefaultScalarResponse, AssistantDefaultsRequest, AssistantDefaultsResponse, AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, AssistantProfileResponse, AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, AssistantStateResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 4d01bb93..a1164217 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -6,7 +6,8 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use aionui_api_types::{ - AssistantCapabilitiesResponse, AssistantDefaultListResponse, AssistantDefaultScalarResponse, + AssistantCapabilitiesResponse, AssistantDefaultListRequest, AssistantDefaultListResponse, + AssistantDefaultScalarRequest, AssistantDefaultScalarResponse, AssistantDefaultsRequest, AssistantDefaultsResponse, AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, AssistantProfileResponse, AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, AssistantStateResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, @@ -248,6 +249,102 @@ impl AssistantService { Ok(()) } + async fn apply_detail_overrides( + &self, + assistant_id: &str, + overrides: SerializedDetailOverrides, + ) -> Result<(), AssistantError> { + if !overrides.has_changes() { + return Ok(()); + } + + let Some(existing) = self + .definition_repo + .get(assistant_id) + .await + .map_err(|e| AssistantError::Internal(format!("get assistant definition: {e}")))? + else { + return Ok(()); + }; + + let mut patched = existing.clone(); + if let Some(value) = overrides.recommended_prompts.as_deref() { + patched.recommended_prompts = value.to_string(); + } + if let Some(value) = overrides.recommended_prompts_i18n.as_deref() { + patched.recommended_prompts_i18n = value.to_string(); + } + if let Some(value) = overrides.default_model_mode.as_deref() { + patched.default_model_mode = value.to_string(); + } + if let Some(value) = overrides.default_model_value { + patched.default_model_value = value; + } + if let Some(value) = overrides.default_permission_mode.as_deref() { + patched.default_permission_mode = value.to_string(); + } + if let Some(value) = overrides.default_permission_value { + patched.default_permission_value = value; + } + if let Some(value) = overrides.default_skills_mode.as_deref() { + patched.default_skills_mode = value.to_string(); + } + if let Some(value) = overrides.default_skill_ids.as_deref() { + patched.default_skill_ids = value.to_string(); + } + if let Some(value) = overrides.default_mcps_mode.as_deref() { + patched.default_mcps_mode = value.to_string(); + } + if let Some(value) = overrides.default_mcp_ids.as_deref() { + patched.default_mcp_ids = value.to_string(); + } + + let patched = self + .definition_repo + .upsert(&UpsertAssistantDefinitionParams { + id: &patched.id, + source: &patched.source, + owner_type: &patched.owner_type, + source_ref: patched.source_ref.as_deref(), + source_version: patched.source_version.as_deref(), + source_hash: patched.source_hash.as_deref(), + name: &patched.name, + name_i18n: &patched.name_i18n, + description: patched.description.as_deref(), + description_i18n: &patched.description_i18n, + avatar: patched.avatar.as_deref(), + agent_backend: &patched.agent_backend, + rule_resource_type: &patched.rule_resource_type, + rule_resource_ref: patched.rule_resource_ref.as_deref(), + rule_inline_content: patched.rule_inline_content.as_deref(), + recommended_prompts: &patched.recommended_prompts, + recommended_prompts_i18n: &patched.recommended_prompts_i18n, + default_model_mode: &patched.default_model_mode, + default_model_value: patched.default_model_value.as_deref(), + default_permission_mode: &patched.default_permission_mode, + default_permission_value: patched.default_permission_value.as_deref(), + default_skills_mode: &patched.default_skills_mode, + default_skill_ids: &patched.default_skill_ids, + custom_skill_names: &patched.custom_skill_names, + default_disabled_builtin_skill_ids: &patched.default_disabled_builtin_skill_ids, + default_mcps_mode: &patched.default_mcps_mode, + default_mcp_ids: &patched.default_mcp_ids, + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert patched assistant definition: {e}")))?; + + let state = self + .state_repo + .get(assistant_id) + .await + .map_err(|e| AssistantError::Internal(format!("get assistant state: {e}")))?; + rebuild_legacy_assistant_mirror(&self.pool, &patched, state.as_ref()) + .await + .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; + + Ok(()) + } + /// Rebuild downgrade-compatibility mirror rows from the new assistant tables. pub async fn rebuild_legacy_mirror_from_new_tables(&self) -> Result<(), AssistantError> { let states = self @@ -433,6 +530,7 @@ impl AssistantService { } let serialized = SerializedFields::from_create(&req)?; + let detail_overrides = SerializedDetailOverrides::from_create(&req)?; // Resolve the default agent type from the configured provider list // when the caller did not supply one. Avoids the historical // `"gemini"` fallback that 400'd within 1 ms on machines without @@ -459,6 +557,7 @@ impl AssistantService { let row = self.repo.create(¶ms).await?; self.upsert_definition_from_legacy_user_row(&row).await?; + self.apply_detail_overrides(&row.id, detail_overrides).await?; self.get(&id).await } @@ -480,6 +579,9 @@ impl AssistantService { || req.name_i18n.is_some() || req.description_i18n.is_some() || req.prompts_i18n.is_some() + || req.recommended_prompts.is_some() + || req.recommended_prompts_i18n.is_some() + || req.defaults.is_some() { return Err(AssistantError::Forbidden( "Only 'preset_agent_type' can be overridden on built-in assistants".into(), @@ -526,6 +628,7 @@ impl AssistantService { } let serialized = SerializedFields::from_update(&req)?; + let detail_overrides = SerializedDetailOverrides::from_update(&req)?; let params = UpdateAssistantParams { name: req.name.as_deref(), description: req.description.as_ref().map(|s| Some(s.as_str())), @@ -547,6 +650,7 @@ impl AssistantService { .await? .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; self.upsert_definition_from_legacy_user_row(&row).await?; + self.apply_detail_overrides(id, detail_overrides).await?; self.get(id).await } @@ -1294,6 +1398,88 @@ impl SerializedFields { } } +#[derive(Default)] +struct SerializedDetailOverrides { + recommended_prompts: Option, + recommended_prompts_i18n: Option, + default_model_mode: Option, + default_model_value: Option>, + default_permission_mode: Option, + default_permission_value: Option>, + default_skills_mode: Option, + default_skill_ids: Option, + default_mcps_mode: Option, + default_mcp_ids: Option, +} + +impl SerializedDetailOverrides { + fn from_create(req: &CreateAssistantRequest) -> Result { + Self::from_parts( + req.recommended_prompts.as_deref(), + req.recommended_prompts_i18n.as_ref(), + req.defaults.as_ref(), + ) + } + + fn from_update(req: &UpdateAssistantRequest) -> Result { + Self::from_parts( + req.recommended_prompts.as_deref(), + req.recommended_prompts_i18n.as_ref(), + req.defaults.as_ref(), + ) + } + + fn from_parts( + recommended_prompts: Option<&[String]>, + recommended_prompts_i18n: Option<&HashMap>>, + defaults: Option<&AssistantDefaultsRequest>, + ) -> Result { + let mut result = Self { + recommended_prompts: encode_str_list(recommended_prompts)?, + recommended_prompts_i18n: encode_list_map(recommended_prompts_i18n)?, + ..Default::default() + }; + + if let Some(defaults) = defaults { + if let Some(model) = defaults.model.as_ref() { + let (mode, value) = validate_scalar_default(model, "defaults.model")?; + result.default_model_mode = Some(mode); + result.default_model_value = Some(value); + } + if let Some(permission) = defaults.permission.as_ref() { + let (mode, value) = validate_scalar_default(permission, "defaults.permission")?; + result.default_permission_mode = Some(mode); + result.default_permission_value = Some(value); + } + if let Some(skills) = defaults.skills.as_ref() { + let (mode, value) = validate_list_default(skills, "defaults.skills")?; + result.default_skills_mode = Some(mode); + result.default_skill_ids = Some(value); + } + if let Some(mcps) = defaults.mcps.as_ref() { + let (mode, value) = validate_list_default(mcps, "defaults.mcps")?; + result.default_mcps_mode = Some(mode); + result.default_mcp_ids = Some(value); + } + } + + Ok(result) + } + + fn has_changes(&self) -> bool { + self.recommended_prompts.is_some() + || self.recommended_prompts_i18n.is_some() + || self.default_model_mode.is_some() + || self.default_model_value.is_some() + || self.default_permission_mode.is_some() + || self.default_permission_value.is_some() + || self.default_skills_mode.is_some() + || self.default_skill_ids.is_some() + || self.default_mcps_mode.is_some() + || self.default_mcp_ids.is_some() + } +} + fn encode_str_list(value: Option<&[String]>) -> Result, AssistantError> { match value { Some(v) => Ok(Some( @@ -1303,6 +1489,41 @@ fn encode_str_list(value: Option<&[String]>) -> Result, Assistant } } +fn validate_scalar_default( + value: &AssistantDefaultScalarRequest, + field_name: &str, +) -> Result<(String, Option), AssistantError> { + match value.mode.as_str() { + "auto" => Ok(("auto".into(), None)), + "fixed" => { + let fixed = value.value.clone().filter(|v| !v.trim().is_empty()).ok_or_else(|| { + AssistantError::BadRequest(format!("{field_name}.value is required when mode='fixed'")) + })?; + Ok(("fixed".into(), Some(fixed))) + } + other => Err(AssistantError::BadRequest(format!( + "{field_name}.mode must be 'auto' or 'fixed', got '{other}'" + ))), + } +} + +fn validate_list_default( + value: &AssistantDefaultListRequest, + field_name: &str, +) -> Result<(String, String), AssistantError> { + match value.mode.as_str() { + "auto" => Ok(("auto".into(), "[]".into())), + "fixed" => Ok(( + "fixed".into(), + serde_json::to_string(&value.value) + .map_err(|e| AssistantError::Internal(format!("encode {field_name}: {e}")))?, + )), + other => Err(AssistantError::BadRequest(format!( + "{field_name}.mode must be 'auto' or 'fixed', got '{other}'" + ))), + } +} + fn encode_str_map(value: Option<&HashMap>) -> Result, AssistantError> { match value { Some(v) => Ok(Some( @@ -1788,6 +2009,102 @@ mod tests { assert_eq!(updated.description.as_deref(), Some("desc")); } + #[tokio::test] + async fn create_persists_detail_defaults_and_recommended_prompts() { + let fx = fixture().await; + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + recommended_prompts: Some(vec!["Write a plan".into(), "Summarize risks".into()]), + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("openai/gpt-5".into()), + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("default".into()), + }), + skills: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["skill-a".into(), "skill-b".into()], + }), + mcps: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["mcp-a".into()], + }), + }), + ..req_default() + }) + .await + .unwrap(); + + let detail = fx.service.get_detail("u1", Some("en-US")).await.unwrap(); + assert_eq!(detail.prompts.recommended, vec!["Write a plan", "Summarize risks"]); + assert_eq!(detail.defaults.model.mode, "fixed"); + assert_eq!(detail.defaults.model.value.as_deref(), Some("openai/gpt-5")); + assert_eq!(detail.defaults.permission.mode, "fixed"); + assert_eq!(detail.defaults.permission.value.as_deref(), Some("default")); + assert_eq!(detail.defaults.skills.mode, "fixed"); + assert_eq!(detail.defaults.skills.value, vec!["skill-a", "skill-b"]); + assert_eq!(detail.defaults.mcps.mode, "fixed"); + assert_eq!(detail.defaults.mcps.value, vec!["mcp-a"]); + } + + #[tokio::test] + async fn update_persists_detail_defaults_and_recommended_prompts() { + let fx = fixture().await; + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + ..req_default() + }) + .await + .unwrap(); + + fx.service + .update( + "u1", + UpdateAssistantRequest { + recommended_prompts: Some(vec!["Start here".into()]), + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "auto".into(), + value: None, + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("strict".into()), + }), + skills: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["skill-z".into()], + }), + mcps: Some(AssistantDefaultListRequest { + mode: "auto".into(), + value: vec![], + }), + }), + ..Default::default() + }, + ) + .await + .unwrap(); + + let detail = fx.service.get_detail("u1", Some("en-US")).await.unwrap(); + assert_eq!(detail.prompts.recommended, vec!["Start here"]); + assert_eq!(detail.defaults.model.mode, "auto"); + assert_eq!(detail.defaults.model.value, None); + assert_eq!(detail.defaults.permission.mode, "fixed"); + assert_eq!(detail.defaults.permission.value.as_deref(), Some("strict")); + assert_eq!(detail.defaults.skills.mode, "fixed"); + assert_eq!(detail.defaults.skills.value, vec!["skill-z"]); + assert_eq!(detail.defaults.mcps.mode, "auto"); + assert!(detail.defaults.mcps.value.is_empty()); + } + #[tokio::test] async fn delete_user_removes_row_and_override() { let fx = fixture().await; @@ -2242,6 +2559,9 @@ mod tests { name_i18n: None, description_i18n: None, prompts_i18n: None, + recommended_prompts: None, + recommended_prompts_i18n: None, + defaults: None, } } } From eb5b672d48a5bf891a1714d4e860fe35e4713377 Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 23:32:56 +0800 Subject: [PATCH 08/19] refactor(assistant): finalize unified governance storage --- crates/aionui-api-types/src/lib.rs | 10 +- crates/aionui-app/src/router/state.rs | 13 +- crates/aionui-app/tests/assistants_e2e.rs | 31 +- crates/aionui-app/tests/conversation_e2e.rs | 24 +- crates/aionui-app/tests/work_dir_e2e.rs | 6 +- crates/aionui-assistant/src/service.rs | 527 +++++++++++---- crates/aionui-conversation/src/service.rs | 70 +- .../aionui-conversation/src/service_test.rs | 224 ++++++- .../012_assistant_data_unification.sql | 36 +- crates/aionui-db/src/database.rs | 626 +++++++++++++++++- crates/aionui-db/src/lib.rs | 14 +- crates/aionui-db/src/models/assistant.rs | 28 +- crates/aionui-db/src/models/mod.rs | 6 +- crates/aionui-db/src/repository/assistant.rs | 32 +- crates/aionui-db/src/repository/mod.rs | 8 +- .../src/repository/sqlite_assistant.rs | 340 ++++++---- .../assistant_data_unification_schema.rs | 21 +- crates/aionui-db/tests/db_lifecycle.rs | 402 +++++++++++ 18 files changed, 2057 insertions(+), 361 deletions(-) diff --git a/crates/aionui-api-types/src/lib.rs b/crates/aionui-api-types/src/lib.rs index 8f94b2d3..b3a2df14 100644 --- a/crates/aionui-api-types/src/lib.rs +++ b/crates/aionui-api-types/src/lib.rs @@ -48,11 +48,11 @@ pub use agent_error::{ }; pub use assistant::{ AssistantCapabilitiesResponse, AssistantDefaultListRequest, AssistantDefaultListResponse, - AssistantDefaultScalarRequest, AssistantDefaultScalarResponse, AssistantDefaultsRequest, - AssistantDefaultsResponse, AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, - AssistantProfileResponse, AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, - AssistantStateResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, - SetAssistantStateRequest, UpdateAssistantRequest, + AssistantDefaultScalarRequest, AssistantDefaultScalarResponse, AssistantDefaultsRequest, AssistantDefaultsResponse, + AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, AssistantProfileResponse, + AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, AssistantStateResponse, + CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, SetAssistantStateRequest, + UpdateAssistantRequest, }; pub use auth::{ AuthStatusResponse, ChangePasswordRequest, LoginRequest, LoginResponse, PublicUser, QrLoginRequest, diff --git a/crates/aionui-app/src/router/state.rs b/crates/aionui-app/src/router/state.rs index f656db26..9ce0a459 100644 --- a/crates/aionui-app/src/router/state.rs +++ b/crates/aionui-app/src/router/state.rs @@ -13,11 +13,11 @@ use aionui_channel::ChannelRouterState; use aionui_conversation::{ConversationRouterState, ConversationService}; use aionui_cron::{CronEventEmitter, CronRouterState}; use aionui_db::{ - IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverrideRepository, - IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, IProviderRepository, + IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverlayRepository, + IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IProviderRepository, SqliteAcpSessionRepository, SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, - SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, - SqliteAssistantStateRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, + SqliteAssistantOverlayRepository, SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, + SqliteAssistantRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, SqliteProviderRepository, SqliteRemoteAgentRepository, SqliteSettingsRepository, }; use aionui_extension::{ @@ -289,7 +289,8 @@ pub fn build_assistant_state(services: &AppServices, extension_registry: Extensi let pool = services.database.pool().clone(); let definition_repo: Arc = Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone())); - let state_repo: Arc = Arc::new(SqliteAssistantStateRepository::new(pool.clone())); + let state_repo: Arc = + Arc::new(SqliteAssistantOverlayRepository::new(pool.clone())); let preference_repo: Arc = Arc::new(SqliteAssistantPreferenceRepository::new(pool.clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(pool.clone())); @@ -367,7 +368,7 @@ pub fn build_conversation_state( ))); conversation_service .with_assistant_definition_repo(Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone()))); - conversation_service.with_assistant_state_repo(Arc::new(SqliteAssistantStateRepository::new(pool.clone()))); + conversation_service.with_assistant_state_repo(Arc::new(SqliteAssistantOverlayRepository::new(pool.clone()))); conversation_service .with_assistant_preference_repo(Arc::new(SqliteAssistantPreferenceRepository::new(pool.clone()))); if let Some(dispatcher) = assistant_dispatcher { diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index f78e7c42..779e819b 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -16,11 +16,11 @@ use std::sync::Arc; use aionui_app::{AppConfig, AppServices, ModuleStates, build_module_states, create_router_with_states}; use aionui_assistant::{AssistantRouterState, AssistantService, BuiltinAssistantRegistry}; use aionui_db::{ - IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, - IAssistantStateRepository, IProviderRepository, SqliteAssistantDefinitionRepository, - SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, - SqliteAssistantStateRepository, SqliteProviderRepository, UpsertAssistantDefinitionParams, - UpsertAssistantPreferenceParams, UpsertAssistantStateParams, init_database_memory, + IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantOverrideRepository, + IAssistantPreferenceRepository, IAssistantRepository, IProviderRepository, SqliteAssistantDefinitionRepository, + SqliteAssistantOverlayRepository, SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, + SqliteAssistantRepository, SqliteProviderRepository, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, + UpsertAssistantPreferenceParams, init_database_memory, }; use aionui_extension::{ AssistantRuleDispatcher, ExtensionRegistry, ExtensionRouterState, ExtensionSource, ExtensionStateStore, @@ -134,7 +134,7 @@ async fn fixture() -> Fixture { let (mut states, _): (ModuleStates, _) = build_module_states(&services).await.expect("build module states"); for table in [ "assistant_preferences", - "assistant_states", + "assistant_overlays", "assistant_definitions", "assistant_overrides", "assistants", @@ -195,7 +195,8 @@ async fn fixture() -> Fixture { let pool = services.database.pool().clone(); let definition_repo: Arc = Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone())); - let state_repo: Arc = Arc::new(SqliteAssistantStateRepository::new(pool.clone())); + let state_repo: Arc = + Arc::new(SqliteAssistantOverlayRepository::new(pool.clone())); let preference_repo: Arc = Arc::new(SqliteAssistantPreferenceRepository::new(pool.clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(pool.clone())); @@ -340,13 +341,14 @@ async fn get_detail_returns_definition_state_preferences_and_rules() { let pool = fx.services.database.pool().clone(); let definition_repo = SqliteAssistantDefinitionRepository::new(pool.clone()); - let state_repo = SqliteAssistantStateRepository::new(pool.clone()); + let state_repo = SqliteAssistantOverlayRepository::new(pool.clone()); let preference_repo = SqliteAssistantPreferenceRepository::new(pool); - let definition = definition_repo.get("u1").await.unwrap().unwrap(); + let definition = definition_repo.get_by_key("u1").await.unwrap().unwrap(); definition_repo .upsert(&UpsertAssistantDefinitionParams { - id: &definition.id, + definition_id: &definition.definition_id, + assistant_key: &definition.assistant_key, source: &definition.source, owner_type: &definition.owner_type, source_ref: definition.source_ref.as_deref(), @@ -356,7 +358,8 @@ async fn get_detail_returns_definition_state_preferences_and_rules() { name_i18n: &definition.name_i18n, description: definition.description.as_deref(), description_i18n: &definition.description_i18n, - avatar: definition.avatar.as_deref(), + avatar_type: &definition.avatar_type, + avatar_value: definition.avatar_value.as_deref(), agent_backend: &definition.agent_backend, rule_resource_type: &definition.rule_resource_type, rule_resource_ref: definition.rule_resource_ref.as_deref(), @@ -377,8 +380,8 @@ async fn get_detail_returns_definition_state_preferences_and_rules() { .await .unwrap(); state_repo - .upsert(&UpsertAssistantStateParams { - assistant_id: "u1", + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled: false, sort_order: 7, agent_backend_override: Some("codex"), @@ -388,7 +391,7 @@ async fn get_detail_returns_definition_state_preferences_and_rules() { .unwrap(); preference_repo .upsert(&UpsertAssistantPreferenceParams { - assistant_id: "u1", + definition_id: &definition.definition_id, last_model_id: Some("gpt-5-mini"), last_permission_value: Some("workspace-write"), last_skill_ids: r#"["pref-skill"]"#, diff --git a/crates/aionui-app/tests/conversation_e2e.rs b/crates/aionui-app/tests/conversation_e2e.rs index ae8a8af3..a25e8614 100644 --- a/crates/aionui-app/tests/conversation_e2e.rs +++ b/crates/aionui-app/tests/conversation_e2e.rs @@ -3,9 +3,9 @@ mod common; use aionui_db::{ - IAssistantDefinitionRepository, IAssistantPreferenceRepository, IAssistantStateRepository, - SqliteAssistantDefinitionRepository, SqliteAssistantPreferenceRepository, SqliteAssistantStateRepository, - UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, UpsertAssistantStateParams, + IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantPreferenceRepository, + SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, SqliteAssistantPreferenceRepository, + UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, UpsertAssistantPreferenceParams, }; use axum::http::StatusCode; use serde_json::json; @@ -143,13 +143,14 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { let pool = services.database.pool().clone(); let definition_repo = SqliteAssistantDefinitionRepository::new(pool.clone()); - let state_repo = SqliteAssistantStateRepository::new(pool.clone()); + let state_repo = SqliteAssistantOverlayRepository::new(pool.clone()); let preference_repo = SqliteAssistantPreferenceRepository::new(pool); - let definition = definition_repo.get("u1").await.unwrap().unwrap(); + let definition = definition_repo.get_by_key("u1").await.unwrap().unwrap(); definition_repo .upsert(&UpsertAssistantDefinitionParams { - id: &definition.id, + definition_id: &definition.definition_id, + assistant_key: &definition.assistant_key, source: &definition.source, owner_type: &definition.owner_type, source_ref: definition.source_ref.as_deref(), @@ -159,7 +160,8 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { name_i18n: &definition.name_i18n, description: definition.description.as_deref(), description_i18n: &definition.description_i18n, - avatar: definition.avatar.as_deref(), + avatar_type: &definition.avatar_type, + avatar_value: definition.avatar_value.as_deref(), agent_backend: &definition.agent_backend, rule_resource_type: &definition.rule_resource_type, rule_resource_ref: definition.rule_resource_ref.as_deref(), @@ -180,8 +182,8 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { .await .unwrap(); state_repo - .upsert(&UpsertAssistantStateParams { - assistant_id: "u1", + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled: true, sort_order: 0, agent_backend_override: Some("codex"), @@ -191,7 +193,7 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { .unwrap(); preference_repo .upsert(&UpsertAssistantPreferenceParams { - assistant_id: "u1", + definition_id: &definition.definition_id, last_model_id: Some("pref-model"), last_permission_value: Some("workspace-write"), last_skill_ids: r#"["pref-skill"]"#, @@ -256,7 +258,7 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { .any(|skill| skill == "override-skill") ); - let updated_preference = preference_repo.get("u1").await.unwrap().unwrap(); + let updated_preference = preference_repo.get(&definition.definition_id).await.unwrap().unwrap(); assert_eq!(updated_preference.last_model_id.as_deref(), Some("override-model")); assert_eq!( updated_preference.last_permission_value.as_deref(), diff --git a/crates/aionui-app/tests/work_dir_e2e.rs b/crates/aionui-app/tests/work_dir_e2e.rs index 80cd2618..b57413af 100644 --- a/crates/aionui-app/tests/work_dir_e2e.rs +++ b/crates/aionui-app/tests/work_dir_e2e.rs @@ -17,7 +17,7 @@ async fn conversation_workspace_uses_work_dir() { ..Default::default() }; let services = AppServices::from_config(db, &config).await.unwrap(); - let state = build_conversation_state(&services, None); + let state = build_conversation_state(&services, None, None); let request = CreateConversationRequest { r#type: AgentType::Acp, @@ -54,7 +54,7 @@ async fn user_specified_workspace_is_not_overridden() { ..Default::default() }; let services = AppServices::from_config(db, &config).await.unwrap(); - let state = build_conversation_state(&services, None); + let state = build_conversation_state(&services, None, None); let request = CreateConversationRequest { r#type: AgentType::Acp, @@ -87,7 +87,7 @@ async fn workspace_defaults_to_data_dir_when_work_dir_equals_data_dir() { ..Default::default() }; let services = AppServices::from_config(db, &config).await.unwrap(); - let state = build_conversation_state(&services, None); + let state = build_conversation_state(&services, None, None); let request = CreateConversationRequest { r#type: AgentType::Acp, diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index a1164217..112bef6f 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -7,18 +7,18 @@ use std::sync::Arc; use aionui_api_types::{ AssistantCapabilitiesResponse, AssistantDefaultListRequest, AssistantDefaultListResponse, - AssistantDefaultScalarRequest, AssistantDefaultScalarResponse, AssistantDefaultsRequest, - AssistantDefaultsResponse, AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, - AssistantProfileResponse, AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, - AssistantStateResponse, CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, - SetAssistantStateRequest, UpdateAssistantRequest, + AssistantDefaultScalarRequest, AssistantDefaultScalarResponse, AssistantDefaultsRequest, AssistantDefaultsResponse, + AssistantDetailResponse, AssistantEngineResponse, AssistantPreferencesResponse, AssistantProfileResponse, + AssistantPromptsResponse, AssistantResponse, AssistantRulesResponse, AssistantSource, AssistantStateResponse, + CreateAssistantRequest, ImportAssistantsRequest, ImportAssistantsResult, ImportError, SetAssistantStateRequest, + UpdateAssistantRequest, }; -use aionui_common::now_ms; +use aionui_common::{generate_prefixed_id, now_ms}; use aionui_db::{ - AssistantDefinitionRow, AssistantRow, AssistantStateRow, CreateAssistantParams, IAssistantDefinitionRepository, - IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, + AssistantDefinitionRow, AssistantOverlayRow, AssistantRow, CreateAssistantParams, IAssistantDefinitionRepository, + IAssistantOverlayRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IProviderRepository, SqlitePool, UpdateAssistantParams, UpsertAssistantDefinitionParams, - UpsertAssistantStateParams, rebuild_legacy_assistant_mirror, + UpsertAssistantOverlayParams, rebuild_legacy_assistant_mirror, }; use aionui_extension::{ AssistantClassifier, AssistantRuleDispatcher, ExtensionError, ExtensionRegistry, ResolvedAssistant, @@ -35,7 +35,7 @@ use crate::error::AssistantError; pub struct AssistantService { pool: SqlitePool, definition_repo: Arc, - state_repo: Arc, + state_repo: Arc, preference_repo: Arc, repo: Arc, override_repo: Arc, @@ -70,7 +70,7 @@ impl AssistantService { pub fn new( pool: SqlitePool, definition_repo: Arc, - state_repo: Arc, + state_repo: Arc, preference_repo: Arc, repo: Arc, override_repo: Arc, @@ -120,10 +120,15 @@ impl AssistantService { .map_err(|e| AssistantError::Internal(format!("encode builtin custom skills: {e}")))?; let default_disabled_builtin_skill_ids = serde_json::to_string(&builtin.disabled_builtin_skills) .map_err(|e| AssistantError::Internal(format!("encode builtin disabled skills: {e}")))?; + let (avatar_type, avatar_value) = serialize_avatar("builtin", builtin.avatar.as_deref()); + let (definition_id, assistant_key) = self + .resolve_definition_identity("builtin", Some(&builtin.id), &builtin.id) + .await?; self.definition_repo .upsert(&UpsertAssistantDefinitionParams { - id: &builtin.id, + definition_id: &definition_id, + assistant_key: &assistant_key, source: "builtin", owner_type: "system", source_ref: Some(&builtin.id), @@ -133,26 +138,27 @@ impl AssistantService { name_i18n: &name_i18n, description: builtin.description.as_deref(), description_i18n: &description_i18n, - avatar: builtin.avatar.as_deref(), + avatar_type: &avatar_type, + avatar_value: avatar_value.as_deref(), agent_backend: &builtin.preset_agent_type, rule_resource_type: if builtin.rule_file.is_some() { "builtin_asset" } else { "none" }, - rule_resource_ref: builtin.rule_file.as_deref(), + rule_resource_ref: builtin.rule_file.as_ref().map(|_| builtin.id.as_str()), rule_inline_content: None, recommended_prompts: &recommended_prompts, recommended_prompts_i18n: &recommended_prompts_i18n, - default_model_mode: "auto", + default_model_mode: "unset", default_model_value: None, - default_permission_mode: "auto", + default_permission_mode: "unset", default_permission_value: None, default_skills_mode: "fixed", default_skill_ids: &default_skill_ids, custom_skill_names: &custom_skill_names, default_disabled_builtin_skill_ids: &default_disabled_builtin_skill_ids, - default_mcps_mode: "auto", + default_mcps_mode: "unset", default_mcp_ids: "[]", }) .await @@ -174,48 +180,48 @@ impl AssistantService { async fn sync_legacy_overrides_to_new_states(&self) -> Result<(), AssistantError> { for override_row in self.override_repo.get_all().await? { - if self.definition_repo.get(&override_row.assistant_id).await?.is_none() { + let Some(definition) = self.definition_repo.get_by_key(&override_row.assistant_id).await? else { warn!( assistant_id = %override_row.assistant_id, "skip syncing assistant override without unified definition" ); continue; - } + }; self.state_repo - .upsert(&UpsertAssistantStateParams { - assistant_id: &override_row.assistant_id, + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled: override_row.enabled, sort_order: override_row.sort_order, agent_backend_override: override_row.preset_agent_type.as_deref(), last_used_at: override_row.last_used_at, }) .await - .map_err(|e| AssistantError::Internal(format!("upsert assistant state: {e}")))?; + .map_err(|e| AssistantError::Internal(format!("upsert assistant overlay: {e}")))?; } Ok(()) } async fn upsert_definition_from_legacy_user_row(&self, row: &AssistantRow) -> Result<(), AssistantError> { - let name_i18n = normalize_json_object_string(row.name_i18n.as_deref(), "name_i18n")?; - let description_i18n = normalize_json_object_string(row.description_i18n.as_deref(), "description_i18n")?; + // User-defined assistants do not expose locale-aware editing in the + // current product. Keep the unified definition canonical fields as the + // single source of truth and leave *_i18n empty for user rows. + let name_i18n = "{}".to_string(); + let description_i18n = "{}".to_string(); let recommended_prompts = normalize_json_array_string(row.prompts.as_deref(), "prompts")?; - let recommended_prompts_i18n = - normalize_json_map_of_arrays_string(row.prompts_i18n.as_deref(), "prompts_i18n")?; + let recommended_prompts_i18n = "{}".to_string(); let default_skill_ids = normalize_json_array_string(row.enabled_skills.as_deref(), "enabled_skills")?; let custom_skill_names = normalize_json_array_string(row.custom_skill_names.as_deref(), "custom_skill_names")?; let default_disabled_builtin_skill_ids = normalize_json_array_string(row.disabled_builtin_skills.as_deref(), "disabled_builtin_skills")?; - let models = decode_str_list(row.models.as_deref())?; - let (default_model_mode, default_model_value) = match models.first() { - Some(model) => ("fixed", Some(model.as_str())), - None => ("auto", None), - }; + let (avatar_type, avatar_value) = serialize_avatar("user", row.avatar.as_deref()); + let (definition_id, assistant_key) = self.resolve_definition_identity("user", Some(&row.id), &row.id).await?; self.definition_repo .upsert(&UpsertAssistantDefinitionParams { - id: &row.id, + definition_id: &definition_id, + assistant_key: &assistant_key, source: "user", owner_type: "user", source_ref: Some(&row.id), @@ -225,22 +231,23 @@ impl AssistantService { name_i18n: &name_i18n, description: row.description.as_deref(), description_i18n: &description_i18n, - avatar: row.avatar.as_deref(), + avatar_type: &avatar_type, + avatar_value: avatar_value.as_deref(), agent_backend: &row.preset_agent_type, rule_resource_type: "user_file", rule_resource_ref: Some(&row.id), rule_inline_content: None, recommended_prompts: &recommended_prompts, recommended_prompts_i18n: &recommended_prompts_i18n, - default_model_mode, - default_model_value, - default_permission_mode: "auto", + default_model_mode: "unset", + default_model_value: None, + default_permission_mode: "unset", default_permission_value: None, default_skills_mode: "fixed", default_skill_ids: &default_skill_ids, custom_skill_names: &custom_skill_names, default_disabled_builtin_skill_ids: &default_disabled_builtin_skill_ids, - default_mcps_mode: "auto", + default_mcps_mode: "unset", default_mcp_ids: "[]", }) .await @@ -253,14 +260,15 @@ impl AssistantService { &self, assistant_id: &str, overrides: SerializedDetailOverrides, + reset_model_and_permission: bool, ) -> Result<(), AssistantError> { - if !overrides.has_changes() { + if !overrides.has_changes() && !reset_model_and_permission { return Ok(()); } let Some(existing) = self .definition_repo - .get(assistant_id) + .get_by_key(assistant_id) .await .map_err(|e| AssistantError::Internal(format!("get assistant definition: {e}")))? else { @@ -268,6 +276,12 @@ impl AssistantService { }; let mut patched = existing.clone(); + if reset_model_and_permission { + patched.default_model_mode = "unset".to_string(); + patched.default_model_value = None; + patched.default_permission_mode = "unset".to_string(); + patched.default_permission_value = None; + } if let Some(value) = overrides.recommended_prompts.as_deref() { patched.recommended_prompts = value.to_string(); } @@ -302,7 +316,8 @@ impl AssistantService { let patched = self .definition_repo .upsert(&UpsertAssistantDefinitionParams { - id: &patched.id, + definition_id: &patched.definition_id, + assistant_key: &patched.assistant_key, source: &patched.source, owner_type: &patched.owner_type, source_ref: patched.source_ref.as_deref(), @@ -312,7 +327,8 @@ impl AssistantService { name_i18n: &patched.name_i18n, description: patched.description.as_deref(), description_i18n: &patched.description_i18n, - avatar: patched.avatar.as_deref(), + avatar_type: &patched.avatar_type, + avatar_value: patched.avatar_value.as_deref(), agent_backend: &patched.agent_backend, rule_resource_type: &patched.rule_resource_type, rule_resource_ref: patched.rule_resource_ref.as_deref(), @@ -335,9 +351,9 @@ impl AssistantService { let state = self .state_repo - .get(assistant_id) + .get(&patched.definition_id) .await - .map_err(|e| AssistantError::Internal(format!("get assistant state: {e}")))?; + .map_err(|e| AssistantError::Internal(format!("get assistant overlay: {e}")))?; rebuild_legacy_assistant_mirror(&self.pool, &patched, state.as_ref()) .await .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; @@ -351,10 +367,10 @@ impl AssistantService { .state_repo .list() .await - .map_err(|e| AssistantError::Internal(format!("list assistant states: {e}")))?; - let state_map: HashMap = states + .map_err(|e| AssistantError::Internal(format!("list assistant overlays: {e}")))?; + let state_map: HashMap = states .into_iter() - .map(|state| (state.assistant_id.clone(), state)) + .map(|state| (state.definition_id.clone(), state)) .collect(); for definition in self @@ -363,7 +379,7 @@ impl AssistantService { .await .map_err(|e| AssistantError::Internal(format!("list assistant definitions: {e}")))? { - rebuild_legacy_assistant_mirror(&self.pool, &definition, state_map.get(&definition.id)) + rebuild_legacy_assistant_mirror(&self.pool, &definition, state_map.get(&definition.definition_id)) .await .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; } @@ -403,17 +419,20 @@ impl AssistantService { .state_repo .list() .await - .map_err(|e| AssistantError::Internal(format!("list assistant states: {e}")))?; + .map_err(|e| AssistantError::Internal(format!("list assistant overlays: {e}")))?; let extensions = self.extension_registry.get_assistants().await; - let state_map: HashMap = states + let state_map: HashMap = states .into_iter() - .map(|state| (state.assistant_id.clone(), state)) + .map(|state| (state.definition_id.clone(), state)) .collect(); let mut result = Vec::new(); for definition in &definitions { - result.push(definition_to_response(definition, state_map.get(&definition.id))?); + result.push(definition_to_response( + definition, + state_map.get(&definition.definition_id), + )?); } for e in &extensions { result.push(extension_to_response(e)); @@ -437,8 +456,8 @@ impl AssistantService { } pub async fn get(&self, id: &str) -> Result { - if let Some(definition) = self.definition_repo.get(id).await? { - let state = self.state_repo.get(id).await?; + if let Some(definition) = self.definition_repo.get_by_key(id).await? { + let state = self.state_repo.get(&definition.definition_id).await?; return definition_to_response(&definition, state.as_ref()); } @@ -450,9 +469,9 @@ impl AssistantService { } pub async fn get_detail(&self, id: &str, locale: Option<&str>) -> Result { - if let Some(definition) = self.definition_repo.get(id).await? { - let state = self.state_repo.get(id).await?; - let preference = self.preference_repo.get(id).await?; + if let Some(definition) = self.definition_repo.get_by_key(id).await? { + let state = self.state_repo.get(&definition.definition_id).await?; + let preference = self.preference_repo.get(&definition.definition_id).await?; let rules_content = self.read_rule(id, locale).await?; return definition_to_detail_response(&definition, state.as_ref(), preference.as_ref(), &rules_content); } @@ -557,16 +576,23 @@ impl AssistantService { let row = self.repo.create(¶ms).await?; self.upsert_definition_from_legacy_user_row(&row).await?; - self.apply_detail_overrides(&row.id, detail_overrides).await?; + self.apply_detail_overrides(&row.id, detail_overrides, false).await?; self.get(&id).await } pub async fn update(&self, id: &str, req: UpdateAssistantRequest) -> Result { match self.classify_source(id).await { AssistantSource::Builtin => { + let detail_overrides = SerializedDetailOverrides::from_update(&req)?; + let builtin_defaults_forbidden = req + .defaults + .as_ref() + .is_some_and(|defaults| defaults.skills.is_some() || defaults.mcps.is_some()); + // Built-in rows are sourced from the embedded bundle and can't - // be mutated. Users may still override `preset_agent_type` — - // that lives in the overrides table. Any other field on the + // be mutated. Users may still override `preset_agent_type`, and + // product-defined governance allows model/permission defaults + // to vary per built-in assistant. Any other field on the // request is rejected so callers don't silently lose data. if req.name.is_some() || req.description.is_some() @@ -581,10 +607,10 @@ impl AssistantService { || req.prompts_i18n.is_some() || req.recommended_prompts.is_some() || req.recommended_prompts_i18n.is_some() - || req.defaults.is_some() + || builtin_defaults_forbidden { return Err(AssistantError::Forbidden( - "Only 'preset_agent_type' can be overridden on built-in assistants".into(), + "Only 'preset_agent_type', 'defaults.model', and 'defaults.permission' can be overridden on built-in assistants".into(), )); } @@ -593,27 +619,42 @@ impl AssistantService { "'preset_agent_type' is required when updating a built-in assistant".into(), ) })?; + let definition = self + .definition_repo + .get_by_key(id) + .await? + .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; let existing = self.override_repo.get(id).await?; let enabled = existing.as_ref().is_none_or(|o| o.enabled); let sort_order = existing.as_ref().map(|o| o.sort_order).unwrap_or(0); let last_used_at = existing.as_ref().and_then(|o| o.last_used_at); + let current_agent_backend = self + .state_repo + .get(&definition.definition_id) + .await + .map_err(|e| AssistantError::Internal(format!("get assistant overlay: {e}")))? + .and_then(|row| row.agent_backend_override) + .unwrap_or_else(|| definition.agent_backend.clone()); + let reset_model_and_permission = current_agent_backend != preset_agent_type; self.state_repo - .upsert(&UpsertAssistantStateParams { - assistant_id: id, + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled, sort_order, agent_backend_override: Some(preset_agent_type), last_used_at, }) .await - .map_err(|e| AssistantError::Internal(format!("upsert assistant state: {e}")))?; + .map_err(|e| AssistantError::Internal(format!("upsert assistant overlay: {e}")))?; + self.apply_detail_overrides(id, detail_overrides, reset_model_and_permission) + .await?; let definition = self .definition_repo - .get(id) + .get_by_key(id) .await? .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; - let state = self.state_repo.get(id).await?; + let state = self.state_repo.get(&definition.definition_id).await?; rebuild_legacy_assistant_mirror(&self.pool, &definition, state.as_ref()) .await .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; @@ -629,6 +670,15 @@ impl AssistantService { let serialized = SerializedFields::from_update(&req)?; let detail_overrides = SerializedDetailOverrides::from_update(&req)?; + let current_definition = self + .definition_repo + .get_by_key(id) + .await? + .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + let reset_model_and_permission = req + .preset_agent_type + .as_deref() + .is_some_and(|preset_agent_type| preset_agent_type != current_definition.agent_backend); let params = UpdateAssistantParams { name: req.name.as_deref(), description: req.description.as_ref().map(|s| Some(s.as_str())), @@ -650,7 +700,8 @@ impl AssistantService { .await? .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; self.upsert_definition_from_legacy_user_row(&row).await?; - self.apply_detail_overrides(id, detail_overrides).await?; + self.apply_detail_overrides(id, detail_overrides, reset_model_and_permission) + .await?; self.get(id).await } @@ -676,14 +727,20 @@ impl AssistantService { if let Err(e) = self.override_repo.delete(id).await { warn!("failed to remove override for deleted assistant '{id}': {e}"); } - if let Err(e) = self.state_repo.delete(id).await { - warn!("failed to remove assistant state for deleted assistant '{id}': {e}"); - } - if let Err(e) = self.preference_repo.delete(id).await { - warn!("failed to remove assistant preferences for deleted assistant '{id}': {e}"); - } - if let Err(e) = self.definition_repo.soft_delete(id, now_ms()).await { - warn!("failed to soft-delete assistant definition for deleted assistant '{id}': {e}"); + if let Some(definition) = self.definition_repo.get_by_key(id).await? { + if let Err(e) = self.state_repo.delete(&definition.definition_id).await { + warn!("failed to remove assistant overlay for deleted assistant '{id}': {e}"); + } + if let Err(e) = self.preference_repo.delete(&definition.definition_id).await { + warn!("failed to remove assistant preferences for deleted assistant '{id}': {e}"); + } + if let Err(e) = self + .definition_repo + .soft_delete(&definition.definition_id, now_ms()) + .await + { + warn!("failed to soft-delete assistant definition for deleted assistant '{id}': {e}"); + } } // Best-effort filesystem cleanup. @@ -711,7 +768,12 @@ impl AssistantService { } // Merge with existing state/override to preserve fields not in this request. - let existing_state = self.state_repo.get(id).await?; + let definition = self + .definition_repo + .get_by_key(id) + .await? + .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + let existing_state = self.state_repo.get(&definition.definition_id).await?; let existing = self.override_repo.get(id).await?; let enabled = req.enabled.unwrap_or_else(|| { existing_state @@ -734,20 +796,15 @@ impl AssistantService { .or_else(|| existing.as_ref().and_then(|o| o.preset_agent_type.as_deref())); let state = self .state_repo - .upsert(&UpsertAssistantStateParams { - assistant_id: id, + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled, sort_order, agent_backend_override, last_used_at, }) .await - .map_err(|e| AssistantError::Internal(format!("upsert assistant state: {e}")))?; - let definition = self - .definition_repo - .get(id) - .await? - .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + .map_err(|e| AssistantError::Internal(format!("upsert assistant overlay: {e}")))?; rebuild_legacy_assistant_mirror(&self.pool, &definition, Some(&state)) .await .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; @@ -1057,6 +1114,34 @@ impl AssistantService { assistant_md_path(&self.user_skills_dir(), id, locale) } + async fn resolve_definition_identity( + &self, + source: &str, + source_ref: Option<&str>, + assistant_key: &str, + ) -> Result<(String, String), AssistantError> { + if let Some(source_ref) = source_ref + && let Some(existing) = self + .definition_repo + .get_by_source_ref(source, source_ref) + .await + .map_err(|e| AssistantError::Internal(format!("get assistant definition by source_ref: {e}")))? + { + return Ok((existing.definition_id, existing.assistant_key)); + } + + if let Some(existing) = self + .definition_repo + .get_by_key(assistant_key) + .await + .map_err(|e| AssistantError::Internal(format!("get assistant definition by key: {e}")))? + { + return Ok((existing.definition_id, existing.assistant_key)); + } + + Ok((generate_prefixed_id("asstdef"), assistant_key.to_string())) + } + fn cleanup_user_assets(&self, id: &str) { remove_assistant_md_files(&self.user_rules_dir(), id); remove_assistant_md_files(&self.user_skills_dir(), id); @@ -1134,9 +1219,34 @@ fn assistant_error_to_extension_error(error: AssistantError) -> ExtensionError { /// configured providers and returns a more specific default when possible. const DEFAULT_AGENT_TYPE: &str = "aionrs"; +fn avatar_display_value(definition: &AssistantDefinitionRow) -> Option { + definition.avatar_value.clone() +} + +fn serialize_avatar(source: &str, avatar: Option<&str>) -> (String, Option) { + let Some(value) = avatar.map(str::trim).filter(|value| !value.is_empty()) else { + return ("none".to_string(), None); + }; + + let avatar_type = if looks_like_avatar_asset(value) { + match source { + "builtin" => "builtin_asset", + _ => "user_asset", + } + } else { + "emoji" + }; + + (avatar_type.to_string(), Some(value.to_string())) +} + +fn looks_like_avatar_asset(value: &str) -> bool { + value.contains('/') || (std::path::Path::new(value).extension().is_some() && !value.starts_with('.')) +} + fn definition_to_response( definition: &AssistantDefinitionRow, - state: Option<&AssistantStateRow>, + state: Option<&AssistantOverlayRow>, ) -> Result { let source = match definition.source.as_str() { "builtin" => AssistantSource::Builtin, @@ -1152,13 +1262,13 @@ fn definition_to_response( }; Ok(AssistantResponse { - id: definition.id.clone(), + id: definition.assistant_key.clone(), source, name: definition.name.clone(), name_i18n: decode_str_map(Some(definition.name_i18n.as_str()))?, description: definition.description.clone(), description_i18n: decode_str_map(Some(definition.description_i18n.as_str()))?, - avatar: definition.avatar.clone(), + avatar: avatar_display_value(definition), enabled: state.is_none_or(|row| row.enabled), sort_order: state.map(|row| row.sort_order).unwrap_or(0), preset_agent_type: state @@ -1178,7 +1288,7 @@ fn definition_to_response( fn definition_to_detail_response( definition: &AssistantDefinitionRow, - state: Option<&AssistantStateRow>, + state: Option<&AssistantOverlayRow>, preference: Option<&aionui_db::AssistantPreferenceRow>, rules_content: &str, ) -> Result { @@ -1201,7 +1311,7 @@ fn definition_to_detail_response( .unwrap_or_default(); Ok(AssistantDetailResponse { - id: definition.id.clone(), + id: definition.assistant_key.clone(), source: match definition.source.as_str() { "builtin" => AssistantSource::Builtin, "extension" => AssistantSource::Extension, @@ -1212,7 +1322,7 @@ fn definition_to_detail_response( name_i18n: decode_str_map(Some(definition.name_i18n.as_str()))?, description: definition.description.clone(), description_i18n: decode_str_map(Some(definition.description_i18n.as_str()))?, - avatar: definition.avatar.clone(), + avatar: avatar_display_value(definition), }, state: AssistantStateResponse { enabled: state.map(|row| row.enabled).unwrap_or(true), @@ -1322,11 +1432,11 @@ fn extension_to_detail_response(e: &ResolvedAssistant) -> AssistantDetailRespons }, defaults: AssistantDefaultsResponse { model: AssistantDefaultScalarResponse { - mode: "auto".to_string(), + mode: "unset".to_string(), value: None, }, permission: AssistantDefaultScalarResponse { - mode: "auto".to_string(), + mode: "unset".to_string(), value: None, }, skills: AssistantDefaultListResponse { @@ -1334,7 +1444,7 @@ fn extension_to_detail_response(e: &ResolvedAssistant) -> AssistantDetailRespons value: Vec::new(), }, mcps: AssistantDefaultListResponse { - mode: "auto".to_string(), + mode: "unset".to_string(), value: Vec::new(), }, }, @@ -1431,12 +1541,14 @@ impl SerializedDetailOverrides { fn from_parts( recommended_prompts: Option<&[String]>, - recommended_prompts_i18n: Option<&HashMap>>, + _recommended_prompts_i18n: Option<&HashMap>>, defaults: Option<&AssistantDefaultsRequest>, ) -> Result { let mut result = Self { recommended_prompts: encode_str_list(recommended_prompts)?, - recommended_prompts_i18n: encode_list_map(recommended_prompts_i18n)?, + // User-defined assistants currently have no locale-aware editor. + // Keep unified storage canonical-only until product exposes it. + recommended_prompts_i18n: None, ..Default::default() }; @@ -1494,6 +1606,7 @@ fn validate_scalar_default( field_name: &str, ) -> Result<(String, Option), AssistantError> { match value.mode.as_str() { + "unset" => Ok(("unset".into(), None)), "auto" => Ok(("auto".into(), None)), "fixed" => { let fixed = value.value.clone().filter(|v| !v.trim().is_empty()).ok_or_else(|| { @@ -1502,7 +1615,7 @@ fn validate_scalar_default( Ok(("fixed".into(), Some(fixed))) } other => Err(AssistantError::BadRequest(format!( - "{field_name}.mode must be 'auto' or 'fixed', got '{other}'" + "{field_name}.mode must be 'unset', 'auto' or 'fixed', got '{other}'" ))), } } @@ -1512,6 +1625,7 @@ fn validate_list_default( field_name: &str, ) -> Result<(String, String), AssistantError> { match value.mode.as_str() { + "unset" => Ok(("unset".into(), "[]".into())), "auto" => Ok(("auto".into(), "[]".into())), "fixed" => Ok(( "fixed".into(), @@ -1519,7 +1633,7 @@ fn validate_list_default( .map_err(|e| AssistantError::Internal(format!("encode {field_name}: {e}")))?, )), other => Err(AssistantError::BadRequest(format!( - "{field_name}.mode must be 'auto' or 'fixed', got '{other}'" + "{field_name}.mode must be 'unset', 'auto' or 'fixed', got '{other}'" ))), } } @@ -1573,14 +1687,6 @@ fn normalize_json_array_string(raw: Option<&str>, field: &str) -> Result, field: &str) -> Result { - serde_json::to_string(&decode_str_map(raw)?).map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) -} - -fn normalize_json_map_of_arrays_string(raw: Option<&str>, field: &str) -> Result { - serde_json::to_string(&decode_list_map(raw)?).map_err(|e| AssistantError::Internal(format!("encode {field}: {e}"))) -} - // --------------------------------------------------------------------------- // Filesystem helpers // --------------------------------------------------------------------------- @@ -1664,8 +1770,8 @@ pub fn generate_user_id() -> String { mod tests { use super::*; use aionui_db::{ - CreateProviderParams, SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, - SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteAssistantStateRepository, + CreateProviderParams, SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, + SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteProviderRepository, init_database_memory, }; use aionui_extension::ExtensionStateStore; @@ -1675,7 +1781,7 @@ mod tests { struct Fixture { service: AssistantService, definition_repo: Arc, - state_repo: Arc, + state_repo: Arc, provider_repo: Arc, _tmp: TempDir, _db: aionui_db::Database, @@ -1714,8 +1820,8 @@ mod tests { let db = init_database_memory().await.unwrap(); let definition_repo: Arc = Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); - let state_repo: Arc = - Arc::new(SqliteAssistantStateRepository::new(db.pool().clone())); + let state_repo: Arc = + Arc::new(SqliteAssistantOverlayRepository::new(db.pool().clone())); let preference_repo: Arc = Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(db.pool().clone())); @@ -1850,7 +1956,9 @@ mod tests { #[tokio::test] async fn bootstrap_materializes_builtin_and_syncs_legacy_rows() { - let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await; + let mut builtin = mk_builtin("builtin-office", "Office"); + builtin.rule_file = Some("rules/builtin-office.{locale}.md".into()); + let fx = fixture_with_builtins(vec![builtin]).await; fx.service .create(CreateAssistantRequest { @@ -1874,16 +1982,50 @@ mod tests { fx.service.bootstrap_assistant_storage().await.unwrap(); - let builtin = fx.definition_repo.get("builtin-office").await.unwrap().unwrap(); + let builtin = fx.definition_repo.get_by_key("builtin-office").await.unwrap().unwrap(); assert_eq!(builtin.source, "builtin"); - let user = fx.definition_repo.get("u1").await.unwrap().unwrap(); + assert_eq!(builtin.rule_resource_type, "builtin_asset"); + assert_eq!(builtin.rule_resource_ref.as_deref(), Some("builtin-office")); + let user = fx.definition_repo.get_by_key("u1").await.unwrap().unwrap(); assert_eq!(user.source, "user"); - let builtin_state = fx.state_repo.get("builtin-office").await.unwrap().unwrap(); + let builtin_state = fx.state_repo.get(&builtin.definition_id).await.unwrap().unwrap(); assert!(!builtin_state.enabled); assert_eq!(builtin_state.sort_order, 9); assert_eq!(builtin_state.last_used_at, Some(1234)); } + #[tokio::test] + async fn create_user_definition_ignores_i18n_payloads_in_unified_storage() { + let fx = fixture().await; + let mut name_i18n = HashMap::new(); + name_i18n.insert("zh-CN".into(), "中文名".into()); + let mut description_i18n = HashMap::new(); + description_i18n.insert("zh-CN".into(), "中文描述".into()); + let mut prompts_i18n = HashMap::new(); + prompts_i18n.insert("zh-CN".into(), vec!["中文提示词".into()]); + let mut recommended_prompts_i18n = HashMap::new(); + recommended_prompts_i18n.insert("zh-CN".into(), vec!["推荐提示词".into()]); + + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + description: Some("desc".into()), + name_i18n: Some(name_i18n), + description_i18n: Some(description_i18n), + prompts_i18n: Some(prompts_i18n), + recommended_prompts_i18n: Some(recommended_prompts_i18n), + ..req_default() + }) + .await + .unwrap(); + + let definition = fx.definition_repo.get_by_key("u1").await.unwrap().unwrap(); + assert_eq!(definition.name_i18n, "{}"); + assert_eq!(definition.description_i18n, "{}"); + assert_eq!(definition.recommended_prompts_i18n, "{}"); + } + #[tokio::test] async fn create_rejects_empty_name() { let fx = fixture().await; @@ -1982,6 +2124,99 @@ mod tests { assert_eq!(listed.preset_agent_type, "claude"); } + #[tokio::test] + async fn update_builtin_allows_agent_model_and_permission_overrides() { + let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await; + let updated = fx + .service + .update( + "builtin-office", + UpdateAssistantRequest { + preset_agent_type: Some("gemini".into()), + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("gemini-2.5-pro".into()), + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("default".into()), + }), + ..Default::default() + }), + ..Default::default() + }, + ) + .await + .unwrap(); + + assert_eq!(updated.source, AssistantSource::Builtin); + assert_eq!(updated.preset_agent_type, "gemini"); + + let detail = fx.service.get_detail("builtin-office", Some("en-US")).await.unwrap(); + assert_eq!(detail.defaults.model.mode, "fixed"); + assert_eq!(detail.defaults.model.value.as_deref(), Some("gemini-2.5-pro")); + assert_eq!(detail.defaults.permission.mode, "fixed"); + assert_eq!(detail.defaults.permission.value.as_deref(), Some("default")); + } + + #[tokio::test] + async fn update_builtin_changing_agent_without_defaults_clears_model_and_permission() { + let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await; + fx.service + .update( + "builtin-office", + UpdateAssistantRequest { + preset_agent_type: Some("gemini".into()), + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("gemini-2.5-pro".into()), + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("default".into()), + }), + ..Default::default() + }), + ..Default::default() + }, + ) + .await + .unwrap(); + + fx.service + .update( + "builtin-office", + UpdateAssistantRequest { + preset_agent_type: Some("claude".into()), + ..Default::default() + }, + ) + .await + .unwrap(); + + let detail = fx.service.get_detail("builtin-office", Some("en-US")).await.unwrap(); + assert_eq!(detail.engine.agent_backend, "claude"); + assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.model.value, None); + assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.permission.value, None); + } + + #[tokio::test] + async fn builtin_detail_defaults_start_unset_for_model_permission_and_mcps() { + let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await; + + let detail = fx.service.get_detail("builtin-office", Some("en-US")).await.unwrap(); + assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.model.value, None); + assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.permission.value, None); + assert_eq!(detail.defaults.mcps.mode, "unset"); + assert!(detail.defaults.mcps.value.is_empty()); + } + #[tokio::test] async fn update_user_partial_preserves_other_fields() { let fx = fixture().await; @@ -2009,6 +2244,66 @@ mod tests { assert_eq!(updated.description.as_deref(), Some("desc")); } + #[tokio::test] + async fn update_user_changing_agent_without_defaults_clears_model_and_permission() { + let fx = fixture().await; + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("openai/gpt-5".into()), + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("default".into()), + }), + ..Default::default() + }), + ..req_default() + }) + .await + .unwrap(); + + fx.service + .update( + "u1", + UpdateAssistantRequest { + preset_agent_type: Some("codex".into()), + ..Default::default() + }, + ) + .await + .unwrap(); + + let detail = fx.service.get_detail("u1", Some("en-US")).await.unwrap(); + assert_eq!(detail.engine.agent_backend, "codex"); + assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.model.value, None); + assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.permission.value, None); + } + + #[tokio::test] + async fn create_user_without_governance_defaults_starts_unset() { + let fx = fixture().await; + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + ..req_default() + }) + .await + .unwrap(); + + let detail = fx.service.get_detail("u1", Some("en-US")).await.unwrap(); + assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.mcps.mode, "unset"); + } + #[tokio::test] async fn create_persists_detail_defaults_and_recommended_prompts() { let fx = fixture().await; @@ -2339,8 +2634,8 @@ mod tests { let definition_repo: Arc = Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); - let state_repo: Arc = - Arc::new(SqliteAssistantStateRepository::new(db.pool().clone())); + let state_repo: Arc = + Arc::new(SqliteAssistantOverlayRepository::new(db.pool().clone())); let preference_repo: Arc = Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); let repo: Arc = Arc::new(SqliteAssistantRepository::new(db.pool().clone())); diff --git a/crates/aionui-conversation/src/service.rs b/crates/aionui-conversation/src/service.rs index 99cdc4c3..04bfc2be 100644 --- a/crates/aionui-conversation/src/service.rs +++ b/crates/aionui-conversation/src/service.rs @@ -25,8 +25,8 @@ use aionui_common::{ use aionui_db::models::{ConversationRow, MessageRow}; use aionui_db::{ ConversationFilters, ConversationRowUpdate, CreateAcpSessionParams, IAcpSessionRepository, - IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantPreferenceRepository, - IAssistantStateRepository, IConversationRepository, IMcpServerRepository, SaveRuntimeStateParams, SortOrder, + IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverlayRepository, + IAssistantPreferenceRepository, IConversationRepository, IMcpServerRepository, SaveRuntimeStateParams, SortOrder, }; use aionui_extension::AssistantRuleDispatcher; use aionui_mcp::{AcpMcpCapabilities, parse_acp_mcp_capabilities}; @@ -181,7 +181,7 @@ pub struct ConversationService { cron_service: Arc>>>, mcp_server_repo: Arc>>>, assistant_definition_repo: Arc>>>, - assistant_state_repo: Arc>>>, + assistant_state_repo: Arc>>>, assistant_preference_repo: Arc>>>, assistant_dispatcher: Arc>>>, runtime_state: Arc, @@ -248,7 +248,7 @@ impl ConversationService { } } - pub fn with_assistant_state_repo(&self, repo: Arc) { + pub fn with_assistant_state_repo(&self, repo: Arc) { if let Ok(mut guard) = self.assistant_state_repo.write() { *guard = Some(repo); } @@ -318,7 +318,7 @@ impl ConversationService { .and_then(|guard| guard.as_ref().cloned()) } - fn assistant_state_repo(&self) -> Option> { + fn assistant_state_repo(&self) -> Option> { self.assistant_state_repo .read() .ok() @@ -874,7 +874,7 @@ impl ConversationService { }; let Some(definition) = definition_repo - .get(assistant_id) + .get_by_key(assistant_id) .await .map_err(|e| ConversationError::internal(format!("assistant definition lookup failed: {e}")))? else { @@ -882,11 +882,11 @@ impl ConversationService { }; let state = state_repo - .get(assistant_id) + .get(&definition.definition_id) .await .map_err(|e| ConversationError::internal(format!("assistant state lookup failed: {e}")))?; let preference = preference_repo - .get(assistant_id) + .get(&definition.definition_id) .await .map_err(|e| ConversationError::internal(format!("assistant preference lookup failed: {e}")))?; @@ -923,6 +923,7 @@ impl ConversationService { None if definition.default_mcps_mode == "fixed" => { parse_json_string_list(Some(definition.default_mcp_ids.as_str()), "default_mcp_ids")? } + None if definition.default_mcps_mode == "unset" => Vec::new(), None => preference .as_ref() .map(|row| parse_json_string_list(Some(row.last_mcp_ids.as_str()), "last_mcp_ids")) @@ -935,14 +936,16 @@ impl ConversationService { .clone() .or_else(|| match definition.default_model_mode.as_str() { "fixed" => definition.default_model_value.clone(), - _ => preference.as_ref().and_then(|row| row.last_model_id.clone()), + "auto" => preference.as_ref().and_then(|row| row.last_model_id.clone()), + _ => None, }); let permission = overrides .permission .clone() .or_else(|| match definition.default_permission_mode.as_str() { "fixed" => definition.default_permission_value.clone(), - _ => preference.as_ref().and_then(|row| row.last_permission_value.clone()), + "auto" => preference.as_ref().and_then(|row| row.last_permission_value.clone()), + _ => None, }); let rules_content = if let Some(dispatcher) = self.assistant_dispatcher() { @@ -967,7 +970,7 @@ impl ConversationService { assistant_id: assistant_id.to_owned(), assistant_source: definition.source, name: definition.name, - avatar: definition.avatar, + avatar: definition.avatar_value, agent_backend, rules: AssistantSnapshotRules { content: if rules_content.is_empty() { @@ -998,43 +1001,62 @@ impl ConversationService { return Ok(()); }; let Some(definition) = definition_repo - .get(assistant_id) + .get_by_key(assistant_id) .await .map_err(|e| ConversationError::internal(format!("assistant definition lookup failed: {e}")))? else { return Ok(()); }; - let last_model_id = (definition.default_model_mode == "auto") - .then_some(snapshot.resolved_defaults.model.as_deref()) - .flatten(); - let last_permission_value = (definition.default_permission_mode == "auto") - .then_some(snapshot.resolved_defaults.permission.as_deref()) - .flatten(); + let existing_preference = preference_repo + .get(&definition.definition_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant preference lookup failed: {e}")))?; + let last_model_id = if definition.default_model_mode == "auto" { + snapshot.resolved_defaults.model.clone() + } else { + existing_preference.as_ref().and_then(|row| row.last_model_id.clone()) + }; + let last_permission_value = if definition.default_permission_mode == "auto" { + snapshot.resolved_defaults.permission.clone() + } else { + existing_preference + .as_ref() + .and_then(|row| row.last_permission_value.clone()) + }; let last_skill_ids = if definition.default_skills_mode == "auto" { serde_json::to_string(&snapshot.resolved_defaults.skill_ids) .map_err(|e| ConversationError::internal(format!("encode assistant skills: {e}")))? } else { - definition.default_skill_ids.clone() + existing_preference + .as_ref() + .map(|row| row.last_skill_ids.clone()) + .unwrap_or_else(|| "[]".to_string()) }; let last_disabled_builtin_skill_ids = if definition.default_skills_mode == "auto" { serde_json::to_string(&snapshot.resolved_defaults.disabled_builtin_skill_ids) .map_err(|e| ConversationError::internal(format!("encode assistant disabled builtin skills: {e}")))? } else { - definition.default_disabled_builtin_skill_ids.clone() + existing_preference + .as_ref() + .map(|row| row.last_disabled_builtin_skill_ids.clone()) + .unwrap_or_else(|| "[]".to_string()) }; let last_mcp_ids = if definition.default_mcps_mode == "auto" { serde_json::to_string(&snapshot.resolved_defaults.mcp_ids) .map_err(|e| ConversationError::internal(format!("encode assistant mcps: {e}")))? } else { - definition.default_mcp_ids.clone() + existing_preference + .as_ref() + .map(|row| row.last_mcp_ids.clone()) + .unwrap_or_else(|| "[]".to_string()) }; preference_repo .upsert(&aionui_db::UpsertAssistantPreferenceParams { - assistant_id, - last_model_id, - last_permission_value, + definition_id: &definition.definition_id, + last_model_id: last_model_id.as_deref(), + last_permission_value: last_permission_value.as_deref(), last_skill_ids: &last_skill_ids, last_disabled_builtin_skill_ids: &last_disabled_builtin_skill_ids, last_mcp_ids: &last_mcp_ids, diff --git a/crates/aionui-conversation/src/service_test.rs b/crates/aionui-conversation/src/service_test.rs index 80672896..c01f871c 100644 --- a/crates/aionui-conversation/src/service_test.rs +++ b/crates/aionui-conversation/src/service_test.rs @@ -29,11 +29,11 @@ use aionui_db::models::{ }; use aionui_db::{ ConversationFilters, ConversationRowUpdate, CreateAcpSessionParams, DbError, IAcpSessionRepository, - IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantPreferenceRepository, - IAssistantStateRepository, IConversationRepository, MessageRowUpdate, MessageSearchRow, PersistedSessionState, - SaveRuntimeStateParams, SortOrder, SqliteAssistantDefinitionRepository, SqliteAssistantPreferenceRepository, - SqliteAssistantStateRepository, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, - UpsertAssistantStateParams, init_database_memory, + IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverlayRepository, + IAssistantPreferenceRepository, IConversationRepository, MessageRowUpdate, MessageSearchRow, PersistedSessionState, + SaveRuntimeStateParams, SortOrder, SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, + SqliteAssistantPreferenceRepository, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, + UpsertAssistantPreferenceParams, init_database_memory, }; use aionui_extension::{AssistantRuleDispatcher, ExtensionError}; use aionui_realtime::EventBroadcaster; @@ -666,13 +666,13 @@ async fn make_service_with_assistant_support( Arc, Arc, Arc, - Arc, + Arc, Arc, ) { let (svc, broadcaster, repo, _task_mgr) = make_service_with_resolver(skill_resolver); let db = init_database_memory().await.unwrap(); let definition_repo = Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); - let state_repo = Arc::new(SqliteAssistantStateRepository::new(db.pool().clone())); + let state_repo = Arc::new(SqliteAssistantOverlayRepository::new(db.pool().clone())); let preference_repo: Arc = Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); @@ -3398,7 +3398,8 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { definition_repo .upsert(&UpsertAssistantDefinitionParams { - id: "preset-1", + definition_id: "asstdef_preset_1", + assistant_key: "preset-1", source: "builtin", owner_type: "system", source_ref: Some("preset-1"), @@ -3408,10 +3409,11 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { name_i18n: "{}", description: Some("desc"), description_i18n: "{}", - avatar: Some("🤖"), + avatar_type: "emoji", + avatar_value: Some("🤖"), agent_backend: "claude", rule_resource_type: "builtin_asset", - rule_resource_ref: Some("rules/preset-1.md"), + rule_resource_ref: Some("preset-1"), rule_inline_content: None, recommended_prompts: "[]", recommended_prompts_i18n: "{}", @@ -3429,8 +3431,8 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { .await .unwrap(); state_repo - .upsert(&UpsertAssistantStateParams { - assistant_id: "preset-1", + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_preset_1", enabled: true, sort_order: 0, agent_backend_override: Some("codex"), @@ -3440,7 +3442,7 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { .unwrap(); preference_repo .upsert(&UpsertAssistantPreferenceParams { - assistant_id: "preset-1", + definition_id: "asstdef_preset_1", last_model_id: Some("old-model"), last_permission_value: Some("workspace-write"), last_skill_ids: r#"["legacy-skill"]"#, @@ -3479,12 +3481,206 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { json!(["pdf"]) ); - let updated_pref = preference_repo.get("preset-1").await.unwrap().unwrap(); + let updated_pref = preference_repo.get("asstdef_preset_1").await.unwrap().unwrap(); assert_eq!(updated_pref.last_model_id.as_deref(), Some("new-model")); assert_eq!(updated_pref.last_skill_ids, r#"["pdf"]"#); assert_eq!(updated_pref.last_disabled_builtin_skill_ids, r#"["todo-tracker"]"#); } +#[tokio::test] +async fn create_does_not_overwrite_preferences_for_fixed_skills_and_mcps() { + let resolver = Arc::new(FixedSkillResolver { + names: vec!["cron".into(), "todo-tracker".into()], + }); + let dispatcher = Arc::new(StaticAssistantDispatcher { + rules: std::collections::HashMap::from([("preset-fixed".to_string(), "assistant rule body".to_string())]), + }); + let (svc, _broadcaster, _repo, definition_repo, state_repo, preference_repo) = + make_service_with_assistant_support(resolver, dispatcher).await; + let workspace = ensure_test_workspace_path(); + + definition_repo + .upsert(&UpsertAssistantDefinitionParams { + definition_id: "asstdef_preset_fixed", + assistant_key: "preset-fixed", + source: "builtin", + owner_type: "system", + source_ref: Some("preset-fixed"), + source_version: None, + source_hash: None, + name: "Preset Fixed", + name_i18n: "{}", + description: Some("desc"), + description_i18n: "{}", + avatar_type: "emoji", + avatar_value: Some("🤖"), + agent_backend: "claude", + rule_resource_type: "builtin_asset", + rule_resource_ref: Some("preset-fixed"), + rule_inline_content: None, + recommended_prompts: "[]", + recommended_prompts_i18n: "{}", + default_model_mode: "auto", + default_model_value: None, + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "fixed", + default_skill_ids: r#"["pdf"]"#, + custom_skill_names: "[]", + default_disabled_builtin_skill_ids: r#"["todo-tracker"]"#, + default_mcps_mode: "fixed", + default_mcp_ids: r#"["mcp-fixed"]"#, + }) + .await + .unwrap(); + state_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_preset_fixed", + enabled: true, + sort_order: 0, + agent_backend_override: Some("codex"), + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_preset_fixed", + last_model_id: Some("legacy-model"), + last_permission_value: Some("workspace-write"), + last_skill_ids: r#"["legacy-skill"]"#, + last_disabled_builtin_skill_ids: r#"["legacy-disabled"]"#, + last_mcp_ids: r#"["legacy-mcp"]"#, + }) + .await + .unwrap(); + + let req: CreateConversationRequest = serde_json::from_value(json!({ + "type": "acp", + "name": "t", + "extra": { + "workspace": workspace, + "backend": "claude", + "assistant_id": "preset-fixed", + "assistant_locale": "zh-CN", + "assistant_overrides": { + "model": "new-model", + "permission": "workspace-read", + "skill_ids": ["pdf", "cron"], + "disabled_builtin_skill_ids": [], + "mcp_ids": ["mcp-temp"] + } + }, + })) + .unwrap(); + let _resp = svc.create("user-1", req).await.unwrap(); + + let updated_pref = preference_repo.get("asstdef_preset_fixed").await.unwrap().unwrap(); + assert_eq!(updated_pref.last_model_id.as_deref(), Some("new-model")); + assert_eq!(updated_pref.last_permission_value.as_deref(), Some("workspace-read")); + assert_eq!(updated_pref.last_skill_ids, r#"["legacy-skill"]"#); + assert_eq!(updated_pref.last_disabled_builtin_skill_ids, r#"["legacy-disabled"]"#); + assert_eq!(updated_pref.last_mcp_ids, r#"["legacy-mcp"]"#); +} + +#[tokio::test] +async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() { + let resolver = Arc::new(FixedSkillResolver { + names: vec!["cron".into(), "todo-tracker".into()], + }); + let dispatcher = Arc::new(StaticAssistantDispatcher { + rules: std::collections::HashMap::from([("preset-unset".to_string(), "assistant rule body".to_string())]), + }); + let (svc, _broadcaster, _repo, definition_repo, state_repo, preference_repo) = + make_service_with_assistant_support(resolver, dispatcher).await; + let workspace = ensure_test_workspace_path(); + + definition_repo + .upsert(&UpsertAssistantDefinitionParams { + definition_id: "asstdef_preset_unset", + assistant_key: "preset-unset", + source: "builtin", + owner_type: "system", + source_ref: Some("preset-unset"), + source_version: None, + source_hash: None, + name: "Preset Unset", + name_i18n: "{}", + description: Some("desc"), + description_i18n: "{}", + avatar_type: "emoji", + avatar_value: Some("🤖"), + agent_backend: "claude", + rule_resource_type: "builtin_asset", + rule_resource_ref: Some("preset-unset"), + rule_inline_content: None, + recommended_prompts: "[]", + recommended_prompts_i18n: "{}", + default_model_mode: "unset", + default_model_value: None, + default_permission_mode: "unset", + default_permission_value: None, + default_skills_mode: "fixed", + default_skill_ids: r#"["pdf"]"#, + custom_skill_names: "[]", + default_disabled_builtin_skill_ids: "[]", + default_mcps_mode: "unset", + default_mcp_ids: "[]", + }) + .await + .unwrap(); + state_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_preset_unset", + enabled: true, + sort_order: 0, + agent_backend_override: Some("codex"), + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_preset_unset", + last_model_id: Some("legacy-model"), + last_permission_value: Some("workspace-write"), + last_skill_ids: r#"["legacy-skill"]"#, + last_disabled_builtin_skill_ids: r#"["legacy-disabled"]"#, + last_mcp_ids: r#"["legacy-mcp"]"#, + }) + .await + .unwrap(); + + let req: CreateConversationRequest = serde_json::from_value(json!({ + "type": "acp", + "name": "t", + "extra": { + "workspace": workspace, + "backend": "claude", + "assistant_id": "preset-unset", + "assistant_locale": "zh-CN" + }, + })) + .unwrap(); + let resp = svc.create("user-1", req).await.unwrap(); + + assert!(resp.extra.get("current_model_id").is_none()); + assert!(resp.extra.get("permission_mode").is_none()); + assert_eq!( + resp.extra["assistant_snapshot"]["resolved_defaults"]["skill_ids"], + json!(["pdf"]) + ); + assert_eq!( + resp.extra["assistant_snapshot"]["resolved_defaults"]["mcp_ids"], + json!([]) + ); + + let updated_pref = preference_repo.get("asstdef_preset_unset").await.unwrap().unwrap(); + assert_eq!(updated_pref.last_model_id.as_deref(), Some("legacy-model")); + assert_eq!(updated_pref.last_permission_value.as_deref(), Some("workspace-write")); + assert_eq!(updated_pref.last_mcp_ids, r#"["legacy-mcp"]"#); +} + #[tokio::test] async fn create_writes_empty_skills_when_no_auto_inject_and_no_preset() { let resolver = Arc::new(FixedSkillResolver { names: vec![] }); diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql index 93c87f7a..cf22cb7e 100644 --- a/crates/aionui-db/migrations/012_assistant_data_unification.sql +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -2,14 +2,15 @@ -- -- Introduces the new assistant runtime storage: -- - assistant_definitions --- - assistant_states +-- - assistant_overlays -- - assistant_preferences -- -- Legacy tables `assistants` and `assistant_overrides` are intentionally kept -- for downgrade compatibility and mirror projection. CREATE TABLE IF NOT EXISTS assistant_definitions ( - id TEXT PRIMARY KEY, + definition_id TEXT PRIMARY KEY, + assistant_key TEXT NOT NULL, source TEXT NOT NULL CHECK (source IN ('builtin', 'user', 'generated', 'extension')), owner_type TEXT NOT NULL @@ -21,7 +22,9 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( name_i18n TEXT NOT NULL DEFAULT '{}', description TEXT, description_i18n TEXT NOT NULL DEFAULT '{}', - avatar TEXT, + avatar_type TEXT NOT NULL DEFAULT 'none' + CHECK (avatar_type IN ('none', 'emoji', 'builtin_asset', 'user_asset')), + avatar_value TEXT, agent_backend TEXT NOT NULL, rule_resource_type TEXT NOT NULL CHECK ( @@ -38,10 +41,10 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( recommended_prompts TEXT NOT NULL DEFAULT '[]', recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', default_model_mode TEXT NOT NULL - CHECK (default_model_mode IN ('auto', 'fixed')), + CHECK (default_model_mode IN ('unset', 'auto', 'fixed')), default_model_value TEXT, default_permission_mode TEXT NOT NULL - CHECK (default_permission_mode IN ('auto', 'fixed')), + CHECK (default_permission_mode IN ('unset', 'auto', 'fixed')), default_permission_value TEXT, default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), @@ -49,7 +52,7 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( custom_skill_names TEXT NOT NULL DEFAULT '[]', default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', default_mcps_mode TEXT NOT NULL - CHECK (default_mcps_mode IN ('auto', 'fixed')), + CHECK (default_mcps_mode IN ('unset', 'auto', 'fixed')), default_mcp_ids TEXT NOT NULL DEFAULT '[]', created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, @@ -60,31 +63,34 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_assistant_definitions_source_ref ON assistant_definitions(source, source_ref) WHERE source_ref IS NOT NULL; +CREATE UNIQUE INDEX IF NOT EXISTS idx_assistant_definitions_assistant_key + ON assistant_definitions(assistant_key); + CREATE INDEX IF NOT EXISTS idx_assistant_definitions_source ON assistant_definitions(source); CREATE INDEX IF NOT EXISTS idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend); -CREATE TABLE IF NOT EXISTS assistant_states ( - assistant_id TEXT PRIMARY KEY, +CREATE TABLE IF NOT EXISTS assistant_overlays ( + definition_id TEXT PRIMARY KEY, enabled INTEGER NOT NULL DEFAULT 1, sort_order INTEGER NOT NULL DEFAULT 0, agent_backend_override TEXT, last_used_at INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, - FOREIGN KEY (assistant_id) REFERENCES assistant_definitions(id) ON DELETE CASCADE + FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE ); -CREATE INDEX IF NOT EXISTS idx_assistant_states_enabled - ON assistant_states(enabled); +CREATE INDEX IF NOT EXISTS idx_assistant_overlays_enabled + ON assistant_overlays(enabled); -CREATE INDEX IF NOT EXISTS idx_assistant_states_sort_order - ON assistant_states(sort_order); +CREATE INDEX IF NOT EXISTS idx_assistant_overlays_sort_order + ON assistant_overlays(sort_order); CREATE TABLE IF NOT EXISTS assistant_preferences ( - assistant_id TEXT PRIMARY KEY, + definition_id TEXT PRIMARY KEY, last_model_id TEXT, last_permission_value TEXT, last_skill_ids TEXT NOT NULL DEFAULT '[]', @@ -92,5 +98,5 @@ CREATE TABLE IF NOT EXISTS assistant_preferences ( last_mcp_ids TEXT NOT NULL DEFAULT '[]', created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, - FOREIGN KEY (assistant_id) REFERENCES assistant_definitions(id) ON DELETE CASCADE + FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE ); diff --git a/crates/aionui-db/src/database.rs b/crates/aionui-db/src/database.rs index 5694a34e..72e1955c 100644 --- a/crates/aionui-db/src/database.rs +++ b/crates/aionui-db/src/database.rs @@ -7,7 +7,7 @@ use fs2::FileExt; use sqlx::migrate::Migrator; use sqlx::pool::PoolOptions; use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode}; -use sqlx::{Sqlite, SqlitePool}; +use sqlx::{Row, Sqlite, SqlitePool}; use tracing::{info, warn}; use crate::error::DbError; @@ -29,6 +29,7 @@ static DB_MIGRATOR: Migrator = sqlx::migrate!(); // Historical special-case for the MCP schema reconciliation fallback. // Keep this pinned to migration version 7 even as newer migrations land. const MCP_SCHEMA_RECONCILIATION_MIGRATION_VERSION: i64 = 7; +const ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION: i64 = 12; /// Wraps a SQLite connection pool with lifecycle management. #[derive(Clone, Debug)] @@ -370,6 +371,21 @@ async fn run_migrations_with_retry(conn: &mut sqlx::SqliteConnection) -> Result< ))) } } + Err(sqlx::migrate::MigrateError::VersionMismatch(version)) + if version == ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION => + { + if align_reconciled_assistant_migration_checksum(&mut *conn).await? { + warn!( + "Aligned checksum for reconciled assistant migration {}; retrying", + ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION + ); + DB_MIGRATOR.run(&mut *conn).await.map_err(DbError::Migration) + } else { + Err(DbError::Migration(sqlx::migrate::MigrateError::VersionMismatch( + version, + ))) + } + } Err(e) => Err(DbError::Migration(e)), } } @@ -424,6 +440,7 @@ impl Drop for MigrateLockGuard { /// safely adds any missing columns via `ALTER TABLE ADD COLUMN`. async fn ensure_schema_columns(pool: &SqlitePool) -> Result<(), DbError> { reconcile_mcp_server_schema(pool).await?; + reconcile_assistant_unification_schema(pool).await?; let expected: &[(&str, &str, &str)] = &[ ("cron_jobs", "skill_content", "TEXT"), @@ -461,6 +478,28 @@ async fn ensure_schema_columns(pool: &SqlitePool) -> Result<(), DbError> { Ok(()) } +async fn reconcile_assistant_unification_schema(pool: &SqlitePool) -> Result<(), DbError> { + let table_exists: bool = sqlx::query_scalar( + "SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='assistant_definitions'", + ) + .fetch_one(pool) + .await + .map_err(DbError::Query)?; + if !table_exists { + return Ok(()); + } + + let final_shape = assistant_unification_schema_is_final(pool).await?; + if final_shape { + return Ok(()); + } + + rebuild_legacy_assistant_unification_schema(pool).await?; + info!("Rebuilt assistant unification tables into final identity schema"); + + Ok(()) +} + async fn reconcile_mcp_server_schema(pool: &SqlitePool) -> Result<(), DbError> { let table_exists: bool = sqlx::query_scalar("SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='mcp_servers'") @@ -613,6 +652,591 @@ async fn align_reconciled_mcp_migration_checksum(conn: &mut sqlx::SqliteConnecti Ok(updated.rows_affected() > 0) } +async fn align_reconciled_assistant_migration_checksum(conn: &mut sqlx::SqliteConnection) -> Result { + if !assistant_unification_schema_is_final_conn(conn).await? { + return Ok(false); + } + + let Some(migration) = DB_MIGRATOR + .iter() + .find(|migration| migration.version == ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION) + else { + return Ok(false); + }; + + let updated = sqlx::query("UPDATE _sqlx_migrations SET checksum = ? WHERE version = ?") + .bind(&*migration.checksum) + .bind(ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION) + .execute(&mut *conn) + .await + .map_err(DbError::Query)?; + + Ok(updated.rows_affected() > 0) +} + +async fn assistant_unification_schema_is_final(pool: &SqlitePool) -> Result { + let has_definition_id = table_has_column(pool, "assistant_definitions", "definition_id").await?; + let has_assistant_key = table_has_column(pool, "assistant_definitions", "assistant_key").await?; + let has_avatar_type = table_has_column(pool, "assistant_definitions", "avatar_type").await?; + let has_avatar_value = table_has_column(pool, "assistant_definitions", "avatar_value").await?; + let state_uses_definition_id = table_has_column(pool, "assistant_overlays", "definition_id").await?; + let preference_uses_definition_id = table_has_column(pool, "assistant_preferences", "definition_id").await?; + let scalar_default_modes_support_unset = assistant_definition_scalar_default_modes_support_unset(pool).await?; + + Ok(has_definition_id + && has_assistant_key + && has_avatar_type + && has_avatar_value + && state_uses_definition_id + && preference_uses_definition_id + && scalar_default_modes_support_unset) +} + +async fn table_exists(pool: &SqlitePool, table: &str) -> Result { + sqlx::query_scalar("SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = ?") + .bind(table) + .fetch_one(pool) + .await + .map_err(DbError::Query) +} + +async fn table_has_column(pool: &SqlitePool, table: &str, column: &str) -> Result { + sqlx::query_scalar("SELECT COUNT(*) > 0 FROM pragma_table_info(?) WHERE name = ?") + .bind(table) + .bind(column) + .fetch_one(pool) + .await + .map_err(DbError::Query) +} + +async fn assistant_unification_schema_is_final_conn(conn: &mut sqlx::SqliteConnection) -> Result { + let has_definition_id = table_has_column_conn(conn, "assistant_definitions", "definition_id").await?; + let has_assistant_key = table_has_column_conn(conn, "assistant_definitions", "assistant_key").await?; + let has_avatar_type = table_has_column_conn(conn, "assistant_definitions", "avatar_type").await?; + let has_avatar_value = table_has_column_conn(conn, "assistant_definitions", "avatar_value").await?; + let state_uses_definition_id = table_has_column_conn(conn, "assistant_overlays", "definition_id").await?; + let preference_uses_definition_id = table_has_column_conn(conn, "assistant_preferences", "definition_id").await?; + let scalar_default_modes_support_unset = assistant_definition_scalar_default_modes_support_unset_conn(conn).await?; + + Ok(has_definition_id + && has_assistant_key + && has_avatar_type + && has_avatar_value + && state_uses_definition_id + && preference_uses_definition_id + && scalar_default_modes_support_unset) +} + +async fn table_has_column_conn(conn: &mut sqlx::SqliteConnection, table: &str, column: &str) -> Result { + sqlx::query_scalar("SELECT COUNT(*) > 0 FROM pragma_table_info(?) WHERE name = ?") + .bind(table) + .bind(column) + .fetch_one(&mut *conn) + .await + .map_err(DbError::Query) +} + +async fn assistant_definition_scalar_default_modes_support_unset(pool: &SqlitePool) -> Result { + let table_sql: Option = + sqlx::query_scalar("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'assistant_definitions'") + .fetch_one(pool) + .await + .map_err(DbError::Query)?; + Ok(table_sql + .as_deref() + .map(assistant_definition_sql_supports_unset_defaults) + .unwrap_or(false)) +} + +async fn assistant_definition_scalar_default_modes_support_unset_conn( + conn: &mut sqlx::SqliteConnection, +) -> Result { + let table_sql: Option = + sqlx::query_scalar("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'assistant_definitions'") + .fetch_one(&mut *conn) + .await + .map_err(DbError::Query)?; + Ok(table_sql + .as_deref() + .map(assistant_definition_sql_supports_unset_defaults) + .unwrap_or(false)) +} + +fn assistant_definition_sql_supports_unset_defaults(table_sql: &str) -> bool { + let normalized = table_sql.to_ascii_lowercase().replace(char::is_whitespace, ""); + normalized.contains("default_model_mode") + && normalized.contains("default_permission_mode") + && normalized.contains("default_mcps_mode") + && normalized.contains("('unset','auto','fixed')") +} + +async fn rebuild_legacy_assistant_unification_schema(pool: &SqlitePool) -> Result<(), DbError> { + let overlay_table = if table_exists(pool, "assistant_overlays").await? { + "assistant_overlays" + } else if table_exists(pool, "assistant_states").await? { + "assistant_states" + } else { + return Err(DbError::Init( + "assistant schema repair failed: neither assistant_overlays nor assistant_states exists".into(), + )); + }; + let definitions_use_internal_identity = table_has_column(pool, "assistant_definitions", "definition_id").await?; + let overlays_use_definition_id = table_has_column(pool, overlay_table, "definition_id").await?; + let preferences_use_definition_id = table_has_column(pool, "assistant_preferences", "definition_id").await?; + + let definition_rows = if definitions_use_internal_identity { + sqlx::query( + "SELECT definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar_type, avatar_value, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, + default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at + FROM assistant_definitions", + ) + .fetch_all(pool) + .await + .map_err(DbError::Query)? + } else { + sqlx::query( + "SELECT id, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, + default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at + FROM assistant_definitions", + ) + .fetch_all(pool) + .await + .map_err(DbError::Query)? + }; + + let state_rows = sqlx::query(&format!( + "SELECT {} AS overlay_key, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at + FROM {overlay_table}", + if overlays_use_definition_id { + "definition_id" + } else { + "assistant_id" + } + )) + .fetch_all(pool) + .await + .map_err(DbError::Query)?; + + let preference_rows = sqlx::query(&format!( + "SELECT {} AS preference_key, last_model_id, last_permission_value, last_skill_ids, + last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at + FROM assistant_preferences", + if preferences_use_definition_id { + "definition_id" + } else { + "assistant_id" + } + )) + .fetch_all(pool) + .await + .map_err(DbError::Query)?; + + let mut definition_id_map = std::collections::HashMap::new(); + let mut definitions = Vec::with_capacity(definition_rows.len()); + for row in definition_rows { + if definitions_use_internal_identity { + let definition_id: String = row.get("definition_id"); + let assistant_key: String = row.get("assistant_key"); + definition_id_map.insert(assistant_key.clone(), definition_id.clone()); + definitions.push(( + definition_id, + assistant_key, + row.get::("source"), + row.get::("owner_type"), + row.get::, _>("source_ref"), + row.get::, _>("source_version"), + row.get::, _>("source_hash"), + row.get::("name"), + row.get::("name_i18n"), + row.get::, _>("description"), + row.get::("description_i18n"), + row.get::("avatar_type"), + row.get::, _>("avatar_value"), + row.get::("agent_backend"), + row.get::("rule_resource_type"), + row.get::, _>("rule_resource_ref"), + row.get::, _>("rule_inline_content"), + row.get::("recommended_prompts"), + row.get::("recommended_prompts_i18n"), + row.get::("default_model_mode"), + row.get::, _>("default_model_value"), + row.get::("default_permission_mode"), + row.get::, _>("default_permission_value"), + row.get::("default_skills_mode"), + row.get::("default_skill_ids"), + row.get::("custom_skill_names"), + row.get::("default_disabled_builtin_skill_ids"), + row.get::("default_mcps_mode"), + row.get::("default_mcp_ids"), + row.get::("created_at"), + row.get::("updated_at"), + row.get::, _>("deleted_at"), + )); + } else { + let assistant_key: String = row.get("id"); + let source: String = row.get("source"); + let avatar: Option = row.get("avatar"); + let definition_id = aionui_common::generate_prefixed_id("asstdef"); + let (avatar_type, avatar_value) = infer_avatar_storage(&source, avatar.as_deref()); + definition_id_map.insert(assistant_key.clone(), definition_id.clone()); + definitions.push(( + definition_id, + assistant_key, + source, + row.get::("owner_type"), + row.get::, _>("source_ref"), + row.get::, _>("source_version"), + row.get::, _>("source_hash"), + row.get::("name"), + row.get::("name_i18n"), + row.get::, _>("description"), + row.get::("description_i18n"), + avatar_type, + avatar_value, + row.get::("agent_backend"), + row.get::("rule_resource_type"), + row.get::, _>("rule_resource_ref"), + row.get::, _>("rule_inline_content"), + row.get::("recommended_prompts"), + row.get::("recommended_prompts_i18n"), + row.get::("default_model_mode"), + row.get::, _>("default_model_value"), + row.get::("default_permission_mode"), + row.get::, _>("default_permission_value"), + row.get::("default_skills_mode"), + row.get::("default_skill_ids"), + row.get::("custom_skill_names"), + row.get::("default_disabled_builtin_skill_ids"), + row.get::("default_mcps_mode"), + row.get::("default_mcp_ids"), + row.get::("created_at"), + row.get::("updated_at"), + row.get::, _>("deleted_at"), + )); + } + } + + let mut tx = pool.begin().await.map_err(DbError::Query)?; + sqlx::query("PRAGMA foreign_keys = OFF") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + + for table in [ + "_assistant_definitions_legacy_v12", + "_assistant_overlays_legacy_v12", + "_assistant_preferences_legacy_v12", + ] { + sqlx::query(&format!("DROP TABLE IF EXISTS {table}")) + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + } + + sqlx::query("ALTER TABLE assistant_definitions RENAME TO _assistant_definitions_legacy_v12") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + sqlx::query(&format!( + "ALTER TABLE {overlay_table} RENAME TO _assistant_overlays_legacy_v12" + )) + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + sqlx::query("ALTER TABLE assistant_preferences RENAME TO _assistant_preferences_legacy_v12") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + + for index in [ + "idx_assistant_definitions_source_ref", + "idx_assistant_definitions_assistant_key", + "idx_assistant_definitions_source", + "idx_assistant_definitions_agent_backend", + "idx_assistant_states_enabled", + "idx_assistant_states_sort_order", + "idx_assistant_overlays_enabled", + "idx_assistant_overlays_sort_order", + ] { + sqlx::query(&format!("DROP INDEX IF EXISTS {index}")) + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + } + + create_final_assistant_unification_tables(&mut tx).await?; + + for row in &definitions { + sqlx::query( + "INSERT INTO assistant_definitions ( + definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar_type, avatar_value, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + ) + .bind(&row.0) + .bind(&row.1) + .bind(&row.2) + .bind(&row.3) + .bind(&row.4) + .bind(&row.5) + .bind(&row.6) + .bind(&row.7) + .bind(&row.8) + .bind(&row.9) + .bind(&row.10) + .bind(&row.11) + .bind(&row.12) + .bind(&row.13) + .bind(&row.14) + .bind(&row.15) + .bind(&row.16) + .bind(&row.17) + .bind(&row.18) + .bind(&row.19) + .bind(&row.20) + .bind(&row.21) + .bind(&row.22) + .bind(&row.23) + .bind(&row.24) + .bind(&row.25) + .bind(&row.26) + .bind(&row.27) + .bind(&row.28) + .bind(&row.29) + .bind(&row.30) + .bind(&row.31) + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + } + + for row in state_rows { + let overlay_key: String = row.get("overlay_key"); + let definition_id = if overlays_use_definition_id { + overlay_key + } else { + let Some(definition_id) = definition_id_map.get(&overlay_key) else { + continue; + }; + definition_id.clone() + }; + sqlx::query( + "INSERT INTO assistant_overlays ( + definition_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?)", + ) + .bind(definition_id) + .bind(row.get::("enabled")) + .bind(row.get::("sort_order")) + .bind(row.get::, _>("agent_backend_override")) + .bind(row.get::, _>("last_used_at")) + .bind(row.get::("created_at")) + .bind(row.get::("updated_at")) + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + } + + for row in preference_rows { + let preference_key: String = row.get("preference_key"); + let definition_id = if preferences_use_definition_id { + preference_key + } else { + let Some(definition_id) = definition_id_map.get(&preference_key) else { + continue; + }; + definition_id.clone() + }; + sqlx::query( + "INSERT INTO assistant_preferences ( + definition_id, last_model_id, last_permission_value, last_skill_ids, + last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + ) + .bind(definition_id) + .bind(row.get::, _>("last_model_id")) + .bind(row.get::, _>("last_permission_value")) + .bind(row.get::("last_skill_ids")) + .bind(row.get::("last_disabled_builtin_skill_ids")) + .bind(row.get::("last_mcp_ids")) + .bind(row.get::("created_at")) + .bind(row.get::("updated_at")) + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + } + + sqlx::query("DROP TABLE _assistant_definitions_legacy_v12") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + sqlx::query("DROP TABLE _assistant_overlays_legacy_v12") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + sqlx::query("DROP TABLE _assistant_preferences_legacy_v12") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + + sqlx::query("PRAGMA foreign_keys = ON") + .execute(&mut *tx) + .await + .map_err(DbError::Query)?; + tx.commit().await.map_err(DbError::Query)?; + Ok(()) +} + +async fn create_final_assistant_unification_tables(tx: &mut sqlx::Transaction<'_, Sqlite>) -> Result<(), DbError> { + sqlx::query( + "CREATE TABLE assistant_definitions ( + definition_id TEXT PRIMARY KEY, + assistant_key TEXT NOT NULL, + source TEXT NOT NULL + CHECK (source IN ('builtin', 'user', 'generated', 'extension')), + owner_type TEXT NOT NULL + CHECK (owner_type IN ('system', 'user', 'extension')), + source_ref TEXT, + source_version TEXT, + source_hash TEXT, + name TEXT NOT NULL, + name_i18n TEXT NOT NULL DEFAULT '{}', + description TEXT, + description_i18n TEXT NOT NULL DEFAULT '{}', + avatar_type TEXT NOT NULL DEFAULT 'none' + CHECK (avatar_type IN ('none', 'emoji', 'builtin_asset', 'user_asset')), + avatar_value TEXT, + agent_backend TEXT NOT NULL, + rule_resource_type TEXT NOT NULL + CHECK (rule_resource_type IN ('none', 'builtin_asset', 'user_file', 'inline', 'extension')), + rule_resource_ref TEXT, + rule_inline_content TEXT, + recommended_prompts TEXT NOT NULL DEFAULT '[]', + recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', + default_model_mode TEXT NOT NULL CHECK (default_model_mode IN ('unset', 'auto', 'fixed')), + default_model_value TEXT, + default_permission_mode TEXT NOT NULL CHECK (default_permission_mode IN ('unset', 'auto', 'fixed')), + default_permission_value TEXT, + default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), + default_skill_ids TEXT NOT NULL DEFAULT '[]', + custom_skill_names TEXT NOT NULL DEFAULT '[]', + default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + default_mcps_mode TEXT NOT NULL CHECK (default_mcps_mode IN ('unset', 'auto', 'fixed')), + default_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + deleted_at INTEGER + )", + ) + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + sqlx::query( + "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref + ON assistant_definitions(source, source_ref) + WHERE source_ref IS NOT NULL", + ) + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + sqlx::query( + "CREATE UNIQUE INDEX idx_assistant_definitions_assistant_key + ON assistant_definitions(assistant_key)", + ) + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + + sqlx::query( + "CREATE TABLE assistant_overlays ( + definition_id TEXT PRIMARY KEY, + enabled INTEGER NOT NULL DEFAULT 1, + sort_order INTEGER NOT NULL DEFAULT 0, + agent_backend_override TEXT, + last_used_at INTEGER, + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE + )", + ) + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + sqlx::query("CREATE INDEX idx_assistant_overlays_enabled ON assistant_overlays(enabled)") + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + sqlx::query("CREATE INDEX idx_assistant_overlays_sort_order ON assistant_overlays(sort_order)") + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + + sqlx::query( + "CREATE TABLE assistant_preferences ( + definition_id TEXT PRIMARY KEY, + last_model_id TEXT, + last_permission_value TEXT, + last_skill_ids TEXT NOT NULL DEFAULT '[]', + last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + last_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE + )", + ) + .execute(&mut **tx) + .await + .map_err(DbError::Query)?; + + Ok(()) +} + +fn infer_avatar_storage(source: &str, avatar: Option<&str>) -> (String, Option) { + let Some(value) = avatar.map(str::trim).filter(|value| !value.is_empty()) else { + return ("none".to_string(), None); + }; + + let avatar_type = if looks_like_avatar_asset(value) { + match source { + "builtin" => "builtin_asset", + _ => "user_asset", + } + } else { + "emoji" + }; + + (avatar_type.to_string(), Some(value.to_string())) +} + +fn looks_like_avatar_asset(value: &str) -> bool { + value.contains('/') || (Path::new(value).extension().is_some() && !value.starts_with('.')) +} + /// Ensure the system default user exists. /// /// Uses INSERT OR IGNORE so it is safe to call on every startup. diff --git a/crates/aionui-db/src/lib.rs b/crates/aionui-db/src/lib.rs index 288dfdbe..12ca8c06 100644 --- a/crates/aionui-db/src/lib.rs +++ b/crates/aionui-db/src/lib.rs @@ -11,10 +11,10 @@ pub use database::{ }; pub use error::DbError; pub use models::{ - AgentMetadataRow, AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, - AssistantStateRow, ConversationArtifactRow, CreateAssistantParams, UpdateAgentHandshakeParams, - UpdateAssistantParams, UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, - UpsertAssistantStateParams, UpsertOverrideParams, + AgentMetadataRow, AssistantDefinitionRow, AssistantOverlayRow, AssistantOverrideRow, AssistantPreferenceRow, + AssistantRow, ConversationArtifactRow, CreateAssistantParams, UpdateAgentHandshakeParams, UpdateAssistantParams, + UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, + UpsertAssistantPreferenceParams, UpsertOverrideParams, }; pub use repository::channel::UpdatePluginStatusParams; pub use repository::conversation::{ @@ -28,12 +28,12 @@ pub use repository::remote_agent::{CreateRemoteAgentParams, UpdateRemoteAgentPar pub use repository::team::{UpdateTaskParams, UpdateTeamParams}; pub use repository::{ CreateAcpSessionParams, IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, - IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IAssistantStateRepository, + IAssistantOverlayRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IChannelRepository, IClientPreferenceRepository, IConversationRepository, ICronRepository, IMcpServerRepository, IOAuthTokenRepository, IProviderRepository, IRemoteAgentRepository, ISettingsRepository, ITeamRepository, IUserRepository, PersistedSessionState, SaveRuntimeStateParams, SqliteAcpSessionRepository, - SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, - SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteAssistantStateRepository, + SqliteAgentMetadataRepository, SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, + SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteChannelRepository, SqliteClientPreferenceRepository, SqliteConversationRepository, SqliteCronRepository, SqliteMcpServerRepository, SqliteOAuthTokenRepository, SqliteProviderRepository, SqliteRemoteAgentRepository, SqliteSettingsRepository, SqliteTeamRepository, SqliteUserRepository, rebuild_legacy_assistant_mirror, diff --git a/crates/aionui-db/src/models/assistant.rs b/crates/aionui-db/src/models/assistant.rs index dc51d31e..eeb92cf3 100644 --- a/crates/aionui-db/src/models/assistant.rs +++ b/crates/aionui-db/src/models/assistant.rs @@ -45,7 +45,8 @@ pub struct AssistantOverrideRow { /// Row mapping for the `assistant_definitions` table. #[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] pub struct AssistantDefinitionRow { - pub id: String, + pub definition_id: String, + pub assistant_key: String, pub source: String, pub owner_type: String, pub source_ref: Option, @@ -55,7 +56,8 @@ pub struct AssistantDefinitionRow { pub name_i18n: String, pub description: Option, pub description_i18n: String, - pub avatar: Option, + pub avatar_type: String, + pub avatar_value: Option, pub agent_backend: String, pub rule_resource_type: String, pub rule_resource_ref: Option, @@ -77,10 +79,10 @@ pub struct AssistantDefinitionRow { pub deleted_at: Option, } -/// Row mapping for the `assistant_states` table. +/// Row mapping for the `assistant_overlays` table. #[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] -pub struct AssistantStateRow { - pub assistant_id: String, +pub struct AssistantOverlayRow { + pub definition_id: String, pub enabled: bool, pub sort_order: i32, pub agent_backend_override: Option, @@ -92,7 +94,7 @@ pub struct AssistantStateRow { /// Row mapping for the `assistant_preferences` table. #[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] pub struct AssistantPreferenceRow { - pub assistant_id: String, + pub definition_id: String, pub last_model_id: Option, pub last_permission_value: Option, pub last_skill_ids: String, @@ -159,7 +161,8 @@ pub struct UpsertOverrideParams<'a> { /// Insert-or-update parameters for `assistant_definitions`. #[derive(Debug, Clone)] pub struct UpsertAssistantDefinitionParams<'a> { - pub id: &'a str, + pub definition_id: &'a str, + pub assistant_key: &'a str, pub source: &'a str, pub owner_type: &'a str, pub source_ref: Option<&'a str>, @@ -169,7 +172,8 @@ pub struct UpsertAssistantDefinitionParams<'a> { pub name_i18n: &'a str, pub description: Option<&'a str>, pub description_i18n: &'a str, - pub avatar: Option<&'a str>, + pub avatar_type: &'a str, + pub avatar_value: Option<&'a str>, pub agent_backend: &'a str, pub rule_resource_type: &'a str, pub rule_resource_ref: Option<&'a str>, @@ -188,10 +192,10 @@ pub struct UpsertAssistantDefinitionParams<'a> { pub default_mcp_ids: &'a str, } -/// Insert-or-update parameters for `assistant_states`. +/// Insert-or-update parameters for `assistant_overlays`. #[derive(Debug, Clone)] -pub struct UpsertAssistantStateParams<'a> { - pub assistant_id: &'a str, +pub struct UpsertAssistantOverlayParams<'a> { + pub definition_id: &'a str, pub enabled: bool, pub sort_order: i32, pub agent_backend_override: Option<&'a str>, @@ -201,7 +205,7 @@ pub struct UpsertAssistantStateParams<'a> { /// Insert-or-update parameters for `assistant_preferences`. #[derive(Debug, Clone)] pub struct UpsertAssistantPreferenceParams<'a> { - pub assistant_id: &'a str, + pub definition_id: &'a str, pub last_model_id: Option<&'a str>, pub last_permission_value: Option<&'a str>, pub last_skill_ids: &'a str, diff --git a/crates/aionui-db/src/models/mod.rs b/crates/aionui-db/src/models/mod.rs index 5fb0001b..f7ccf5f5 100644 --- a/crates/aionui-db/src/models/mod.rs +++ b/crates/aionui-db/src/models/mod.rs @@ -18,9 +18,9 @@ mod user; pub use acp_session::AcpSessionRow; pub use agent_metadata::{AgentMetadataRow, UpdateAgentHandshakeParams, UpsertAgentMetadataParams}; pub use assistant::{ - AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, - CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, - UpsertAssistantStateParams, UpsertOverrideParams, + AssistantDefinitionRow, AssistantOverlayRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, + UpsertAssistantPreferenceParams, UpsertOverrideParams, }; pub use channel::{AssistantSessionRow, AssistantUserRow, ChannelPluginRow, PairingCodeRow}; pub use client_preference::ClientPreference; diff --git a/crates/aionui-db/src/repository/assistant.rs b/crates/aionui-db/src/repository/assistant.rs index 394445f0..a46aaa5c 100644 --- a/crates/aionui-db/src/repository/assistant.rs +++ b/crates/aionui-db/src/repository/assistant.rs @@ -2,9 +2,9 @@ use crate::error::DbError; use crate::models::{ - AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, - CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, - UpsertAssistantStateParams, UpsertOverrideParams, + AssistantDefinitionRow, AssistantOverlayRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, + UpsertAssistantPreferenceParams, UpsertOverrideParams, }; /// CRUD access for user-authored assistant rows. @@ -60,24 +60,30 @@ pub trait IAssistantOverrideRepository: Send + Sync { #[async_trait::async_trait] pub trait IAssistantDefinitionRepository: Send + Sync { async fn list(&self) -> Result, DbError>; - async fn get(&self, id: &str) -> Result, DbError>; + async fn get_by_key(&self, assistant_key: &str) -> Result, DbError>; + async fn get_by_definition_id(&self, definition_id: &str) -> Result, DbError>; + async fn get_by_source_ref( + &self, + source: &str, + source_ref: &str, + ) -> Result, DbError>; async fn upsert(&self, params: &UpsertAssistantDefinitionParams<'_>) -> Result; - async fn soft_delete(&self, id: &str, deleted_at: i64) -> Result; + async fn soft_delete(&self, definition_id: &str, deleted_at: i64) -> Result; } -/// Runtime assistant state used by the current app version. +/// Runtime per-user assistant overlay used by the current app version. #[async_trait::async_trait] -pub trait IAssistantStateRepository: Send + Sync { - async fn get(&self, assistant_id: &str) -> Result, DbError>; - async fn list(&self) -> Result, DbError>; - async fn upsert(&self, params: &UpsertAssistantStateParams<'_>) -> Result; - async fn delete(&self, assistant_id: &str) -> Result; +pub trait IAssistantOverlayRepository: Send + Sync { + async fn get(&self, definition_id: &str) -> Result, DbError>; + async fn list(&self) -> Result, DbError>; + async fn upsert(&self, params: &UpsertAssistantOverlayParams<'_>) -> Result; + async fn delete(&self, definition_id: &str) -> Result; } /// Assistant-scoped "auto remember last" preferences. #[async_trait::async_trait] pub trait IAssistantPreferenceRepository: Send + Sync { - async fn get(&self, assistant_id: &str) -> Result, DbError>; + async fn get(&self, definition_id: &str) -> Result, DbError>; async fn upsert(&self, params: &UpsertAssistantPreferenceParams<'_>) -> Result; - async fn delete(&self, assistant_id: &str) -> Result; + async fn delete(&self, definition_id: &str) -> Result; } diff --git a/crates/aionui-db/src/repository/mod.rs b/crates/aionui-db/src/repository/mod.rs index a703d155..bb5e5d83 100644 --- a/crates/aionui-db/src/repository/mod.rs +++ b/crates/aionui-db/src/repository/mod.rs @@ -30,8 +30,8 @@ mod user; pub use acp_session::{CreateAcpSessionParams, IAcpSessionRepository, PersistedSessionState, SaveRuntimeStateParams}; pub use agent_metadata::IAgentMetadataRepository; pub use assistant::{ - IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, - IAssistantStateRepository, + IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantOverrideRepository, + IAssistantPreferenceRepository, IAssistantRepository, }; pub use channel::IChannelRepository; pub use client_preference::IClientPreferenceRepository; @@ -45,8 +45,8 @@ pub use settings::ISettingsRepository; pub use sqlite_acp_session::SqliteAcpSessionRepository; pub use sqlite_agent_metadata::SqliteAgentMetadataRepository; pub use sqlite_assistant::{ - SqliteAssistantDefinitionRepository, SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, - SqliteAssistantRepository, SqliteAssistantStateRepository, rebuild_legacy_assistant_mirror, + SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, SqliteAssistantOverrideRepository, + SqliteAssistantPreferenceRepository, SqliteAssistantRepository, rebuild_legacy_assistant_mirror, }; pub use sqlite_channel::SqliteChannelRepository; pub use sqlite_client_preference::SqliteClientPreferenceRepository; diff --git a/crates/aionui-db/src/repository/sqlite_assistant.rs b/crates/aionui-db/src/repository/sqlite_assistant.rs index e9c14a07..17c9dcad 100644 --- a/crates/aionui-db/src/repository/sqlite_assistant.rs +++ b/crates/aionui-db/src/repository/sqlite_assistant.rs @@ -5,13 +5,13 @@ use sqlx::SqlitePool; use crate::error::DbError; use crate::models::{ - AssistantDefinitionRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, AssistantStateRow, - CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantPreferenceParams, - UpsertAssistantStateParams, UpsertOverrideParams, + AssistantDefinitionRow, AssistantOverlayRow, AssistantOverrideRow, AssistantPreferenceRow, AssistantRow, + CreateAssistantParams, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, + UpsertAssistantPreferenceParams, UpsertOverrideParams, }; use crate::repository::assistant::{ - IAssistantDefinitionRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, - IAssistantStateRepository, + IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantOverrideRepository, + IAssistantPreferenceRepository, IAssistantRepository, }; /// SQLite-backed implementation of [`IAssistantRepository`]. @@ -245,13 +245,13 @@ impl SqliteAssistantDefinitionRepository { } } -/// SQLite-backed implementation of [`IAssistantStateRepository`]. +/// SQLite-backed implementation of [`IAssistantOverlayRepository`]. #[derive(Clone, Debug)] -pub struct SqliteAssistantStateRepository { +pub struct SqliteAssistantOverlayRepository { pool: SqlitePool, } -impl SqliteAssistantStateRepository { +impl SqliteAssistantOverlayRepository { pub fn new(pool: SqlitePool) -> Self { Self { pool } } @@ -374,11 +374,36 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { Ok(rows) } - async fn get(&self, id: &str) -> Result, DbError> { + async fn get_by_key(&self, assistant_key: &str) -> Result, DbError> { let row = sqlx::query_as::<_, AssistantDefinitionRow>( - "SELECT * FROM assistant_definitions WHERE id = ? AND deleted_at IS NULL", + "SELECT * FROM assistant_definitions WHERE assistant_key = ? AND deleted_at IS NULL", ) - .bind(id) + .bind(assistant_key) + .fetch_optional(&self.pool) + .await?; + Ok(row) + } + + async fn get_by_definition_id(&self, definition_id: &str) -> Result, DbError> { + let row = sqlx::query_as::<_, AssistantDefinitionRow>( + "SELECT * FROM assistant_definitions WHERE definition_id = ? AND deleted_at IS NULL", + ) + .bind(definition_id) + .fetch_optional(&self.pool) + .await?; + Ok(row) + } + + async fn get_by_source_ref( + &self, + source: &str, + source_ref: &str, + ) -> Result, DbError> { + let row = sqlx::query_as::<_, AssistantDefinitionRow>( + "SELECT * FROM assistant_definitions WHERE source = ? AND source_ref = ? AND deleted_at IS NULL", + ) + .bind(source) + .bind(source_ref) .fetch_optional(&self.pool) .await?; Ok(row) @@ -389,8 +414,8 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { sqlx::query( "INSERT INTO assistant_definitions ( - id, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar, + definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar_type, avatar_value, agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, recommended_prompts, recommended_prompts_i18n, default_model_mode, default_model_value, @@ -398,8 +423,9 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL) - ON CONFLICT(id) DO UPDATE SET + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL) + ON CONFLICT(definition_id) DO UPDATE SET + assistant_key = excluded.assistant_key, source = excluded.source, owner_type = excluded.owner_type, source_ref = excluded.source_ref, @@ -409,7 +435,8 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { name_i18n = excluded.name_i18n, description = excluded.description, description_i18n = excluded.description_i18n, - avatar = excluded.avatar, + avatar_type = excluded.avatar_type, + avatar_value = excluded.avatar_value, agent_backend = excluded.agent_backend, rule_resource_type = excluded.rule_resource_type, rule_resource_ref = excluded.rule_resource_ref, @@ -429,7 +456,8 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { updated_at = excluded.updated_at, deleted_at = NULL", ) - .bind(params.id) + .bind(params.definition_id) + .bind(params.assistant_key) .bind(params.source) .bind(params.owner_type) .bind(params.source_ref) @@ -439,7 +467,8 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { .bind(params.name_i18n) .bind(params.description) .bind(params.description_i18n) - .bind(params.avatar) + .bind(params.avatar_type) + .bind(params.avatar_value) .bind(params.agent_backend) .bind(params.rule_resource_type) .bind(params.rule_resource_ref) @@ -461,18 +490,23 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { .execute(&self.pool) .await?; - self.get(params.id) - .await? - .ok_or_else(|| DbError::Init(format!("upsert did not produce definition row for id '{}'", params.id))) + self.get_by_definition_id(params.definition_id).await?.ok_or_else(|| { + DbError::Init(format!( + "upsert did not produce definition row for definition_id '{}'", + params.definition_id + )) + }) } - async fn soft_delete(&self, id: &str, deleted_at: i64) -> Result { + async fn soft_delete(&self, definition_id: &str, deleted_at: i64) -> Result { let result = sqlx::query( - "UPDATE assistant_definitions SET deleted_at = ?, updated_at = ? WHERE id = ? AND deleted_at IS NULL", + "UPDATE assistant_definitions + SET deleted_at = ?, updated_at = ? + WHERE definition_id = ? AND deleted_at IS NULL", ) .bind(deleted_at) .bind(now_ms()) - .bind(id) + .bind(definition_id) .execute(&self.pool) .await?; Ok(result.rows_affected() > 0) @@ -480,37 +514,38 @@ impl IAssistantDefinitionRepository for SqliteAssistantDefinitionRepository { } #[async_trait::async_trait] -impl IAssistantStateRepository for SqliteAssistantStateRepository { - async fn get(&self, assistant_id: &str) -> Result, DbError> { - let row = sqlx::query_as::<_, AssistantStateRow>("SELECT * FROM assistant_states WHERE assistant_id = ?") - .bind(assistant_id) +impl IAssistantOverlayRepository for SqliteAssistantOverlayRepository { + async fn get(&self, definition_id: &str) -> Result, DbError> { + let row = sqlx::query_as::<_, AssistantOverlayRow>("SELECT * FROM assistant_overlays WHERE definition_id = ?") + .bind(definition_id) .fetch_optional(&self.pool) .await?; Ok(row) } - async fn list(&self) -> Result, DbError> { - let rows = - sqlx::query_as::<_, AssistantStateRow>("SELECT * FROM assistant_states ORDER BY sort_order, updated_at") - .fetch_all(&self.pool) - .await?; + async fn list(&self) -> Result, DbError> { + let rows = sqlx::query_as::<_, AssistantOverlayRow>( + "SELECT * FROM assistant_overlays ORDER BY sort_order, updated_at", + ) + .fetch_all(&self.pool) + .await?; Ok(rows) } - async fn upsert(&self, params: &UpsertAssistantStateParams<'_>) -> Result { + async fn upsert(&self, params: &UpsertAssistantOverlayParams<'_>) -> Result { let now = now_ms(); sqlx::query( - "INSERT INTO assistant_states ( - assistant_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at + "INSERT INTO assistant_overlays ( + definition_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(assistant_id) DO UPDATE SET + ON CONFLICT(definition_id) DO UPDATE SET enabled = excluded.enabled, sort_order = excluded.sort_order, agent_backend_override = excluded.agent_backend_override, last_used_at = excluded.last_used_at, updated_at = excluded.updated_at", ) - .bind(params.assistant_id) + .bind(params.definition_id) .bind(params.enabled) .bind(params.sort_order) .bind(params.agent_backend_override) @@ -520,17 +555,17 @@ impl IAssistantStateRepository for SqliteAssistantStateRepository { .execute(&self.pool) .await?; - self.get(params.assistant_id).await?.ok_or_else(|| { + self.get(params.definition_id).await?.ok_or_else(|| { DbError::Init(format!( - "upsert did not produce state row for id '{}'", - params.assistant_id + "upsert did not produce state row for definition_id '{}'", + params.definition_id )) }) } - async fn delete(&self, assistant_id: &str) -> Result { - let result = sqlx::query("DELETE FROM assistant_states WHERE assistant_id = ?") - .bind(assistant_id) + async fn delete(&self, definition_id: &str) -> Result { + let result = sqlx::query("DELETE FROM assistant_overlays WHERE definition_id = ?") + .bind(definition_id) .execute(&self.pool) .await?; Ok(result.rows_affected() > 0) @@ -539,10 +574,10 @@ impl IAssistantStateRepository for SqliteAssistantStateRepository { #[async_trait::async_trait] impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { - async fn get(&self, assistant_id: &str) -> Result, DbError> { + async fn get(&self, definition_id: &str) -> Result, DbError> { let row = - sqlx::query_as::<_, AssistantPreferenceRow>("SELECT * FROM assistant_preferences WHERE assistant_id = ?") - .bind(assistant_id) + sqlx::query_as::<_, AssistantPreferenceRow>("SELECT * FROM assistant_preferences WHERE definition_id = ?") + .bind(definition_id) .fetch_optional(&self.pool) .await?; Ok(row) @@ -552,10 +587,10 @@ impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { let now = now_ms(); sqlx::query( "INSERT INTO assistant_preferences ( - assistant_id, last_model_id, last_permission_value, last_skill_ids, + definition_id, last_model_id, last_permission_value, last_skill_ids, last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(assistant_id) DO UPDATE SET + ON CONFLICT(definition_id) DO UPDATE SET last_model_id = excluded.last_model_id, last_permission_value = excluded.last_permission_value, last_skill_ids = excluded.last_skill_ids, @@ -563,7 +598,7 @@ impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { last_mcp_ids = excluded.last_mcp_ids, updated_at = excluded.updated_at", ) - .bind(params.assistant_id) + .bind(params.definition_id) .bind(params.last_model_id) .bind(params.last_permission_value) .bind(params.last_skill_ids) @@ -574,17 +609,17 @@ impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { .execute(&self.pool) .await?; - self.get(params.assistant_id).await?.ok_or_else(|| { + self.get(params.definition_id).await?.ok_or_else(|| { DbError::Init(format!( - "upsert did not produce preference row for id '{}'", - params.assistant_id + "upsert did not produce preference row for definition_id '{}'", + params.definition_id )) }) } - async fn delete(&self, assistant_id: &str) -> Result { - let result = sqlx::query("DELETE FROM assistant_preferences WHERE assistant_id = ?") - .bind(assistant_id) + async fn delete(&self, definition_id: &str) -> Result { + let result = sqlx::query("DELETE FROM assistant_preferences WHERE definition_id = ?") + .bind(definition_id) .execute(&self.pool) .await?; Ok(result.rows_affected() > 0) @@ -594,7 +629,7 @@ impl IAssistantPreferenceRepository for SqliteAssistantPreferenceRepository { pub async fn rebuild_legacy_assistant_mirror( pool: &SqlitePool, definition: &AssistantDefinitionRow, - state: Option<&AssistantStateRow>, + state: Option<&AssistantOverlayRow>, ) -> Result<(), DbError> { let prompts = normalize_json_array(Some(definition.recommended_prompts.as_str())); let default_skills = normalize_json_array(Some(definition.default_skill_ids.as_str())); @@ -608,44 +643,51 @@ pub async fn rebuild_legacy_assistant_mirror( _ => "[]".to_string(), }; - sqlx::query( - "INSERT INTO assistants ( - id, name, description, avatar, preset_agent_type, enabled_skills, - custom_skill_names, disabled_builtin_skills, prompts, models, - name_i18n, description_i18n, prompts_i18n, created_at, updated_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT(id) DO UPDATE SET - name = excluded.name, - description = excluded.description, - avatar = excluded.avatar, - preset_agent_type = excluded.preset_agent_type, - enabled_skills = excluded.enabled_skills, - custom_skill_names = excluded.custom_skill_names, - disabled_builtin_skills = excluded.disabled_builtin_skills, - prompts = excluded.prompts, - models = excluded.models, - name_i18n = excluded.name_i18n, - description_i18n = excluded.description_i18n, - prompts_i18n = excluded.prompts_i18n, - updated_at = excluded.updated_at", - ) - .bind(&definition.id) - .bind(&definition.name) - .bind(&definition.description) - .bind(&definition.avatar) - .bind(&definition.agent_backend) - .bind(&default_skills) - .bind(&custom_skill_names) - .bind(&disabled_builtin) - .bind(&prompts) - .bind(&models) - .bind(&definition.name_i18n) - .bind(&definition.description_i18n) - .bind(&definition.recommended_prompts_i18n) - .bind(definition.created_at) - .bind(definition.updated_at) - .execute(pool) - .await?; + if definition.source == "user" { + sqlx::query( + "INSERT INTO assistants ( + id, name, description, avatar, preset_agent_type, enabled_skills, + custom_skill_names, disabled_builtin_skills, prompts, models, + name_i18n, description_i18n, prompts_i18n, created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(id) DO UPDATE SET + name = excluded.name, + description = excluded.description, + avatar = excluded.avatar, + preset_agent_type = excluded.preset_agent_type, + enabled_skills = excluded.enabled_skills, + custom_skill_names = excluded.custom_skill_names, + disabled_builtin_skills = excluded.disabled_builtin_skills, + prompts = excluded.prompts, + models = excluded.models, + name_i18n = excluded.name_i18n, + description_i18n = excluded.description_i18n, + prompts_i18n = excluded.prompts_i18n, + updated_at = excluded.updated_at", + ) + .bind(&definition.assistant_key) + .bind(&definition.name) + .bind(&definition.description) + .bind(&definition.avatar_value) + .bind(&definition.agent_backend) + .bind(&default_skills) + .bind(&custom_skill_names) + .bind(&disabled_builtin) + .bind(&prompts) + .bind(&models) + .bind(&definition.name_i18n) + .bind(&definition.description_i18n) + .bind(&definition.recommended_prompts_i18n) + .bind(definition.created_at) + .bind(definition.updated_at) + .execute(pool) + .await?; + } else { + sqlx::query("DELETE FROM assistants WHERE id = ?") + .bind(&definition.assistant_key) + .execute(pool) + .await?; + } let enabled = state.map(|row| row.enabled).unwrap_or(true); let sort_order = state.map(|row| row.sort_order).unwrap_or_default(); @@ -662,7 +704,7 @@ pub async fn rebuild_legacy_assistant_mirror( last_used_at = excluded.last_used_at, updated_at = excluded.updated_at", ) - .bind(&definition.id) + .bind(&definition.assistant_key) .bind(enabled) .bind(sort_order) .bind(agent_backend_override) @@ -703,13 +745,13 @@ mod tests { async fn setup_v2() -> ( SqliteAssistantDefinitionRepository, - SqliteAssistantStateRepository, + SqliteAssistantOverlayRepository, SqliteAssistantPreferenceRepository, crate::Database, ) { let db = init_database_memory().await.unwrap(); let d = SqliteAssistantDefinitionRepository::new(db.pool().clone()); - let s = SqliteAssistantStateRepository::new(db.pool().clone()); + let s = SqliteAssistantOverlayRepository::new(db.pool().clone()); let p = SqliteAssistantPreferenceRepository::new(db.pool().clone()); (d, s, p, db) } @@ -734,7 +776,8 @@ mod tests { fn definition_params<'a>(id: &'a str, name: &'a str) -> UpsertAssistantDefinitionParams<'a> { UpsertAssistantDefinitionParams { - id, + definition_id: "asstdef_u1", + assistant_key: id, source: "user", owner_type: "user", source_ref: Some(id), @@ -744,7 +787,8 @@ mod tests { name_i18n: r#"{"zh-CN":"助手"}"#, description: Some("desc"), description_i18n: "{}", - avatar: Some("🤖"), + avatar_type: "emoji", + avatar_value: Some("🤖"), agent_backend: "gemini", rule_resource_type: "inline", rule_resource_ref: None, @@ -1028,21 +1072,24 @@ mod tests { async fn definition_upsert_then_get() { let (d, _s, _p, _db) = setup_v2().await; let row = d.upsert(&definition_params("u1", "User One")).await.unwrap(); - assert_eq!(row.id, "u1"); + assert_eq!(row.assistant_key, "u1"); + assert_eq!(row.definition_id, "asstdef_u1"); assert_eq!(row.source, "user"); assert_eq!(row.default_permission_mode, "fixed"); - let fetched = d.get("u1").await.unwrap().unwrap(); + let fetched = d.get_by_key("u1").await.unwrap().unwrap(); assert_eq!(fetched.name, "User One"); assert_eq!(fetched.rule_inline_content.as_deref(), Some("# rule")); + assert_eq!(fetched.avatar_type, "emoji"); + assert_eq!(fetched.avatar_value.as_deref(), Some("🤖")); } #[tokio::test] async fn state_upsert_then_list() { let (d, s, _p, _db) = setup_v2().await; - d.upsert(&definition_params("u1", "User One")).await.unwrap(); - s.upsert(&UpsertAssistantStateParams { - assistant_id: "u1", + let definition = d.upsert(&definition_params("u1", "User One")).await.unwrap(); + s.upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled: false, sort_order: 9, agent_backend_override: Some("claude"), @@ -1053,7 +1100,7 @@ mod tests { let list = s.list().await.unwrap(); assert_eq!(list.len(), 1); - assert_eq!(list[0].assistant_id, "u1"); + assert_eq!(list[0].definition_id, definition.definition_id); assert!(!list[0].enabled); assert_eq!(list[0].sort_order, 9); assert_eq!(list[0].agent_backend_override.as_deref(), Some("claude")); @@ -1062,10 +1109,10 @@ mod tests { #[tokio::test] async fn preference_upsert_then_get() { let (d, _s, p, _db) = setup_v2().await; - d.upsert(&definition_params("u1", "User One")).await.unwrap(); + let definition = d.upsert(&definition_params("u1", "User One")).await.unwrap(); let row = p .upsert(&UpsertAssistantPreferenceParams { - assistant_id: "u1", + definition_id: &definition.definition_id, last_model_id: Some("gpt-4.1"), last_permission_value: Some("workspace-write"), last_skill_ids: r#"["pdf"]"#, @@ -1076,7 +1123,7 @@ mod tests { .unwrap(); assert_eq!(row.last_model_id.as_deref(), Some("gpt-4.1")); - let fetched = p.get("u1").await.unwrap().unwrap(); + let fetched = p.get(&definition.definition_id).await.unwrap().unwrap(); assert_eq!(fetched.last_skill_ids, r#"["pdf"]"#); } @@ -1085,8 +1132,8 @@ mod tests { let (d, s, _p, db) = setup_v2().await; let definition = d.upsert(&definition_params("u1", "User One")).await.unwrap(); let state = s - .upsert(&UpsertAssistantStateParams { - assistant_id: "u1", + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, enabled: false, sort_order: 7, agent_backend_override: Some("claude"), @@ -1104,6 +1151,7 @@ mod tests { .await .unwrap(); assert_eq!(legacy_assistant.preset_agent_type, "gemini"); + assert_eq!(legacy_assistant.avatar.as_deref(), Some("🤖")); assert_eq!(legacy_assistant.enabled_skills.as_deref(), Some(r#"["pdf","cron"]"#)); let legacy_override = @@ -1115,4 +1163,74 @@ mod tests { assert_eq!(legacy_override.sort_order, 7); assert_eq!(legacy_override.last_used_at, Some(999)); } + + #[tokio::test] + async fn rebuild_legacy_mirror_skips_builtin_assistant_rows() { + let (d, s, _p, db) = setup_v2().await; + let definition = d + .upsert(&UpsertAssistantDefinitionParams { + definition_id: "asstdef_builtin_office", + assistant_key: "builtin-office", + source: "builtin", + owner_type: "system", + source_ref: Some("builtin-office"), + source_version: None, + source_hash: None, + name: "Office", + name_i18n: r#"{"zh-CN":"Office"}"#, + description: Some("builtin"), + description_i18n: "{}", + avatar_type: "builtin_asset", + avatar_value: Some("office.svg"), + agent_backend: "aionrs", + rule_resource_type: "builtin_asset", + rule_resource_ref: Some("builtin-office"), + rule_inline_content: None, + recommended_prompts: r#"["hello"]"#, + recommended_prompts_i18n: "{}", + default_model_mode: "auto", + default_model_value: None, + default_permission_mode: "auto", + default_permission_value: None, + default_skills_mode: "fixed", + default_skill_ids: "[]", + custom_skill_names: "[]", + default_disabled_builtin_skill_ids: "[]", + default_mcps_mode: "auto", + default_mcp_ids: "[]", + }) + .await + .unwrap(); + let state = s + .upsert(&UpsertAssistantOverlayParams { + definition_id: &definition.definition_id, + enabled: false, + sort_order: 3, + agent_backend_override: Some("claude"), + last_used_at: Some(42), + }) + .await + .unwrap(); + + rebuild_legacy_assistant_mirror(db.pool(), &definition, Some(&state)) + .await + .unwrap(); + + let legacy_assistant_count: i64 = + sqlx::query_scalar("SELECT COUNT(*) FROM assistants WHERE id = 'builtin-office'") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(legacy_assistant_count, 0); + + let legacy_override = sqlx::query_as::<_, AssistantOverrideRow>( + "SELECT * FROM assistant_overrides WHERE assistant_id = 'builtin-office'", + ) + .fetch_one(db.pool()) + .await + .unwrap(); + assert!(!legacy_override.enabled); + assert_eq!(legacy_override.sort_order, 3); + assert_eq!(legacy_override.preset_agent_type.as_deref(), Some("claude")); + } } diff --git a/crates/aionui-db/tests/assistant_data_unification_schema.rs b/crates/aionui-db/tests/assistant_data_unification_schema.rs index 6a9853fe..38ef307e 100644 --- a/crates/aionui-db/tests/assistant_data_unification_schema.rs +++ b/crates/aionui-db/tests/assistant_data_unification_schema.rs @@ -7,7 +7,7 @@ async fn migration_creates_assistant_unification_tables_and_keeps_legacy_tables( let table_names: Vec = sqlx::query_scalar( "SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ( 'assistant_definitions', - 'assistant_states', + 'assistant_overlays', 'assistant_preferences', 'assistants', 'assistant_overrides' @@ -21,9 +21,9 @@ async fn migration_creates_assistant_unification_tables_and_keeps_legacy_tables( table_names, vec![ "assistant_definitions".to_string(), + "assistant_overlays".to_string(), "assistant_overrides".to_string(), "assistant_preferences".to_string(), - "assistant_states".to_string(), "assistants".to_string(), ] ); @@ -43,8 +43,25 @@ async fn assistant_definition_table_has_expected_default_columns() { "assistant_definitions should exist before inspecting columns" ); + assert!(columns.iter().any(|name| name == "definition_id")); + assert!(columns.iter().any(|name| name == "assistant_key")); assert!(columns.iter().any(|name| name == "default_model_mode")); assert!(columns.iter().any(|name| name == "default_permission_mode")); assert!(columns.iter().any(|name| name == "default_skill_ids")); assert!(columns.iter().any(|name| name == "default_mcp_ids")); + assert!(columns.iter().any(|name| name == "avatar_type")); + assert!(columns.iter().any(|name| name == "avatar_value")); + + let overlay_columns: Vec = sqlx::query_scalar("SELECT name FROM pragma_table_info('assistant_overlays')") + .fetch_all(db.pool()) + .await + .unwrap_or_default(); + assert!(overlay_columns.iter().any(|name| name == "definition_id")); + + let preference_columns: Vec = + sqlx::query_scalar("SELECT name FROM pragma_table_info('assistant_preferences')") + .fetch_all(db.pool()) + .await + .unwrap_or_default(); + assert!(preference_columns.iter().any(|name| name == "definition_id")); } diff --git a/crates/aionui-db/tests/db_lifecycle.rs b/crates/aionui-db/tests/db_lifecycle.rs index a2198327..e8278dc8 100644 --- a/crates/aionui-db/tests/db_lifecycle.rs +++ b/crates/aionui-db/tests/db_lifecycle.rs @@ -1,5 +1,24 @@ +use std::time::Duration; + use aionui_db::{init_database, init_database_memory, maybe_copy_legacy_database}; use sqlx::Row; +use sqlx::pool::PoolOptions; +use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode}; + +async fn open_file_pool(path: &std::path::Path) -> sqlx::SqlitePool { + PoolOptions::::new() + .max_connections(1) + .connect_with( + SqliteConnectOptions::new() + .filename(path) + .create_if_missing(false) + .foreign_keys(true) + .busy_timeout(Duration::from_millis(5000)) + .journal_mode(SqliteJournalMode::Wal), + ) + .await + .unwrap() +} // -- T1.1 Initialization -- @@ -91,6 +110,389 @@ async fn idempotent_reinit_preserves_data() { db.close().await; } +#[tokio::test] +async fn idempotent_reinit_recovers_assistant_unification_checksum_mismatch() { + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("test.db"); + + let db = init_database(&path).await.unwrap(); + db.close().await; + + let pool = PoolOptions::::new() + .max_connections(1) + .connect_with( + SqliteConnectOptions::new() + .filename(&path) + .create_if_missing(false) + .foreign_keys(true) + .busy_timeout(Duration::from_millis(5000)) + .journal_mode(SqliteJournalMode::Wal), + ) + .await + .unwrap(); + sqlx::query("UPDATE _sqlx_migrations SET checksum = x'00' WHERE version = 12") + .execute(&pool) + .await + .unwrap(); + pool.close().await; + + let db = init_database(&path).await.unwrap(); + let checksum: Vec = sqlx::query_scalar("SELECT checksum FROM _sqlx_migrations WHERE version = 12") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_ne!(checksum, vec![0]); + db.close().await; +} + +#[tokio::test] +async fn idempotent_reinit_repairs_legacy_assistant_unification_tables() { + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("test.db"); + + let db = init_database(&path).await.unwrap(); + db.close().await; + + let pool = open_file_pool(&path).await; + sqlx::query("PRAGMA foreign_keys = OFF").execute(&pool).await.unwrap(); + sqlx::query("DROP TABLE assistant_preferences") + .execute(&pool) + .await + .unwrap(); + sqlx::query("DROP TABLE assistant_overlays") + .execute(&pool) + .await + .unwrap(); + sqlx::query("DROP TABLE assistant_definitions") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + r#" +CREATE TABLE assistant_definitions ( + id TEXT PRIMARY KEY, + source TEXT NOT NULL, + owner_type TEXT NOT NULL, + source_ref TEXT, + source_version TEXT, + source_hash TEXT, + name TEXT NOT NULL, + name_i18n TEXT NOT NULL DEFAULT '{}', + description TEXT, + description_i18n TEXT NOT NULL DEFAULT '{}', + avatar TEXT, + agent_backend TEXT NOT NULL, + rule_resource_type TEXT NOT NULL, + rule_resource_ref TEXT, + rule_inline_content TEXT, + recommended_prompts TEXT NOT NULL DEFAULT '[]', + recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', + default_model_mode TEXT NOT NULL, + default_model_value TEXT, + default_permission_mode TEXT NOT NULL, + default_permission_value TEXT, + default_skills_mode TEXT NOT NULL, + default_skill_ids TEXT NOT NULL DEFAULT '[]', + custom_skill_names TEXT NOT NULL DEFAULT '[]', + default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + default_mcps_mode TEXT NOT NULL, + default_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + deleted_at INTEGER +) + "#, + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref + ON assistant_definitions(source, source_ref) + WHERE source_ref IS NOT NULL", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE TABLE assistant_states ( + assistant_id TEXT PRIMARY KEY, + enabled INTEGER NOT NULL DEFAULT 1, + sort_order INTEGER NOT NULL DEFAULT 0, + agent_backend_override TEXT, + last_used_at INTEGER, + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE TABLE assistant_preferences ( + assistant_id TEXT PRIMARY KEY, + last_model_id TEXT, + last_permission_value TEXT, + last_skill_ids TEXT NOT NULL DEFAULT '[]', + last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + last_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_definitions ( + id, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, + default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at + ) VALUES ( + 'u1', 'user', 'user', 'u1', NULL, NULL, + 'Mine', '{}', 'desc', '{}', '🤖', + 'aionrs', 'user_file', 'u1', NULL, + '[\"hello\"]', '{}', + 'auto', NULL, + 'auto', NULL, + 'fixed', '[\"pdf\"]', '[]', '[]', + 'auto', '[]', 1, 2, NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_states (assistant_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at) + VALUES ('u1', 0, 7, 'codex', 1234, 1, 2)", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_preferences (assistant_id, last_model_id, last_permission_value, last_skill_ids, + last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at) + VALUES ('u1', 'gpt-4.1', 'workspace-write', '[\"pdf\"]', '[]', '[\"mcp-1\"]', 1, 2)", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("PRAGMA foreign_keys = ON").execute(&pool).await.unwrap(); + pool.close().await; + + let db = init_database(&path).await.unwrap(); + let row = sqlx::query( + "SELECT definition_id, assistant_key, avatar_type, avatar_value + FROM assistant_definitions WHERE assistant_key = 'u1'", + ) + .fetch_one(db.pool()) + .await + .unwrap(); + let definition_id = row.get::("definition_id"); + assert_eq!(row.get::("assistant_key"), "u1"); + assert_eq!(row.get::("avatar_type"), "emoji"); + assert_eq!(row.get::, _>("avatar_value"), Some("🤖".to_string())); + + let state_definition_id: String = sqlx::query_scalar("SELECT definition_id FROM assistant_overlays LIMIT 1") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(state_definition_id, definition_id); + + let pref_definition_id: String = sqlx::query_scalar("SELECT definition_id FROM assistant_preferences LIMIT 1") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(pref_definition_id, definition_id); + db.close().await; +} + +#[tokio::test] +async fn idempotent_reinit_repairs_stale_assistant_definition_default_mode_constraints() { + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("test.db"); + + let db = init_database(&path).await.unwrap(); + db.close().await; + + let pool = open_file_pool(&path).await; + sqlx::query("PRAGMA foreign_keys = OFF").execute(&pool).await.unwrap(); + sqlx::query("DROP TABLE assistant_preferences") + .execute(&pool) + .await + .unwrap(); + sqlx::query("DROP TABLE assistant_overlays") + .execute(&pool) + .await + .unwrap(); + sqlx::query("DROP TABLE assistant_definitions") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + r#" +CREATE TABLE assistant_definitions ( + definition_id TEXT PRIMARY KEY, + assistant_key TEXT NOT NULL, + source TEXT NOT NULL, + owner_type TEXT NOT NULL, + source_ref TEXT, + source_version TEXT, + source_hash TEXT, + name TEXT NOT NULL, + name_i18n TEXT NOT NULL DEFAULT '{}', + description TEXT, + description_i18n TEXT NOT NULL DEFAULT '{}', + avatar_type TEXT NOT NULL DEFAULT 'none', + avatar_value TEXT, + agent_backend TEXT NOT NULL, + rule_resource_type TEXT NOT NULL, + rule_resource_ref TEXT, + rule_inline_content TEXT, + recommended_prompts TEXT NOT NULL DEFAULT '[]', + recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', + default_model_mode TEXT NOT NULL CHECK (default_model_mode IN ('auto', 'fixed')), + default_model_value TEXT, + default_permission_mode TEXT NOT NULL CHECK (default_permission_mode IN ('auto', 'fixed')), + default_permission_value TEXT, + default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), + default_skill_ids TEXT NOT NULL DEFAULT '[]', + custom_skill_names TEXT NOT NULL DEFAULT '[]', + default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + default_mcps_mode TEXT NOT NULL CHECK (default_mcps_mode IN ('auto', 'fixed')), + default_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + deleted_at INTEGER +) + "#, + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref + ON assistant_definitions(source, source_ref) + WHERE source_ref IS NOT NULL", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE UNIQUE INDEX idx_assistant_definitions_assistant_key + ON assistant_definitions(assistant_key)", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE TABLE assistant_overlays ( + definition_id TEXT PRIMARY KEY, + enabled INTEGER NOT NULL DEFAULT 1, + sort_order INTEGER NOT NULL DEFAULT 0, + agent_backend_override TEXT, + last_used_at INTEGER, + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_overlays_enabled ON assistant_overlays(enabled)") + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_overlays_sort_order ON assistant_overlays(sort_order)") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE TABLE assistant_preferences ( + definition_id TEXT PRIMARY KEY, + last_model_id TEXT, + last_permission_value TEXT, + last_skill_ids TEXT NOT NULL DEFAULT '[]', + last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + last_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_definitions ( + definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar_type, avatar_value, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, + default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at + ) VALUES ( + 'def-1', 'assistant-1', 'builtin', 'system', 'assistant-1', NULL, NULL, + 'Builtin Assistant', '{}', 'desc', '{}', 'emoji', '🤖', + 'codex', 'builtin_asset', 'assistant-1', NULL, + '[]', '{}', + 'auto', NULL, + 'auto', NULL, + 'fixed', '[]', '[]', '[]', + 'auto', '[]', 1000, 1000, NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("PRAGMA foreign_keys = ON").execute(&pool).await.unwrap(); + pool.close().await; + + let db = init_database(&path).await.unwrap(); + let table_sql: String = + sqlx::query_scalar("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'assistant_definitions'") + .fetch_one(db.pool()) + .await + .unwrap(); + assert!(table_sql.contains("default_model_mode IN ('unset', 'auto', 'fixed')")); + assert!(table_sql.contains("default_permission_mode IN ('unset', 'auto', 'fixed')")); + assert!(table_sql.contains("default_mcps_mode IN ('unset', 'auto', 'fixed')")); + + sqlx::query( + "UPDATE assistant_definitions + SET default_model_mode = 'unset', + default_permission_mode = 'unset', + default_mcps_mode = 'unset' + WHERE definition_id = 'def-1'", + ) + .execute(db.pool()) + .await + .unwrap(); + db.close().await; +} + // -- T1.4 Migrations -- #[tokio::test] From 270ddc90d0706dc045f764d2efb6b95fc042885e Mon Sep 17 00:00:00 2001 From: zk <> Date: Wed, 10 Jun 2026 23:36:17 +0800 Subject: [PATCH 09/19] chore: apply auto-fixes (fmt + clippy) --- crates/aionui-db/src/database.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/aionui-db/src/database.rs b/crates/aionui-db/src/database.rs index 72e1955c..6bb6c10a 100644 --- a/crates/aionui-db/src/database.rs +++ b/crates/aionui-db/src/database.rs @@ -1019,9 +1019,9 @@ async fn rebuild_legacy_assistant_unification_schema(pool: &SqlitePool) -> Resul .bind(&row.26) .bind(&row.27) .bind(&row.28) - .bind(&row.29) - .bind(&row.30) - .bind(&row.31) + .bind(row.29) + .bind(row.30) + .bind(row.31) .execute(&mut *tx) .await .map_err(DbError::Query)?; From 9083f3d0867c21be16817cbc7838479a10f61ee6 Mon Sep 17 00:00:00 2001 From: zk <> Date: Thu, 11 Jun 2026 11:17:03 +0800 Subject: [PATCH 10/19] fix(assistant): finalize unified avatar and source handling --- crates/aionui-api-types/src/assistant.rs | 3 - crates/aionui-app/src/router/state.rs | 5 +- crates/aionui-app/tests/assistants_e2e.rs | 159 +++++++-- crates/aionui-assistant/src/service.rs | 325 ++++++++---------- .../012_assistant_data_unification.sql | 4 +- crates/aionui-db/src/database.rs | 21 +- .../assistant_data_unification_schema.rs | 53 +++ crates/aionui-db/tests/db_lifecycle.rs | 167 +++++++++ 8 files changed, 504 insertions(+), 233 deletions(-) diff --git a/crates/aionui-api-types/src/assistant.rs b/crates/aionui-api-types/src/assistant.rs index 3dce08db..e3fa9f19 100644 --- a/crates/aionui-api-types/src/assistant.rs +++ b/crates/aionui-api-types/src/assistant.rs @@ -17,7 +17,6 @@ use serde::{Deserialize, Serialize}; pub enum AssistantSource { Builtin, User, - Extension, } /// Wire shape returned by `GET /api/assistants` (single element) and @@ -304,8 +303,6 @@ mod tests { assert_eq!(json, "\"builtin\""); let json = serde_json::to_string(&AssistantSource::User).unwrap(); assert_eq!(json, "\"user\""); - let json = serde_json::to_string(&AssistantSource::Extension).unwrap(); - assert_eq!(json, "\"extension\""); } #[test] diff --git a/crates/aionui-app/src/router/state.rs b/crates/aionui-app/src/router/state.rs index 9ce0a459..75718897 100644 --- a/crates/aionui-app/src/router/state.rs +++ b/crates/aionui-app/src/router/state.rs @@ -189,7 +189,7 @@ pub async fn build_module_states( "startup: extension registry initialized" ); - let assistant = build_assistant_state(services, ext_state.registry.clone()); + let assistant = build_assistant_state(services); assistant.service.bootstrap_assistant_storage().await.map_err(|error| { RouterBuildError::new("router.assistant.bootstrap", "failed to bootstrap assistant storage").with_source(error) })?; @@ -285,7 +285,7 @@ pub async fn build_module_states( } /// Build the default `AssistantRouterState` from application services. -pub fn build_assistant_state(services: &AppServices, extension_registry: ExtensionRegistry) -> AssistantRouterState { +pub fn build_assistant_state(services: &AppServices) -> AssistantRouterState { let pool = services.database.pool().clone(); let definition_repo: Arc = Arc::new(SqliteAssistantDefinitionRepository::new(pool.clone())); @@ -315,7 +315,6 @@ pub fn build_assistant_state(services: &AppServices, extension_registry: Extensi override_repo, provider_repo, builtin, - extension_registry, services.data_dir.clone(), )); AssistantRouterState { service } diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index 779e819b..6c49ccf7 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -4,10 +4,9 @@ //! Each test exercises the router end-to-end via `tower::ServiceExt::oneshot` //! against a real `aionui_app::create_router_with_states` instance backed by //! an in-memory SQLite database. The assistant module state is re-built with -//! a temp-dir built-in manifest, a temp user-data dir, and (where needed) an -//! extension registry initialized from a fixture manifest that contributes an -//! assistant — giving coverage of the three-source dispatch (builtin / user / -//! extension) without touching `~/.aionui/`. +//! a temp-dir built-in manifest, a temp user-data dir, and a temp extension +//! registry for the unrelated extension router state without touching +//! `~/.aionui/`. mod common; @@ -60,9 +59,6 @@ struct Fixture { /// `builtin-bare` with nothing referenced) /// - a temp user-data dir that `AssistantService` uses for user rule/skill/ /// avatar storage -/// - an extension registry initialized from a fixture manifest that -/// contributes an assistant with id `ext-helper` -/// /// Also logs in `admin` and hands back the session + CSRF tokens so tests /// can issue authenticated mutating requests. async fn fixture() -> Fixture { @@ -235,7 +231,6 @@ async fn fixture() -> Fixture { override_repo, provider_repo, builtin, - registry, user_data_dir.clone(), )); service.bootstrap_assistant_storage().await.unwrap(); @@ -268,7 +263,7 @@ async fn fixture() -> Fixture { // =========================================================================== #[tokio::test] -async fn list_populated_returns_builtins_and_extension() { +async fn list_populated_excludes_extension_assistants() { let fx = fixture().await; let resp = fx @@ -281,15 +276,16 @@ async fn list_populated_returns_builtins_and_extension() { let json = body_json(resp).await; assert_eq!(json["success"], true); let list = json["data"].as_array().unwrap(); - // 2 builtins + 1 extension - assert_eq!(list.len(), 3, "body = {json}"); + // Extension-contributed assistants are no longer part of the unified + // assistant catalog. + assert_eq!(list.len(), 2, "body = {json}"); let ids: Vec<&str> = list.iter().map(|a| a["id"].as_str().unwrap()).collect(); assert!(ids.contains(&"builtin-office")); assert!(ids.contains(&"builtin-bare")); - assert!(ids.contains(&"ext-helper")); + assert!(!ids.contains(&"ext-helper")); let sources: Vec<&str> = list.iter().map(|a| a["source"].as_str().unwrap()).collect(); assert!(sources.contains(&"builtin")); - assert!(sources.contains(&"extension")); + assert!(!sources.contains(&"extension")); } #[tokio::test] @@ -473,7 +469,7 @@ async fn create_rejects_builtin_id_collision_with_400() { } #[tokio::test] -async fn create_rejects_extension_id_collision_with_400() { +async fn create_allows_id_that_matches_extension_registry_assistant() { let fx = fixture().await; let req = json_with_token( "POST", @@ -483,7 +479,106 @@ async fn create_rejects_extension_id_collision_with_400() { &fx.csrf, ); let resp = fx.app.clone().oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + assert_eq!(resp.status(), StatusCode::CREATED); +} + +#[tokio::test] +async fn create_user_avatar_from_local_file_is_served_via_assistant_avatar_route() { + let fx = fixture().await; + let source_avatar = fx.user_data_dir.join("picked-avatar.png"); + std::fs::write(&source_avatar, b"picked-avatar-bytes").unwrap(); + + let req = json_with_token( + "POST", + "/api/assistants", + json!({ + "id": "u-avatar", + "name": "Avatar User", + "avatar": source_avatar.to_string_lossy(), + "preset_agent_type": "aionrs", + }), + &fx.token, + &fx.csrf, + ); + let resp = fx.app.clone().oneshot(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + let body = body_json(resp).await; + assert_eq!(body["data"]["avatar"], "/api/assistants/u-avatar/avatar"); + + let persisted_avatar = fx.user_data_dir.join("assistant-avatars/u-avatar.png"); + assert!( + persisted_avatar.exists(), + "persisted avatar missing: {}", + persisted_avatar.display() + ); + assert_eq!(std::fs::read(&persisted_avatar).unwrap(), b"picked-avatar-bytes"); + + let resp = fx + .app + .clone() + .oneshot(get_with_token("/api/assistants/u-avatar/avatar", &fx.token)) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get("content-type").and_then(|v| v.to_str().ok()), + Some("image/png") + ); + let bytes = http_body_util::BodyExt::collect(resp.into_body()) + .await + .unwrap() + .to_bytes(); + assert_eq!(&bytes[..], b"picked-avatar-bytes"); +} + +#[tokio::test] +async fn update_user_avatar_with_existing_route_preserves_served_file() { + let fx = fixture().await; + let source_avatar = fx.user_data_dir.join("picked-avatar.png"); + std::fs::write(&source_avatar, b"picked-avatar-bytes").unwrap(); + + let create_req = json_with_token( + "POST", + "/api/assistants", + json!({ + "id": "u-avatar-stable", + "name": "Avatar User", + "avatar": source_avatar.to_string_lossy(), + "preset_agent_type": "aionrs", + }), + &fx.token, + &fx.csrf, + ); + let create_resp = fx.app.clone().oneshot(create_req).await.unwrap(); + assert_eq!(create_resp.status(), StatusCode::CREATED); + + let update_req = json_with_token( + "PUT", + "/api/assistants/u-avatar-stable", + json!({ + "avatar": "/api/assistants/u-avatar-stable/avatar" + }), + &fx.token, + &fx.csrf, + ); + let update_resp = fx.app.clone().oneshot(update_req).await.unwrap(); + assert_eq!(update_resp.status(), StatusCode::OK); + + let persisted_avatar = fx.user_data_dir.join("assistant-avatars/u-avatar-stable.png"); + assert!( + persisted_avatar.exists(), + "persisted avatar missing: {}", + persisted_avatar.display() + ); + assert_eq!(std::fs::read(&persisted_avatar).unwrap(), b"picked-avatar-bytes"); + + let avatar_resp = fx + .app + .clone() + .oneshot(get_with_token("/api/assistants/u-avatar-stable/avatar", &fx.token)) + .await + .unwrap(); + assert_eq!(avatar_resp.status(), StatusCode::OK); } #[tokio::test] @@ -561,7 +656,7 @@ async fn update_builtin_is_forbidden() { } #[tokio::test] -async fn update_extension_is_forbidden() { +async fn update_extension_registry_id_without_user_row_returns_404() { let fx = fixture().await; let req = json_with_token( "PUT", @@ -571,7 +666,7 @@ async fn update_extension_is_forbidden() { &fx.csrf, ); let resp = fx.app.clone().oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::FORBIDDEN); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); } // =========================================================================== @@ -637,7 +732,7 @@ async fn delete_builtin_is_forbidden() { } #[tokio::test] -async fn delete_extension_is_forbidden() { +async fn delete_extension_registry_id_without_user_row_returns_404() { let fx = fixture().await; let resp = fx .app @@ -645,7 +740,7 @@ async fn delete_extension_is_forbidden() { .oneshot(delete_with_token("/api/assistants/ext-helper", &fx.token, &fx.csrf)) .await .unwrap(); - assert_eq!(resp.status(), StatusCode::FORBIDDEN); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); } // =========================================================================== @@ -700,7 +795,7 @@ async fn set_state_updates_existing_override_for_user() { } #[tokio::test] -async fn set_state_extension_is_400() { +async fn set_state_extension_registry_id_without_user_row_returns_404() { let fx = fixture().await; let req = json_with_token( "PATCH", @@ -710,7 +805,7 @@ async fn set_state_extension_is_400() { &fx.csrf, ); let resp = fx.app.clone().oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + assert_eq!(resp.status(), StatusCode::NOT_FOUND); } #[tokio::test] @@ -766,7 +861,7 @@ async fn import_skips_builtin_collision() { } #[tokio::test] -async fn import_skips_extension_collision() { +async fn import_allows_id_that_matches_extension_registry_assistant() { let fx = fixture().await; let body = json!({ "assistants": [ @@ -777,8 +872,8 @@ async fn import_skips_extension_collision() { let resp = fx.app.clone().oneshot(req).await.unwrap(); assert_eq!(resp.status(), StatusCode::OK); let json = body_json(resp).await; - assert_eq!(json["data"]["imported"], 0); - assert_eq!(json["data"]["skipped"], 1); + assert_eq!(json["data"]["imported"], 1); + assert_eq!(json["data"]["skipped"], 0); } #[tokio::test] @@ -990,7 +1085,7 @@ async fn write_rule_builtin_returns_400() { } #[tokio::test] -async fn write_rule_extension_returns_400() { +async fn write_rule_extension_registry_id_behaves_like_user_id() { let fx = fixture().await; let req = json_with_token( "POST", @@ -1000,7 +1095,7 @@ async fn write_rule_extension_returns_400() { &fx.csrf, ); let resp = fx.app.clone().oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + assert_eq!(resp.status(), StatusCode::OK); } // =========================================================================== @@ -1042,7 +1137,7 @@ async fn delete_rule_builtin_returns_400() { } #[tokio::test] -async fn delete_rule_extension_returns_400() { +async fn delete_rule_extension_registry_id_behaves_like_user_id() { let fx = fixture().await; let resp = fx .app @@ -1054,7 +1149,7 @@ async fn delete_rule_extension_returns_400() { )) .await .unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + assert_eq!(resp.status(), StatusCode::OK); } // =========================================================================== @@ -1156,7 +1251,7 @@ async fn write_skill_builtin_returns_400() { } #[tokio::test] -async fn write_skill_extension_returns_400() { +async fn write_skill_extension_registry_id_behaves_like_user_id() { let fx = fixture().await; let req = json_with_token( "POST", @@ -1166,7 +1261,7 @@ async fn write_skill_extension_returns_400() { &fx.csrf, ); let resp = fx.app.clone().oneshot(req).await.unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + assert_eq!(resp.status(), StatusCode::OK); } // =========================================================================== @@ -1208,7 +1303,7 @@ async fn delete_skill_builtin_returns_400() { } #[tokio::test] -async fn delete_skill_extension_returns_400() { +async fn delete_skill_extension_registry_id_behaves_like_user_id() { let fx = fixture().await; let resp = fx .app @@ -1220,7 +1315,7 @@ async fn delete_skill_extension_returns_400() { )) .await .unwrap(); - assert_eq!(resp.status(), StatusCode::BAD_REQUEST); + assert_eq!(resp.status(), StatusCode::OK); } // =========================================================================== diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 112bef6f..87c1ada0 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -1,5 +1,5 @@ -//! Assistant service — three-source merge, CRUD, state overrides, import, -//! and source-dispatched rule/skill read/write helpers. +//! Assistant service — unified built-in + user assistant CRUD, state +//! overlays, import, and source-dispatched rule/skill read/write helpers. use std::collections::HashMap; use std::path::{Path, PathBuf}; @@ -20,9 +20,7 @@ use aionui_db::{ IProviderRepository, SqlitePool, UpdateAssistantParams, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, rebuild_legacy_assistant_mirror, }; -use aionui_extension::{ - AssistantClassifier, AssistantRuleDispatcher, ExtensionError, ExtensionRegistry, ResolvedAssistant, -}; +use aionui_extension::{AssistantClassifier, AssistantRuleDispatcher, ExtensionError}; use serde_json; use tracing::{debug, warn}; @@ -45,7 +43,6 @@ pub struct AssistantService { /// pick an agent that actually matches the configured provider list. provider_repo: Arc, builtin: Arc, - extension_registry: ExtensionRegistry, /// Root directory holding user-authored rule/skill md files and avatars. /// Defaults to `~/.aionui/` but can be overridden for tests. user_data_dir: PathBuf, @@ -76,7 +73,6 @@ impl AssistantService { override_repo: Arc, provider_repo: Arc, builtin: Arc, - extension_registry: ExtensionRegistry, user_data_dir: PathBuf, ) -> Self { Self { @@ -88,7 +84,6 @@ impl AssistantService { override_repo, provider_repo, builtin, - extension_registry, user_data_dir, } } @@ -396,9 +391,6 @@ impl AssistantService { if self.builtin.has(id) { return AssistantSource::Builtin; } - if self.extension_registry.has_assistant(id).await { - return AssistantSource::Extension; - } AssistantSource::User } @@ -406,9 +398,9 @@ impl AssistantService { // List / Get // ----------------------------------------------------------------------- - /// Three-source merge (built-in + user + extension) with per-assistant - /// override application. Also performs opportunistic orphan cleanup on - /// the overrides table. + /// Unified assistant list (built-in + user) with per-assistant overlay + /// application. Also performs opportunistic orphan cleanup on the + /// overrides table. pub async fn list(&self) -> Result, AssistantError> { let definitions = self .definition_repo @@ -420,7 +412,6 @@ impl AssistantService { .list() .await .map_err(|e| AssistantError::Internal(format!("list assistant overlays: {e}")))?; - let extensions = self.extension_registry.get_assistants().await; let state_map: HashMap = states .into_iter() .map(|state| (state.definition_id.clone(), state)) @@ -434,9 +425,6 @@ impl AssistantService { state_map.get(&definition.definition_id), )?); } - for e in &extensions { - result.push(extension_to_response(e)); - } // Sort by sort_order asc, then last_used_at desc (newer first). result.sort_by(|a, b| { @@ -461,10 +449,6 @@ impl AssistantService { return definition_to_response(&definition, state.as_ref()); } - if let Some(assistant) = self.extension_registry.get_assistant_by_id(id).await { - return Ok(extension_to_response(&assistant)); - } - Err(AssistantError::NotFound(format!("assistant '{id}' not found"))) } @@ -476,10 +460,6 @@ impl AssistantService { return definition_to_detail_response(&definition, state.as_ref(), preference.as_ref(), &rules_content); } - if let Some(assistant) = self.extension_registry.get_assistant_by_id(id).await { - return Ok(extension_to_detail_response(&assistant)); - } - Err(AssistantError::NotFound(format!("assistant '{id}' not found"))) } @@ -536,17 +516,12 @@ impl AssistantService { _ => generate_user_id(), }; - // Reject id collisions with built-in / extension-contributed. + // Reject id collisions with built-ins. if self.builtin.has(&id) { return Err(AssistantError::BadRequest( "Id conflicts with built-in assistant".into(), )); } - if self.extension_registry.has_assistant(&id).await { - return Err(AssistantError::BadRequest( - "Id conflicts with extension-contributed assistant".into(), - )); - } let serialized = SerializedFields::from_create(&req)?; let detail_overrides = SerializedDetailOverrides::from_create(&req)?; @@ -558,11 +533,12 @@ impl AssistantService { Some(s) if !s.is_empty() => s.to_string(), _ => self.resolve_default_agent_type().await?, }; + let avatar = self.normalize_user_avatar_input(&id, req.avatar.as_deref())?; let params = CreateAssistantParams { id: &id, name: &name, description: req.description.as_deref(), - avatar: req.avatar.as_deref(), + avatar: avatar.as_deref(), preset_agent_type: &resolved_agent_type, enabled_skills: serialized.enabled_skills.as_deref(), custom_skill_names: serialized.custom_skill_names.as_deref(), @@ -660,11 +636,6 @@ impl AssistantService { .map_err(|e| AssistantError::Internal(format!("rebuild legacy mirror: {e}")))?; return self.get(id).await; } - AssistantSource::Extension => { - return Err(AssistantError::Forbidden( - "Cannot modify extension-contributed assistant".into(), - )); - } AssistantSource::User => {} } @@ -679,10 +650,15 @@ impl AssistantService { .preset_agent_type .as_deref() .is_some_and(|preset_agent_type| preset_agent_type != current_definition.agent_backend); + let normalized_avatar = if req.avatar.is_some() { + Some(self.normalize_user_avatar_input(id, req.avatar.as_deref())?) + } else { + None + }; let params = UpdateAssistantParams { name: req.name.as_deref(), description: req.description.as_ref().map(|s| Some(s.as_str())), - avatar: req.avatar.as_ref().map(|s| Some(s.as_str())), + avatar: normalized_avatar.as_ref().map(|value| value.as_deref()), preset_agent_type: req.preset_agent_type.as_deref(), enabled_skills: serialized.enabled_skills.as_ref().map(|s| Some(s.as_str())), custom_skill_names: serialized.custom_skill_names.as_ref().map(|s| Some(s.as_str())), @@ -710,11 +686,6 @@ impl AssistantService { AssistantSource::Builtin => { return Err(AssistantError::Forbidden("Cannot delete built-in assistant".into())); } - AssistantSource::Extension => { - return Err(AssistantError::Forbidden( - "Cannot delete extension-contributed assistant".into(), - )); - } AssistantSource::User => {} } @@ -755,9 +726,6 @@ impl AssistantService { req: SetAssistantStateRequest, ) -> Result { match self.classify_source(id).await { - AssistantSource::Extension => { - return Err(AssistantError::BadRequest("Extension assistants are read-only".into())); - } AssistantSource::Builtin => {} AssistantSource::User => { // Confirm the user row exists (otherwise 404). @@ -817,7 +785,7 @@ impl AssistantService { // ----------------------------------------------------------------------- /// Bulk insert-only import of legacy Electron config rows. Skip on - /// built-in / extension id collision or already-imported user-id collision. + /// built-in id collision or already-imported user-id collision. /// Never overwrites an existing user row. pub async fn import(&self, req: ImportAssistantsRequest) -> Result { let mut result = ImportAssistantsResult::default(); @@ -838,10 +806,6 @@ impl AssistantService { result.skipped += 1; continue; } - if self.extension_registry.has_assistant(&id).await { - result.skipped += 1; - continue; - } match self.repo.get(&id).await { Ok(Some(_)) => { result.skipped += 1; @@ -903,11 +867,23 @@ impl AssistantService { }, }; + let avatar = match self.normalize_user_avatar_input(&id, entry.avatar.as_deref()) { + Ok(value) => value, + Err(e) => { + result.failed += 1; + result.errors.push(ImportError { + id, + error: e.to_string(), + }); + continue; + } + }; + let params = CreateAssistantParams { id: &id, name: &name, description: entry.description.as_deref(), - avatar: entry.avatar.as_deref(), + avatar: avatar.as_deref(), preset_agent_type: &resolved_agent_type, enabled_skills: serialized.enabled_skills.as_deref(), custom_skill_names: serialized.custom_skill_names.as_deref(), @@ -957,12 +933,6 @@ impl AssistantService { .and_then(|b| String::from_utf8(b).ok()) .unwrap_or_default()) } - AssistantSource::Extension => { - // ResolvedAssistant doesn't expose rule content directly in - // the current backend; return empty until extension schema - // gains this field. Callers see empty == "no rule". - Ok(String::new()) - } AssistantSource::User => { let path = self.user_rule_path(id, locale); Ok(read_file_or_empty(&path)) @@ -970,15 +940,12 @@ impl AssistantService { } } - /// Write an assistant rule file. User only; built-in / extension reject. + /// Write an assistant rule file. User only; built-ins reject. pub async fn write_rule(&self, id: &str, locale: Option<&str>, content: &str) -> Result<(), AssistantError> { match self.classify_source(id).await { AssistantSource::Builtin => Err(AssistantError::BadRequest( "Cannot write rule for built-in assistant".into(), )), - AssistantSource::Extension => Err(AssistantError::BadRequest( - "Cannot write rule for extension-contributed assistant".into(), - )), AssistantSource::User => { let path = self.user_rule_path(id, locale); if let Some(parent) = path.parent() { @@ -997,9 +964,6 @@ impl AssistantService { AssistantSource::Builtin => Err(AssistantError::BadRequest( "Cannot delete rule for built-in assistant".into(), )), - AssistantSource::Extension => Err(AssistantError::BadRequest( - "Cannot delete rule for extension-contributed assistant".into(), - )), AssistantSource::User => Ok(remove_assistant_md_files(&self.user_rules_dir(), id)), } } @@ -1007,7 +971,6 @@ impl AssistantService { pub async fn read_skill(&self, id: &str, locale: Option<&str>) -> Result { match self.classify_source(id).await { AssistantSource::Builtin => Ok(String::new()), - AssistantSource::Extension => Ok(String::new()), AssistantSource::User => { let path = self.user_skill_path(id, locale); Ok(read_file_or_empty(&path)) @@ -1020,9 +983,6 @@ impl AssistantService { AssistantSource::Builtin => Err(AssistantError::BadRequest( "Cannot write skill for built-in assistant".into(), )), - AssistantSource::Extension => Err(AssistantError::BadRequest( - "Cannot write skill for extension-contributed assistant".into(), - )), AssistantSource::User => { let path = self.user_skill_path(id, locale); if let Some(parent) = path.parent() { @@ -1040,9 +1000,6 @@ impl AssistantService { AssistantSource::Builtin => Err(AssistantError::BadRequest( "Cannot delete skill for built-in assistant".into(), )), - AssistantSource::Extension => Err(AssistantError::BadRequest( - "Cannot delete skill for extension-contributed assistant".into(), - )), AssistantSource::User => Ok(remove_assistant_md_files(&self.user_skills_dir(), id)), } } @@ -1058,16 +1015,12 @@ impl AssistantService { /// override when `AIONUI_BUILTIN_ASSISTANTS_PATH` is set). /// - User source → scan the user-writable avatars directory for a file /// whose stem equals `id`. - /// - Extension source → `None`; the frontend serves those via - /// `aion-asset://`. - /// /// Built-ins whose manifest `avatar` field is an inline emoji (and thus /// has no on-disk file) also return `None`; clients fall back to the /// text avatar for those. pub async fn avatar_asset(&self, id: &str) -> Option { match self.classify_source(id).await { AssistantSource::Builtin => self.builtin.avatar_asset(id), - AssistantSource::Extension => None, AssistantSource::User => { let dir = self.user_avatars_dir(); let entries = std::fs::read_dir(&dir).ok()?; @@ -1106,6 +1059,77 @@ impl AssistantService { self.user_data_dir.join("assistant-avatars") } + fn normalize_user_avatar_input(&self, id: &str, avatar: Option<&str>) -> Result, AssistantError> { + let Some(value) = avatar.map(str::trim).filter(|value| !value.is_empty()) else { + remove_assistant_avatar_files(&self.user_avatars_dir(), id); + return Ok(None); + }; + + if !looks_like_avatar_asset(value) { + remove_assistant_avatar_files(&self.user_avatars_dir(), id); + return Ok(Some(value.to_string())); + } + + if let Some(source_assistant_id) = parse_assistant_avatar_route(value) { + if let Some(existing_avatar_path) = self.find_existing_user_avatar_file(&source_assistant_id) { + if source_assistant_id == id { + return Ok(Some(existing_avatar_path.to_string_lossy().to_string())); + } + return self.persist_user_avatar_file(id, &existing_avatar_path).map(Some); + } + return Ok(Some(value.to_string())); + } + + if let Some(source_path) = parse_local_avatar_path(value) { + return self.persist_user_avatar_file(id, &source_path).map(Some); + } + + remove_assistant_avatar_files(&self.user_avatars_dir(), id); + Ok(Some(value.to_string())) + } + + fn persist_user_avatar_file(&self, id: &str, source_path: &Path) -> Result { + let extension = source_path + .extension() + .and_then(|ext| ext.to_str()) + .map(|ext| ext.to_ascii_lowercase()) + .ok_or_else(|| AssistantError::BadRequest("assistant avatar must have a file extension".into()))?; + + if !is_supported_avatar_extension(&extension) { + return Err(AssistantError::BadRequest(format!( + "unsupported assistant avatar format: .{extension}" + ))); + } + + let destination_dir = self.user_avatars_dir(); + std::fs::create_dir_all(&destination_dir) + .map_err(|e| AssistantError::Internal(format!("create assistant avatar directory: {e}")))?; + remove_assistant_avatar_files(&destination_dir, id); + + let destination = destination_dir.join(format!("{id}.{extension}")); + std::fs::copy(source_path, &destination).map_err(|e| { + AssistantError::Internal(format!( + "copy assistant avatar from '{}' to '{}': {e}", + source_path.display(), + destination.display() + )) + })?; + + Ok(destination.to_string_lossy().to_string()) + } + + fn find_existing_user_avatar_file(&self, id: &str) -> Option { + let entries = std::fs::read_dir(self.user_avatars_dir()).ok()?; + for entry in entries.flatten() { + let path = entry.path(); + let file_stem = path.file_stem().and_then(|stem| stem.to_str()); + if file_stem == Some(id) { + return Some(path); + } + } + None + } + fn user_rule_path(&self, id: &str, locale: Option<&str>) -> PathBuf { assistant_md_path(&self.user_rules_dir(), id, locale) } @@ -1208,19 +1232,17 @@ fn assistant_error_to_extension_error(error: AssistantError) -> ExtensionError { // Response conversion // --------------------------------------------------------------------------- -/// Last-resort fallback for the assistant `preset_agent_type` when no -/// provider list is reachable (extension-contributed rows, sync display -/// conversions). `"aionrs"` is the only AionUI agent that does not require -/// a third-party CLI to be installed, so it never fails the -/// `Agent '' CLI not found in PATH` guard at agent build time. -/// -/// User- and import-created assistants take a different path: see -/// [`AssistantService::resolve_default_agent_type`], which inspects the -/// configured providers and returns a more specific default when possible. -const DEFAULT_AGENT_TYPE: &str = "aionrs"; - fn avatar_display_value(definition: &AssistantDefinitionRow) -> Option { - definition.avatar_value.clone() + match definition.avatar_type.as_str() { + "user_asset" => definition.avatar_value.as_deref().map(|value| { + if is_direct_avatar_url(value) { + value.to_string() + } else { + format!("/api/assistants/{}/avatar", definition.assistant_key) + } + }), + _ => definition.avatar_value.clone(), + } } fn serialize_avatar(source: &str, avatar: Option<&str>) -> (String, Option) { @@ -1244,13 +1266,39 @@ fn looks_like_avatar_asset(value: &str) -> bool { value.contains('/') || (std::path::Path::new(value).extension().is_some() && !value.starts_with('.')) } +fn parse_local_avatar_path(value: &str) -> Option { + let path = value + .strip_prefix("file://") + .map(PathBuf::from) + .unwrap_or_else(|| PathBuf::from(value)); + path.is_file().then_some(path) +} + +fn is_supported_avatar_extension(extension: &str) -> bool { + matches!(extension, "png" | "jpg" | "jpeg" | "webp" | "gif" | "svg") +} + +fn is_direct_avatar_url(value: &str) -> bool { + value.starts_with("http://") + || value.starts_with("https://") + || value.starts_with("data:") + || value.starts_with("file://") + || value.starts_with("/api/assistants/") +} + +fn parse_assistant_avatar_route(value: &str) -> Option { + let prefix = "/api/assistants/"; + let suffix = "/avatar"; + let id = value.strip_prefix(prefix)?.strip_suffix(suffix)?.trim(); + (!id.is_empty()).then(|| id.to_string()) +} + fn definition_to_response( definition: &AssistantDefinitionRow, state: Option<&AssistantOverlayRow>, ) -> Result { let source = match definition.source.as_str() { "builtin" => AssistantSource::Builtin, - "extension" => AssistantSource::Extension, _ => AssistantSource::User, }; let models = match ( @@ -1314,7 +1362,6 @@ fn definition_to_detail_response( id: definition.assistant_key.clone(), source: match definition.source.as_str() { "builtin" => AssistantSource::Builtin, - "extension" => AssistantSource::Extension, _ => AssistantSource::User, }, profile: AssistantProfileResponse { @@ -1379,90 +1426,6 @@ fn definition_to_detail_response( }) } -fn extension_to_response(e: &ResolvedAssistant) -> AssistantResponse { - AssistantResponse { - id: e.id.clone(), - source: AssistantSource::Extension, - name: e.name.clone(), - name_i18n: HashMap::new(), - description: e.description.clone(), - description_i18n: HashMap::new(), - avatar: e.icon.clone(), - enabled: true, - sort_order: 0, - preset_agent_type: DEFAULT_AGENT_TYPE.to_string(), - enabled_skills: Vec::new(), - custom_skill_names: Vec::new(), - disabled_builtin_skills: Vec::new(), - context: e.context.clone(), - context_i18n: HashMap::new(), - prompts: Vec::new(), - prompts_i18n: HashMap::new(), - models: Vec::new(), - last_used_at: None, - } -} - -fn extension_to_detail_response(e: &ResolvedAssistant) -> AssistantDetailResponse { - AssistantDetailResponse { - id: e.id.clone(), - source: AssistantSource::Extension, - profile: AssistantProfileResponse { - name: e.name.clone(), - name_i18n: HashMap::new(), - description: e.description.clone(), - description_i18n: HashMap::new(), - avatar: e.icon.clone(), - }, - state: AssistantStateResponse { - enabled: true, - sort_order: 0, - last_used_at: None, - }, - engine: AssistantEngineResponse { - agent_backend: DEFAULT_AGENT_TYPE.to_string(), - }, - rules: AssistantRulesResponse { - content: e.context.clone().unwrap_or_default(), - storage_mode: "extension".to_string(), - }, - prompts: AssistantPromptsResponse { - recommended: Vec::new(), - recommended_i18n: HashMap::new(), - }, - defaults: AssistantDefaultsResponse { - model: AssistantDefaultScalarResponse { - mode: "unset".to_string(), - value: None, - }, - permission: AssistantDefaultScalarResponse { - mode: "unset".to_string(), - value: None, - }, - skills: AssistantDefaultListResponse { - mode: "auto".to_string(), - value: Vec::new(), - }, - mcps: AssistantDefaultListResponse { - mode: "unset".to_string(), - value: Vec::new(), - }, - }, - capabilities: AssistantCapabilitiesResponse { - default_skill_ids: Vec::new(), - custom_skill_names: Vec::new(), - default_disabled_builtin_skill_ids: Vec::new(), - }, - preferences: AssistantPreferencesResponse { - last_model_id: None, - last_permission_value: None, - last_skill_ids: Vec::new(), - last_disabled_builtin_skill_ids: Vec::new(), - last_mcp_ids: Vec::new(), - }, - } -} - // --------------------------------------------------------------------------- // Serialization helpers // --------------------------------------------------------------------------- @@ -1774,8 +1737,6 @@ mod tests { SqliteAssistantOverrideRepository, SqliteAssistantPreferenceRepository, SqliteAssistantRepository, SqliteProviderRepository, init_database_memory, }; - use aionui_extension::ExtensionStateStore; - use aionui_realtime::BroadcastEventBus; use tempfile::TempDir; struct Fixture { @@ -1858,10 +1819,6 @@ mod tests { .unwrap(); let builtin_reg = Arc::new(BuiltinAssistantRegistry::load_from_dir(assets_dir)); - let event_bus = Arc::new(BroadcastEventBus::new(8)); - let ext_state_store = ExtensionStateStore::new(tmp.path().join("ext-states.json")); - let extension_registry = ExtensionRegistry::new(ext_state_store, event_bus, "1.0.0".to_string()); - let service = AssistantService::new( db.pool().clone(), definition_repo.clone(), @@ -1871,7 +1828,6 @@ mod tests { orepo, provider_repo.clone(), builtin_reg, - extension_registry, tmp.path().to_path_buf(), ); service.bootstrap_assistant_storage().await.unwrap(); @@ -2642,10 +2598,6 @@ mod tests { let orepo: Arc = Arc::new(SqliteAssistantOverrideRepository::new(db.pool().clone())); let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(db.pool().clone())); - let event_bus = Arc::new(BroadcastEventBus::new(8)); - let ext_state_store = ExtensionStateStore::new(tmp.path().join("ext-states.json")); - let extension_registry = ExtensionRegistry::new(ext_state_store, event_bus, "1.0.0".to_string()); - let service = AssistantService::new( db.pool().clone(), definition_repo, @@ -2655,7 +2607,6 @@ mod tests { orepo, provider_repo, builtin_reg, - extension_registry, tmp.path().to_path_buf(), ); let content = service.read_rule("builtin-office", Some("en-US")).await.unwrap(); diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql index cf22cb7e..dc4b6f7a 100644 --- a/crates/aionui-db/migrations/012_assistant_data_unification.sql +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -12,9 +12,9 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( definition_id TEXT PRIMARY KEY, assistant_key TEXT NOT NULL, source TEXT NOT NULL - CHECK (source IN ('builtin', 'user', 'generated', 'extension')), + CHECK (source IN ('builtin', 'user', 'generated')), owner_type TEXT NOT NULL - CHECK (owner_type IN ('system', 'user', 'extension')), + CHECK (owner_type IN ('system', 'user')), source_ref TEXT, source_version TEXT, source_hash TEXT, diff --git a/crates/aionui-db/src/database.rs b/crates/aionui-db/src/database.rs index 6bb6c10a..61c3caf0 100644 --- a/crates/aionui-db/src/database.rs +++ b/crates/aionui-db/src/database.rs @@ -847,14 +847,19 @@ async fn rebuild_legacy_assistant_unification_schema(pool: &SqlitePool) -> Resul let mut definitions = Vec::with_capacity(definition_rows.len()); for row in definition_rows { if definitions_use_internal_identity { + let source: String = row.get("source"); + let owner_type: String = row.get("owner_type"); + if source == "extension" || owner_type == "extension" { + continue; + } let definition_id: String = row.get("definition_id"); let assistant_key: String = row.get("assistant_key"); definition_id_map.insert(assistant_key.clone(), definition_id.clone()); definitions.push(( definition_id, assistant_key, - row.get::("source"), - row.get::("owner_type"), + source, + owner_type, row.get::, _>("source_ref"), row.get::, _>("source_version"), row.get::, _>("source_hash"), @@ -885,8 +890,12 @@ async fn rebuild_legacy_assistant_unification_schema(pool: &SqlitePool) -> Resul row.get::, _>("deleted_at"), )); } else { - let assistant_key: String = row.get("id"); let source: String = row.get("source"); + let owner_type: String = row.get("owner_type"); + if source == "extension" || owner_type == "extension" { + continue; + } + let assistant_key: String = row.get("id"); let avatar: Option = row.get("avatar"); let definition_id = aionui_common::generate_prefixed_id("asstdef"); let (avatar_type, avatar_value) = infer_avatar_storage(&source, avatar.as_deref()); @@ -895,7 +904,7 @@ async fn rebuild_legacy_assistant_unification_schema(pool: &SqlitePool) -> Resul definition_id, assistant_key, source, - row.get::("owner_type"), + owner_type, row.get::, _>("source_ref"), row.get::, _>("source_version"), row.get::, _>("source_hash"), @@ -1110,9 +1119,9 @@ async fn create_final_assistant_unification_tables(tx: &mut sqlx::Transaction<'_ definition_id TEXT PRIMARY KEY, assistant_key TEXT NOT NULL, source TEXT NOT NULL - CHECK (source IN ('builtin', 'user', 'generated', 'extension')), + CHECK (source IN ('builtin', 'user', 'generated')), owner_type TEXT NOT NULL - CHECK (owner_type IN ('system', 'user', 'extension')), + CHECK (owner_type IN ('system', 'user')), source_ref TEXT, source_version TEXT, source_hash TEXT, diff --git a/crates/aionui-db/tests/assistant_data_unification_schema.rs b/crates/aionui-db/tests/assistant_data_unification_schema.rs index 38ef307e..ed76e32d 100644 --- a/crates/aionui-db/tests/assistant_data_unification_schema.rs +++ b/crates/aionui-db/tests/assistant_data_unification_schema.rs @@ -65,3 +65,56 @@ async fn assistant_definition_table_has_expected_default_columns() { .unwrap_or_default(); assert!(preference_columns.iter().any(|name| name == "definition_id")); } + +#[tokio::test] +async fn assistant_definition_table_rejects_extension_source_and_owner_type() { + let db = init_database_memory().await.unwrap(); + + let source_err = sqlx::query( + r#" + INSERT INTO assistant_definitions ( + definition_id, assistant_key, source, owner_type, source_ref, + name, name_i18n, description_i18n, avatar_type, agent_backend, + rule_resource_type, recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_permission_mode, default_skills_mode, default_skill_ids, + custom_skill_names, default_disabled_builtin_skill_ids, default_mcps_mode, default_mcp_ids, + created_at, updated_at + ) VALUES ( + 'd-ext-source', 'ext-source', 'extension', 'system', 'ext-source', + 'Ext Source', '{}', '{}', 'none', 'aionrs', + 'none', '[]', '{}', + 'unset', 'unset', 'fixed', '[]', + '[]', '[]', 'unset', '[]', + 1, 1 + ) + "#, + ) + .execute(db.pool()) + .await + .unwrap_err(); + assert!(source_err.to_string().contains("CHECK constraint failed")); + + let owner_err = sqlx::query( + r#" + INSERT INTO assistant_definitions ( + definition_id, assistant_key, source, owner_type, source_ref, + name, name_i18n, description_i18n, avatar_type, agent_backend, + rule_resource_type, recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_permission_mode, default_skills_mode, default_skill_ids, + custom_skill_names, default_disabled_builtin_skill_ids, default_mcps_mode, default_mcp_ids, + created_at, updated_at + ) VALUES ( + 'd-ext-owner', 'ext-owner', 'builtin', 'extension', 'ext-owner', + 'Ext Owner', '{}', '{}', 'none', 'aionrs', + 'none', '[]', '{}', + 'unset', 'unset', 'fixed', '[]', + '[]', '[]', 'unset', '[]', + 1, 1 + ) + "#, + ) + .execute(db.pool()) + .await + .unwrap_err(); + assert!(owner_err.to_string().contains("CHECK constraint failed")); +} diff --git a/crates/aionui-db/tests/db_lifecycle.rs b/crates/aionui-db/tests/db_lifecycle.rs index e8278dc8..19beaf6e 100644 --- a/crates/aionui-db/tests/db_lifecycle.rs +++ b/crates/aionui-db/tests/db_lifecycle.rs @@ -320,6 +320,173 @@ CREATE TABLE assistant_definitions ( db.close().await; } +#[tokio::test] +async fn idempotent_reinit_drops_legacy_extension_assistant_definitions() { + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("test.db"); + + let db = init_database(&path).await.unwrap(); + db.close().await; + + let pool = open_file_pool(&path).await; + sqlx::query("PRAGMA foreign_keys = OFF").execute(&pool).await.unwrap(); + sqlx::query("DROP TABLE assistant_preferences") + .execute(&pool) + .await + .unwrap(); + sqlx::query("DROP TABLE assistant_overlays") + .execute(&pool) + .await + .unwrap(); + sqlx::query("DROP TABLE assistant_definitions") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + r#" +CREATE TABLE assistant_definitions ( + id TEXT PRIMARY KEY, + source TEXT NOT NULL, + owner_type TEXT NOT NULL, + source_ref TEXT, + source_version TEXT, + source_hash TEXT, + name TEXT NOT NULL, + name_i18n TEXT NOT NULL DEFAULT '{}', + description TEXT, + description_i18n TEXT NOT NULL DEFAULT '{}', + avatar TEXT, + agent_backend TEXT NOT NULL, + rule_resource_type TEXT NOT NULL, + rule_resource_ref TEXT, + rule_inline_content TEXT, + recommended_prompts TEXT NOT NULL DEFAULT '[]', + recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', + default_model_mode TEXT NOT NULL, + default_model_value TEXT, + default_permission_mode TEXT NOT NULL, + default_permission_value TEXT, + default_skills_mode TEXT NOT NULL, + default_skill_ids TEXT NOT NULL DEFAULT '[]', + custom_skill_names TEXT NOT NULL DEFAULT '[]', + default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + default_mcps_mode TEXT NOT NULL, + default_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + deleted_at INTEGER +) + "#, + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref + ON assistant_definitions(source, source_ref) + WHERE source_ref IS NOT NULL", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") + .execute(&pool) + .await + .unwrap(); + sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE TABLE assistant_states ( + assistant_id TEXT PRIMARY KEY, + enabled INTEGER NOT NULL DEFAULT 1, + sort_order INTEGER NOT NULL DEFAULT 0, + agent_backend_override TEXT, + last_used_at INTEGER, + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "CREATE TABLE assistant_preferences ( + assistant_id TEXT PRIMARY KEY, + last_model_id TEXT, + last_permission_value TEXT, + last_skill_ids TEXT NOT NULL DEFAULT '[]', + last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + last_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_definitions ( + id, source, owner_type, source_ref, source_version, source_hash, + name, name_i18n, description, description_i18n, avatar, + agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, + recommended_prompts, recommended_prompts_i18n, + default_model_mode, default_model_value, + default_permission_mode, default_permission_value, + default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, + default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at + ) VALUES ( + 'ext-helper', 'extension', 'extension', 'ext-helper', NULL, NULL, + 'Helper', '{}', 'desc', '{}', NULL, + 'aionrs', 'inline', NULL, 'ctx', + '[]', '{}', + 'unset', NULL, + 'unset', NULL, + 'fixed', '[]', '[]', '[]', + 'unset', '[]', 1, 2, NULL + )", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_states (assistant_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at) + VALUES ('ext-helper', 1, 3, NULL, NULL, 1, 2)", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query( + "INSERT INTO assistant_preferences (assistant_id, last_model_id, last_permission_value, last_skill_ids, + last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at) + VALUES ('ext-helper', 'gpt-4.1', NULL, '[]', '[]', '[]', 1, 2)", + ) + .execute(&pool) + .await + .unwrap(); + sqlx::query("PRAGMA foreign_keys = ON").execute(&pool).await.unwrap(); + pool.close().await; + + let db = init_database(&path).await.unwrap(); + let count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM assistant_definitions") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(count, 0); + let overlay_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM assistant_overlays") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(overlay_count, 0); + let preference_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM assistant_preferences") + .fetch_one(db.pool()) + .await + .unwrap(); + assert_eq!(preference_count, 0); + db.close().await; +} + #[tokio::test] async fn idempotent_reinit_repairs_stale_assistant_definition_default_mode_constraints() { let dir = tempfile::tempdir().unwrap(); From 6ece4baf5303264bf043d55626733fa8ea1e961f Mon Sep 17 00:00:00 2001 From: zk <> Date: Thu, 11 Jun 2026 12:25:46 +0800 Subject: [PATCH 11/19] refactor(conversation): persist assistant snapshots outside extra --- crates/aionui-app/tests/conversation_e2e.rs | 37 +- crates/aionui-conversation/src/service.rs | 284 +++++++- crates/aionui-conversation/src/service_ops.rs | 19 +- .../aionui-conversation/src/service_test.rs | 541 ++++++++++++++- .../012_assistant_data_unification.sql | 41 ++ crates/aionui-db/src/database.rs | 635 +----------------- crates/aionui-db/src/lib.rs | 7 +- crates/aionui-db/src/models/conversation.rs | 48 ++ crates/aionui-db/src/models/mod.rs | 2 +- .../aionui-db/src/repository/conversation.rs | 26 +- .../src/repository/sqlite_conversation.rs | 102 ++- .../assistant_data_unification_schema.rs | 15 + crates/aionui-db/tests/db_lifecycle.rs | 567 ---------------- 13 files changed, 1051 insertions(+), 1273 deletions(-) diff --git a/crates/aionui-app/tests/conversation_e2e.rs b/crates/aionui-app/tests/conversation_e2e.rs index a25e8614..de5ef1e1 100644 --- a/crates/aionui-app/tests/conversation_e2e.rs +++ b/crates/aionui-app/tests/conversation_e2e.rs @@ -4,8 +4,9 @@ mod common; use aionui_db::{ IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantPreferenceRepository, - SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, SqliteAssistantPreferenceRepository, - UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, UpsertAssistantPreferenceParams, + IConversationRepository, SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, + SqliteAssistantPreferenceRepository, SqliteConversationRepository, UpsertAssistantDefinitionParams, + UpsertAssistantOverlayParams, UpsertAssistantPreferenceParams, }; use axum::http::StatusCode; use serde_json::json; @@ -145,6 +146,7 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { let definition_repo = SqliteAssistantDefinitionRepository::new(pool.clone()); let state_repo = SqliteAssistantOverlayRepository::new(pool.clone()); let preference_repo = SqliteAssistantPreferenceRepository::new(pool); + let conversation_repo = SqliteConversationRepository::new(services.database.pool().clone()); let definition = definition_repo.get_by_key("u1").await.unwrap().unwrap(); definition_repo @@ -232,24 +234,7 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { assert_eq!(data["extra"]["preset_assistant_id"], "u1"); assert_eq!(data["extra"]["preset_context"], "assistant snapshot rule"); assert_eq!(data["extra"]["current_model_id"], "override-model"); - assert_eq!(data["extra"]["assistant_snapshot"]["assistant_id"], "u1"); - assert_eq!(data["extra"]["assistant_snapshot"]["agent_backend"], "codex"); - assert_eq!( - data["extra"]["assistant_snapshot"]["rules"]["content"], - "assistant snapshot rule" - ); - assert_eq!( - data["extra"]["assistant_snapshot"]["resolved_defaults"]["permission"], - "workspace-write" - ); - assert_eq!( - data["extra"]["assistant_snapshot"]["resolved_defaults"]["skill_ids"], - json!(["override-skill"]) - ); - assert_eq!( - data["extra"]["assistant_snapshot"]["resolved_defaults"]["mcp_ids"], - json!(["override-mcp"]) - ); + assert!(data["extra"].get("assistant_snapshot").is_none()); assert!( data["extra"]["skills"] .as_array() @@ -258,6 +243,18 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { .any(|skill| skill == "override-skill") ); + let snapshot = conversation_repo + .get_assistant_snapshot(data["id"].as_str().unwrap()) + .await + .unwrap() + .unwrap(); + assert_eq!(snapshot.assistant_key, "u1"); + assert_eq!(snapshot.agent_backend, "codex"); + assert_eq!(snapshot.rules_content, "assistant snapshot rule"); + assert_eq!(snapshot.resolved_permission_value.as_deref(), Some("workspace-write")); + assert_eq!(snapshot.resolved_skill_ids, r#"["override-skill"]"#); + assert_eq!(snapshot.resolved_mcp_ids, r#"["override-mcp"]"#); + let updated_preference = preference_repo.get(&definition.definition_id).await.unwrap().unwrap(); assert_eq!(updated_preference.last_model_id.as_deref(), Some("override-model")); assert_eq!( diff --git a/crates/aionui-conversation/src/service.rs b/crates/aionui-conversation/src/service.rs index 04bfc2be..bac30ad1 100644 --- a/crates/aionui-conversation/src/service.rs +++ b/crates/aionui-conversation/src/service.rs @@ -27,6 +27,7 @@ use aionui_db::{ ConversationFilters, ConversationRowUpdate, CreateAcpSessionParams, IAcpSessionRepository, IAgentMetadataRepository, IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantPreferenceRepository, IConversationRepository, IMcpServerRepository, SaveRuntimeStateParams, SortOrder, + UpsertConversationAssistantSnapshotParams, }; use aionui_extension::AssistantRuleDispatcher; use aionui_mcp::{AcpMcpCapabilities, parse_acp_mcp_capabilities}; @@ -78,6 +79,18 @@ struct AssistantSnapshotResolvedDefaults { mcp_ids: Vec, } +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)] +struct AssistantSnapshotDefaultModes { + #[serde(default)] + model: String, + #[serde(default)] + permission: String, + #[serde(default)] + skills: String, + #[serde(default)] + mcps: String, +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] struct AssistantSnapshotRules { content: String, @@ -85,18 +98,53 @@ struct AssistantSnapshotRules { #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] struct AssistantSnapshot { + assistant_definition_id: String, assistant_id: String, assistant_source: String, #[serde(default)] name: String, #[serde(default)] + avatar_type: String, + #[serde(default)] avatar: Option, agent_backend: String, rules: AssistantSnapshotRules, + #[serde(default)] + default_modes: AssistantSnapshotDefaultModes, resolved_defaults: AssistantSnapshotResolvedDefaults, created_at: i64, } +#[derive(Debug, Clone, Copy)] +struct AssistantEffectiveDefaultModes<'a> { + model: &'a str, + permission: &'a str, +} + +#[derive(Debug, Clone, Copy, Default)] +pub(crate) struct AssistantRuntimePreferenceUpdate<'a> { + pub(crate) model: Option<&'a str>, + pub(crate) permission: Option<&'a str>, +} + +fn assistant_snapshot_modes<'a>( + snapshot: &'a AssistantSnapshot, + definition: &'a aionui_db::AssistantDefinitionRow, +) -> AssistantEffectiveDefaultModes<'a> { + AssistantEffectiveDefaultModes { + model: if snapshot.default_modes.model.is_empty() { + definition.default_model_mode.as_str() + } else { + snapshot.default_modes.model.as_str() + }, + permission: if snapshot.default_modes.permission.is_empty() { + definition.default_permission_mode.as_str() + } else { + snapshot.default_modes.permission.as_str() + }, + } +} + #[derive(Debug, Clone, Copy)] struct McpSupportPolicy { stdio: bool, @@ -532,11 +580,6 @@ impl ConversationService { "assistant_id".to_owned(), serde_json::Value::String(snapshot.assistant_id.clone()), ); - obj.insert( - "assistant_snapshot".to_owned(), - serde_json::to_value(snapshot) - .map_err(|e| ConversationError::internal(format!("Failed to serialize assistant snapshot: {e}")))?, - ); obj.insert( "preset_assistant_id".to_owned(), serde_json::Value::String(snapshot.assistant_id.clone()), @@ -764,6 +807,44 @@ impl ConversationService { self.conversation_repo.create(&row).await?; + if let Some(snapshot) = assistant_snapshot.as_ref() { + let resolved_skill_ids = serde_json::to_string(&snapshot.resolved_defaults.skill_ids).map_err(|e| { + ConversationError::internal(format!("Failed to serialize assistant skill snapshot: {e}")) + })?; + let resolved_disabled_builtin_skill_ids = + serde_json::to_string(&snapshot.resolved_defaults.disabled_builtin_skill_ids).map_err(|e| { + ConversationError::internal(format!( + "Failed to serialize assistant disabled builtin skill snapshot: {e}" + )) + })?; + let resolved_mcp_ids = serde_json::to_string(&snapshot.resolved_defaults.mcp_ids) + .map_err(|e| ConversationError::internal(format!("Failed to serialize assistant MCP snapshot: {e}")))?; + + self.conversation_repo + .upsert_assistant_snapshot(&UpsertConversationAssistantSnapshotParams { + conversation_id: &row.id, + assistant_definition_id: &snapshot.assistant_definition_id, + assistant_key: &snapshot.assistant_id, + assistant_source: &snapshot.assistant_source, + assistant_name: &snapshot.name, + assistant_avatar_type: &snapshot.avatar_type, + assistant_avatar_value: snapshot.avatar.as_deref(), + agent_backend: &snapshot.agent_backend, + rules_content: &snapshot.rules.content, + default_model_mode: &snapshot.default_modes.model, + resolved_model_id: snapshot.resolved_defaults.model.as_deref(), + default_permission_mode: &snapshot.default_modes.permission, + resolved_permission_value: snapshot.resolved_defaults.permission.as_deref(), + default_skills_mode: &snapshot.default_modes.skills, + resolved_skill_ids: &resolved_skill_ids, + resolved_disabled_builtin_skill_ids: &resolved_disabled_builtin_skill_ids, + default_mcps_mode: &snapshot.default_modes.mcps, + resolved_mcp_ids: &resolved_mcp_ids, + }) + .await? + .ok_or_else(|| ConversationError::internal("assistant snapshot upsert returned no row"))?; + } + // ACP conversations own one `acp_session` row (1:1 by // conversation_id). Other agent types have no session-level // state so we only create it for ACP. @@ -772,8 +853,7 @@ impl ConversationService { } if let Some(snapshot) = assistant_snapshot.as_ref() { - self.persist_assistant_preferences_from_snapshot(&snapshot.assistant_id, snapshot) - .await?; + self.persist_assistant_preferences_from_snapshot(snapshot).await?; } let response = row_to_response(row, &self.workspace_root)?; @@ -967,9 +1047,11 @@ impl ConversationService { .unwrap_or_else(|| definition.agent_backend.clone()); Ok(Some(AssistantSnapshot { + assistant_definition_id: definition.definition_id, assistant_id: assistant_id.to_owned(), assistant_source: definition.source, name: definition.name, + avatar_type: definition.avatar_type, avatar: definition.avatar_value, agent_backend, rules: AssistantSnapshotRules { @@ -979,6 +1061,12 @@ impl ConversationService { rules_content }, }, + default_modes: AssistantSnapshotDefaultModes { + model: definition.default_model_mode.clone(), + permission: definition.default_permission_mode.clone(), + skills: definition.default_skills_mode.clone(), + mcps: definition.default_mcps_mode.clone(), + }, resolved_defaults: AssistantSnapshotResolvedDefaults { model, permission, @@ -992,39 +1080,29 @@ impl ConversationService { async fn persist_assistant_preferences_from_snapshot( &self, - assistant_id: &str, snapshot: &AssistantSnapshot, ) -> Result<(), ConversationError> { - let (Some(definition_repo), Some(preference_repo)) = - (self.assistant_definition_repo(), self.assistant_preference_repo()) - else { - return Ok(()); - }; - let Some(definition) = definition_repo - .get_by_key(assistant_id) - .await - .map_err(|e| ConversationError::internal(format!("assistant definition lookup failed: {e}")))? - else { + let Some(preference_repo) = self.assistant_preference_repo() else { return Ok(()); }; let existing_preference = preference_repo - .get(&definition.definition_id) + .get(&snapshot.assistant_definition_id) .await .map_err(|e| ConversationError::internal(format!("assistant preference lookup failed: {e}")))?; - let last_model_id = if definition.default_model_mode == "auto" { + let last_model_id = if snapshot.default_modes.model == "auto" { snapshot.resolved_defaults.model.clone() } else { existing_preference.as_ref().and_then(|row| row.last_model_id.clone()) }; - let last_permission_value = if definition.default_permission_mode == "auto" { + let last_permission_value = if snapshot.default_modes.permission == "auto" { snapshot.resolved_defaults.permission.clone() } else { existing_preference .as_ref() .and_then(|row| row.last_permission_value.clone()) }; - let last_skill_ids = if definition.default_skills_mode == "auto" { + let last_skill_ids = if snapshot.default_modes.skills == "auto" { serde_json::to_string(&snapshot.resolved_defaults.skill_ids) .map_err(|e| ConversationError::internal(format!("encode assistant skills: {e}")))? } else { @@ -1033,7 +1111,7 @@ impl ConversationService { .map(|row| row.last_skill_ids.clone()) .unwrap_or_else(|| "[]".to_string()) }; - let last_disabled_builtin_skill_ids = if definition.default_skills_mode == "auto" { + let last_disabled_builtin_skill_ids = if snapshot.default_modes.skills == "auto" { serde_json::to_string(&snapshot.resolved_defaults.disabled_builtin_skill_ids) .map_err(|e| ConversationError::internal(format!("encode assistant disabled builtin skills: {e}")))? } else { @@ -1042,7 +1120,7 @@ impl ConversationService { .map(|row| row.last_disabled_builtin_skill_ids.clone()) .unwrap_or_else(|| "[]".to_string()) }; - let last_mcp_ids = if definition.default_mcps_mode == "auto" { + let last_mcp_ids = if snapshot.default_modes.mcps == "auto" { serde_json::to_string(&snapshot.resolved_defaults.mcp_ids) .map_err(|e| ConversationError::internal(format!("encode assistant mcps: {e}")))? } else { @@ -1054,7 +1132,7 @@ impl ConversationService { preference_repo .upsert(&aionui_db::UpsertAssistantPreferenceParams { - definition_id: &definition.definition_id, + definition_id: &snapshot.assistant_definition_id, last_model_id: last_model_id.as_deref(), last_permission_value: last_permission_value.as_deref(), last_skill_ids: &last_skill_ids, @@ -1067,6 +1145,150 @@ impl ConversationService { Ok(()) } + pub(crate) async fn persist_runtime_assistant_preferences( + &self, + conversation_id: &str, + updates: AssistantRuntimePreferenceUpdate<'_>, + ) -> Result<(), ConversationError> { + let (Some(definition_repo), Some(preference_repo)) = + (self.assistant_definition_repo(), self.assistant_preference_repo()) + else { + return Ok(()); + }; + + let persisted_snapshot = self + .conversation_repo + .get_assistant_snapshot(conversation_id) + .await + .map_err(|e| { + ConversationError::internal(format!( + "Failed to load persisted assistant snapshot for preference sync: {e}" + )) + })?; + + let fallback = if persisted_snapshot.is_none() { + let Some(conversation) = self.conversation_repo.get(conversation_id).await.map_err(|e| { + ConversationError::internal(format!( + "Failed to load conversation for assistant preference sync: {e}" + )) + })? + else { + return Ok(()); + }; + let extra: serde_json::Value = serde_json::from_str(&conversation.extra).map_err(|e| { + ConversationError::internal(format!("Invalid extra JSON for assistant preference sync: {e}")) + })?; + let legacy_snapshot = extra + .get("assistant_snapshot") + .cloned() + .map(serde_json::from_value::) + .transpose() + .map_err(|e| { + ConversationError::internal(format!("Invalid assistant snapshot for preference sync: {e}")) + })?; + let assistant_id = legacy_snapshot + .as_ref() + .map(|value| value.assistant_id.clone()) + .or_else(|| { + extra + .get("assistant_id") + .and_then(serde_json::Value::as_str) + .map(ToOwned::to_owned) + }) + .or_else(|| { + extra + .get("preset_assistant_id") + .and_then(serde_json::Value::as_str) + .map(ToOwned::to_owned) + }); + let Some(assistant_id) = assistant_id else { + return Ok(()); + }; + let Some(definition) = definition_repo + .get_by_key(&assistant_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant definition lookup failed: {e}")))? + else { + return Ok(()); + }; + Some((definition, legacy_snapshot)) + } else { + None + }; + + let (definition_id, default_modes) = if let Some(snapshot) = persisted_snapshot.as_ref() { + ( + snapshot.assistant_definition_id.clone(), + AssistantEffectiveDefaultModes { + model: snapshot.default_model_mode.as_str(), + permission: snapshot.default_permission_mode.as_str(), + }, + ) + } else { + let (definition, legacy_snapshot) = fallback + .as_ref() + .ok_or_else(|| ConversationError::internal("assistant preference sync fallback missing"))?; + ( + definition.definition_id.clone(), + legacy_snapshot + .as_ref() + .map(|value| assistant_snapshot_modes(value, definition)) + .unwrap_or_else(|| AssistantEffectiveDefaultModes { + model: definition.default_model_mode.as_str(), + permission: definition.default_permission_mode.as_str(), + }), + ) + }; + + let existing_preference = preference_repo + .get(&definition_id) + .await + .map_err(|e| ConversationError::internal(format!("assistant preference lookup failed: {e}")))?; + + let last_model_id = if default_modes.model == "auto" { + updates + .model + .map(ToOwned::to_owned) + .or_else(|| existing_preference.as_ref().and_then(|row| row.last_model_id.clone())) + } else { + existing_preference.as_ref().and_then(|row| row.last_model_id.clone()) + }; + let last_permission_value = if default_modes.permission == "auto" { + updates.permission.map(ToOwned::to_owned).or_else(|| { + existing_preference + .as_ref() + .and_then(|row| row.last_permission_value.clone()) + }) + } else { + existing_preference + .as_ref() + .and_then(|row| row.last_permission_value.clone()) + }; + + preference_repo + .upsert(&aionui_db::UpsertAssistantPreferenceParams { + definition_id: &definition_id, + last_model_id: last_model_id.as_deref(), + last_permission_value: last_permission_value.as_deref(), + last_skill_ids: existing_preference + .as_ref() + .map(|row| row.last_skill_ids.as_str()) + .unwrap_or("[]"), + last_disabled_builtin_skill_ids: existing_preference + .as_ref() + .map(|row| row.last_disabled_builtin_skill_ids.as_str()) + .unwrap_or("[]"), + last_mcp_ids: existing_preference + .as_ref() + .map(|row| row.last_mcp_ids.as_str()) + .unwrap_or("[]"), + }) + .await + .map_err(|e| ConversationError::internal(format!("assistant runtime preference upsert failed: {e}")))?; + + Ok(()) + } + /// Get a single conversation by ID. /// /// Returns `NotFound` if the conversation does not exist or does not @@ -1259,6 +1481,18 @@ impl ConversationService { self.conversation_repo.update(id, &updates).await?; + if let Some(model) = req.model.as_ref() { + let selected_model = model.use_model.as_deref().unwrap_or(model.model.as_str()); + self.persist_runtime_assistant_preferences( + id, + AssistantRuntimePreferenceUpdate { + model: Some(selected_model), + ..Default::default() + }, + ) + .await?; + } + if model_changed { info!( model_changed = true, diff --git a/crates/aionui-conversation/src/service_ops.rs b/crates/aionui-conversation/src/service_ops.rs index 5db01aa6..abe8e648 100644 --- a/crates/aionui-conversation/src/service_ops.rs +++ b/crates/aionui-conversation/src/service_ops.rs @@ -41,6 +41,14 @@ impl ConversationService { } let task = self.task(conversation_id)?; task.set_mode(&req.mode).await.map_err(ConversationError::from)?; + self.persist_runtime_assistant_preferences( + conversation_id, + crate::service::AssistantRuntimePreferenceUpdate { + permission: Some(&req.mode), + ..Default::default() + }, + ) + .await?; task.get_mode().await.map_err(ConversationError::from) } @@ -77,7 +85,16 @@ impl ConversationService { }; task.set_model_confirmed(&req.model_id) .await - .map_err(ConversationError::from) + .map_err(ConversationError::from)?; + self.persist_runtime_assistant_preferences( + conversation_id, + crate::service::AssistantRuntimePreferenceUpdate { + model: Some(&req.model_id), + ..Default::default() + }, + ) + .await?; + task.get_model().await.map_err(ConversationError::from) } // ── Usage / Slash commands ────────────────────────────────────── diff --git a/crates/aionui-conversation/src/service_test.rs b/crates/aionui-conversation/src/service_test.rs index c01f871c..30ef9bbe 100644 --- a/crates/aionui-conversation/src/service_test.rs +++ b/crates/aionui-conversation/src/service_test.rs @@ -13,19 +13,20 @@ use aionui_ai_agent::{AgentError, AgentSendError, IWorkerTaskManager}; use crate::response_middleware::{CronCommandResult, CronCreateParams, CronUpdateParams, ICronService}; use aionui_api_types::{ - AgentErrorCode, AgentModeResponse, ConversationArtifactKind, GetModelInfoResponse, ModelInfoEntry, - ModelInfoPayload, SetModeRequest, SetModelRequest, + AgentErrorCode, AgentModeResponse, ConversationArtifactKind, ConversationResponse, GetModelInfoResponse, + ModelInfoEntry, ModelInfoPayload, SetModeRequest, SetModelRequest, }; use aionui_api_types::{ CloneConversationRequest, CreateConversationRequest, ListConversationsQuery, SearchMessagesQuery, SendMessageRequest, UpdateConversationRequest, WebSocketMessage, }; use aionui_common::{ - AgentKillReason, AgentType, Confirmation, ConversationSource, ConversationStatus, PaginatedResult, TimestampMs, + AgentKillReason, AgentType, Confirmation, ConversationSource, ConversationStatus, PaginatedResult, + ProviderWithModel, TimestampMs, }; use aionui_db::models::{ - AcpSessionRow, AgentMetadataRow, ConversationArtifactRow, ConversationRow, MessageRow, UpdateAgentHandshakeParams, - UpsertAgentMetadataParams, + AcpSessionRow, AgentMetadataRow, ConversationArtifactRow, ConversationAssistantSnapshotRow, ConversationRow, + MessageRow, UpdateAgentHandshakeParams, UpsertAgentMetadataParams, }; use aionui_db::{ ConversationFilters, ConversationRowUpdate, CreateAcpSessionParams, DbError, IAcpSessionRepository, @@ -33,7 +34,7 @@ use aionui_db::{ IAssistantPreferenceRepository, IConversationRepository, MessageRowUpdate, MessageSearchRow, PersistedSessionState, SaveRuntimeStateParams, SortOrder, SqliteAssistantDefinitionRepository, SqliteAssistantOverlayRepository, SqliteAssistantPreferenceRepository, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, - UpsertAssistantPreferenceParams, init_database_memory, + UpsertAssistantPreferenceParams, UpsertConversationAssistantSnapshotParams, init_database_memory, }; use aionui_extension::{AssistantRuleDispatcher, ExtensionError}; use aionui_realtime::EventBroadcaster; @@ -168,6 +169,7 @@ struct MockRepo { rows: Mutex>, messages: Mutex>, artifacts: Mutex>, + assistant_snapshots: Mutex>, } impl MockRepo { @@ -176,6 +178,7 @@ impl MockRepo { rows: Mutex::new(vec![]), messages: Mutex::new(vec![]), artifacts: Mutex::new(vec![]), + assistant_snapshots: Mutex::new(vec![]), } } } @@ -284,6 +287,53 @@ impl IConversationRepository for MockRepo { Ok(vec![]) } + async fn get_assistant_snapshot( + &self, + conversation_id: &str, + ) -> Result, aionui_db::DbError> { + let rows = self.assistant_snapshots.lock().unwrap(); + Ok(rows.iter().find(|row| row.conversation_id == conversation_id).cloned()) + } + + async fn upsert_assistant_snapshot( + &self, + params: &UpsertConversationAssistantSnapshotParams<'_>, + ) -> Result, aionui_db::DbError> { + let row = ConversationAssistantSnapshotRow { + conversation_id: params.conversation_id.to_owned(), + assistant_definition_id: params.assistant_definition_id.to_owned(), + assistant_key: params.assistant_key.to_owned(), + assistant_source: params.assistant_source.to_owned(), + assistant_name: params.assistant_name.to_owned(), + assistant_avatar_type: params.assistant_avatar_type.to_owned(), + assistant_avatar_value: params.assistant_avatar_value.map(ToOwned::to_owned), + agent_backend: params.agent_backend.to_owned(), + rules_content: params.rules_content.to_owned(), + default_model_mode: params.default_model_mode.to_owned(), + resolved_model_id: params.resolved_model_id.map(ToOwned::to_owned), + default_permission_mode: params.default_permission_mode.to_owned(), + resolved_permission_value: params.resolved_permission_value.map(ToOwned::to_owned), + default_skills_mode: params.default_skills_mode.to_owned(), + resolved_skill_ids: params.resolved_skill_ids.to_owned(), + resolved_disabled_builtin_skill_ids: params.resolved_disabled_builtin_skill_ids.to_owned(), + default_mcps_mode: params.default_mcps_mode.to_owned(), + resolved_mcp_ids: params.resolved_mcp_ids.to_owned(), + created_at: 1, + updated_at: 1, + }; + let mut rows = self.assistant_snapshots.lock().unwrap(); + rows.retain(|existing| existing.conversation_id != params.conversation_id); + rows.push(row.clone()); + Ok(Some(row)) + } + + async fn delete_assistant_snapshot(&self, conversation_id: &str) -> Result { + let mut rows = self.assistant_snapshots.lock().unwrap(); + let before = rows.len(); + rows.retain(|row| row.conversation_id != conversation_id); + Ok(rows.len() != before) + } + async fn get_messages( &self, conv_id: &str, @@ -658,6 +708,30 @@ fn make_service_with_mock_task_manager( (svc, broadcaster, repo) } +async fn make_service_with_mock_task_manager_and_assistant_support( + task_mgr: Arc, +) -> ( + ConversationService, + Arc, + Arc, + Arc, + Arc, + Arc, +) { + let (svc, broadcaster, repo) = make_service_with_mock_task_manager(task_mgr); + let db = init_database_memory().await.unwrap(); + let definition_repo = Arc::new(SqliteAssistantDefinitionRepository::new(db.pool().clone())); + let overlay_repo = Arc::new(SqliteAssistantOverlayRepository::new(db.pool().clone())); + let preference_repo: Arc = + Arc::new(SqliteAssistantPreferenceRepository::new(db.pool().clone())); + + svc.with_assistant_definition_repo(definition_repo.clone()); + svc.with_assistant_state_repo(overlay_repo.clone()); + svc.with_assistant_preference_repo(preference_repo.clone()); + + (svc, broadcaster, repo, definition_repo, overlay_repo, preference_repo) +} + async fn make_service_with_assistant_support( skill_resolver: Arc, dispatcher: Arc, @@ -699,6 +773,80 @@ fn ensure_test_workspace_path() -> String { workspace.to_string_lossy().to_string() } +async fn upsert_test_assistant_definition( + repo: &SqliteAssistantDefinitionRepository, + definition_id: &str, + assistant_key: &str, + agent_backend: &str, + default_model_mode: &str, + default_permission_mode: &str, +) { + repo.upsert(&UpsertAssistantDefinitionParams { + definition_id, + assistant_key, + source: "builtin", + owner_type: "system", + source_ref: Some(assistant_key), + source_version: None, + source_hash: None, + name: assistant_key, + name_i18n: "{}", + description: Some("desc"), + description_i18n: "{}", + avatar_type: "emoji", + avatar_value: Some("🤖"), + agent_backend, + rule_resource_type: "builtin_asset", + rule_resource_ref: Some(assistant_key), + rule_inline_content: None, + recommended_prompts: "[]", + recommended_prompts_i18n: "{}", + default_model_mode, + default_model_value: None, + default_permission_mode, + default_permission_value: None, + default_skills_mode: "auto", + default_skill_ids: "[]", + custom_skill_names: "[]", + default_disabled_builtin_skill_ids: "[]", + default_mcps_mode: "unset", + default_mcp_ids: "[]", + }) + .await + .unwrap(); +} + +async fn create_assistant_backed_conversation( + svc: &ConversationService, + user_id: &str, + conversation_type: &str, + backend: &str, + assistant_id: &str, +) -> ConversationResponse { + let workspace = ensure_test_workspace_path(); + let mut payload = json!({ + "type": conversation_type, + "name": "assistant conversation", + "extra": { + "workspace": workspace, + "backend": backend, + "assistant_id": assistant_id, + "assistant_locale": "en-US" + } + }); + + if conversation_type == "aionrs" { + payload["model"] = json!({ + "provider_id": "provider-1", + "model": "model-a", + "use_model": "model-a" + }); + } + + let req: CreateConversationRequest = serde_json::from_value(payload).unwrap(); + svc.create(user_id, req).await.unwrap() +} + async fn insert_conversation_with_type(repo: &Arc, user_id: &str, agent_type: AgentType) -> ConversationRow { let id = format!( "legacy-{}-{}", @@ -2227,6 +2375,360 @@ async fn set_model_returns_confirmed_model_even_if_get_model_is_stale() { assert_eq!(stale_model_info.current_model_id.as_deref(), Some("model-a")); } +#[tokio::test] +async fn set_model_updates_assistant_preference_only_when_snapshot_model_mode_is_auto() { + let task_mgr = Arc::new(MockTaskManager::new()); + let (svc, _broadcaster, _repo, definition_repo, overlay_repo, preference_repo) = + make_service_with_mock_task_manager_and_assistant_support(task_mgr.clone()).await; + + upsert_test_assistant_definition( + &definition_repo, + "asstdef_model_auto", + "assistant-model-auto", + "claude", + "auto", + "unset", + ) + .await; + overlay_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_model_auto", + enabled: true, + sort_order: 0, + agent_backend_override: None, + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_model_auto", + last_model_id: Some("legacy-model"), + last_permission_value: None, + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", + }) + .await + .unwrap(); + + let auto_conv = create_assistant_backed_conversation(&svc, "user_1", "acp", "claude", "assistant-model-auto").await; + task_mgr.insert_agent( + &auto_conv.id, + AgentInstance::Mock(Arc::new(MockAgent::new(&auto_conv.id))), + ); + + let response = svc + .set_model( + &auto_conv.id, + SetModelRequest { + model_id: "model-b".to_owned(), + }, + ) + .await + .unwrap(); + + assert_eq!( + response + .model_info + .as_ref() + .and_then(|info| info.current_model_id.as_deref()), + Some("model-b") + ); + let auto_pref = preference_repo.get("asstdef_model_auto").await.unwrap().unwrap(); + assert_eq!(auto_pref.last_model_id.as_deref(), Some("model-b")); + + upsert_test_assistant_definition( + &definition_repo, + "asstdef_model_fixed", + "assistant-model-fixed", + "claude", + "fixed", + "unset", + ) + .await; + overlay_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_model_fixed", + enabled: true, + sort_order: 0, + agent_backend_override: None, + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_model_fixed", + last_model_id: Some("legacy-fixed-model"), + last_permission_value: None, + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", + }) + .await + .unwrap(); + + let fixed_conv = + create_assistant_backed_conversation(&svc, "user_1", "acp", "claude", "assistant-model-fixed").await; + task_mgr.insert_agent( + &fixed_conv.id, + AgentInstance::Mock(Arc::new(MockAgent::new(&fixed_conv.id))), + ); + + let _ = svc + .set_model( + &fixed_conv.id, + SetModelRequest { + model_id: "model-c".to_owned(), + }, + ) + .await + .unwrap(); + + let fixed_pref = preference_repo.get("asstdef_model_fixed").await.unwrap().unwrap(); + assert_eq!(fixed_pref.last_model_id.as_deref(), Some("legacy-fixed-model")); +} + +#[tokio::test] +async fn set_mode_updates_assistant_preference_only_when_snapshot_permission_mode_is_auto() { + let task_mgr = Arc::new(MockTaskManager::new()); + let (svc, _broadcaster, _repo, definition_repo, overlay_repo, preference_repo) = + make_service_with_mock_task_manager_and_assistant_support(task_mgr.clone()).await; + + upsert_test_assistant_definition( + &definition_repo, + "asstdef_mode_auto", + "assistant-mode-auto", + "claude", + "unset", + "auto", + ) + .await; + overlay_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_mode_auto", + enabled: true, + sort_order: 0, + agent_backend_override: None, + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_mode_auto", + last_model_id: None, + last_permission_value: Some("legacy-mode"), + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", + }) + .await + .unwrap(); + + let auto_conv = create_assistant_backed_conversation(&svc, "user_1", "acp", "claude", "assistant-mode-auto").await; + task_mgr.insert_agent( + &auto_conv.id, + AgentInstance::Mock(Arc::new(MockAgent::new(&auto_conv.id))), + ); + + let response = svc + .set_mode( + &auto_conv.id, + SetModeRequest { + mode: "plan".to_owned(), + }, + ) + .await + .unwrap(); + + assert_eq!(response.mode, "plan"); + let auto_pref = preference_repo.get("asstdef_mode_auto").await.unwrap().unwrap(); + assert_eq!(auto_pref.last_permission_value.as_deref(), Some("plan")); + + upsert_test_assistant_definition( + &definition_repo, + "asstdef_mode_fixed", + "assistant-mode-fixed", + "claude", + "unset", + "fixed", + ) + .await; + overlay_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_mode_fixed", + enabled: true, + sort_order: 0, + agent_backend_override: None, + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_mode_fixed", + last_model_id: None, + last_permission_value: Some("legacy-fixed-mode"), + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", + }) + .await + .unwrap(); + + let fixed_conv = + create_assistant_backed_conversation(&svc, "user_1", "acp", "claude", "assistant-mode-fixed").await; + task_mgr.insert_agent( + &fixed_conv.id, + AgentInstance::Mock(Arc::new(MockAgent::new(&fixed_conv.id))), + ); + + let _ = svc + .set_mode( + &fixed_conv.id, + SetModeRequest { + mode: "acceptEdits".to_owned(), + }, + ) + .await + .unwrap(); + + let fixed_pref = preference_repo.get("asstdef_mode_fixed").await.unwrap().unwrap(); + assert_eq!(fixed_pref.last_permission_value.as_deref(), Some("legacy-fixed-mode")); +} + +#[tokio::test] +async fn update_aionrs_model_updates_assistant_preference_only_when_snapshot_model_mode_is_auto() { + let task_mgr = Arc::new(MockTaskManager::new()); + let (svc, _broadcaster, repo, definition_repo, overlay_repo, preference_repo) = + make_service_with_mock_task_manager_and_assistant_support(task_mgr.clone()).await; + + upsert_test_assistant_definition( + &definition_repo, + "asstdef_aionrs_auto", + "assistant-aionrs-auto", + "aionrs", + "auto", + "unset", + ) + .await; + overlay_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_aionrs_auto", + enabled: true, + sort_order: 0, + agent_backend_override: None, + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_aionrs_auto", + last_model_id: Some("legacy-aionrs-model"), + last_permission_value: None, + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", + }) + .await + .unwrap(); + + let auto_conv = + create_assistant_backed_conversation(&svc, "user_1", "aionrs", "aionrs", "assistant-aionrs-auto").await; + let updated = svc + .update( + "user_1", + &auto_conv.id, + UpdateConversationRequest { + model: Some(ProviderWithModel { + provider_id: "provider-2".to_owned(), + model: "model-z".to_owned(), + use_model: Some("model-z".to_owned()), + }), + name: None, + extra: None, + pinned: None, + }, + &(task_mgr.clone() as Arc), + ) + .await + .unwrap(); + + assert_eq!( + updated.model.as_ref().and_then(|model| model.use_model.as_deref()), + Some("model-z") + ); + let auto_pref = preference_repo.get("asstdef_aionrs_auto").await.unwrap().unwrap(); + assert_eq!(auto_pref.last_model_id.as_deref(), Some("model-z")); + + upsert_test_assistant_definition( + &definition_repo, + "asstdef_aionrs_fixed", + "assistant-aionrs-fixed", + "aionrs", + "fixed", + "unset", + ) + .await; + overlay_repo + .upsert(&UpsertAssistantOverlayParams { + definition_id: "asstdef_aionrs_fixed", + enabled: true, + sort_order: 0, + agent_backend_override: None, + last_used_at: None, + }) + .await + .unwrap(); + preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: "asstdef_aionrs_fixed", + last_model_id: Some("legacy-aionrs-fixed-model"), + last_permission_value: None, + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", + }) + .await + .unwrap(); + + let fixed_conv = + create_assistant_backed_conversation(&svc, "user_1", "aionrs", "aionrs", "assistant-aionrs-fixed").await; + let _ = svc + .update( + "user_1", + &fixed_conv.id, + UpdateConversationRequest { + model: Some(ProviderWithModel { + provider_id: "provider-3".to_owned(), + model: "model-y".to_owned(), + use_model: Some("model-y".to_owned()), + }), + name: None, + extra: None, + pinned: None, + }, + &(task_mgr as Arc), + ) + .await + .unwrap(); + + let fixed_pref = preference_repo.get("asstdef_aionrs_fixed").await.unwrap().unwrap(); + assert_eq!(fixed_pref.last_model_id.as_deref(), Some("legacy-aionrs-fixed-model")); + + // Ensure the update path used the repository row, not a no-op. + let updated_row = repo.get(&fixed_conv.id).await.unwrap().unwrap(); + assert!( + updated_row + .model + .as_deref() + .is_some_and(|model| model.contains("model-y")) + ); +} + #[tokio::test] async fn send_message_missing_workspace_persists_message_and_failure_tip() { let (svc, broadcaster, repo, _task_mgr) = make_service(); @@ -3392,7 +3894,7 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { let dispatcher = Arc::new(StaticAssistantDispatcher { rules: std::collections::HashMap::from([("preset-1".to_string(), "assistant rule body".to_string())]), }); - let (svc, _broadcaster, _repo, definition_repo, state_repo, preference_repo) = + let (svc, _broadcaster, repo, definition_repo, state_repo, preference_repo) = make_service_with_assistant_support(resolver, dispatcher).await; let workspace = ensure_test_workspace_path(); @@ -3475,11 +3977,17 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { assert_eq!(resp.extra["preset_context"], json!("assistant rule body")); assert_eq!(resp.extra["current_model_id"], json!("new-model")); assert_eq!(resp.extra["skills"], json!(["cron", "pdf"])); - assert_eq!(resp.extra["assistant_snapshot"]["agent_backend"], json!("codex")); - assert_eq!( - resp.extra["assistant_snapshot"]["resolved_defaults"]["skill_ids"], - json!(["pdf"]) - ); + assert!(resp.extra.get("assistant_snapshot").is_none()); + + let snapshot = repo.get_assistant_snapshot(&resp.id).await.unwrap().unwrap(); + assert_eq!(snapshot.assistant_definition_id, "asstdef_preset_1"); + assert_eq!(snapshot.assistant_key, "preset-1"); + assert_eq!(snapshot.agent_backend, "codex"); + assert_eq!(snapshot.rules_content, "assistant rule body"); + assert_eq!(snapshot.default_model_mode, "auto"); + assert_eq!(snapshot.resolved_model_id.as_deref(), Some("new-model")); + assert_eq!(snapshot.default_skills_mode, "auto"); + assert_eq!(snapshot.resolved_skill_ids, r#"["pdf"]"#); let updated_pref = preference_repo.get("asstdef_preset_1").await.unwrap().unwrap(); assert_eq!(updated_pref.last_model_id.as_deref(), Some("new-model")); @@ -3666,14 +4174,7 @@ async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() assert!(resp.extra.get("current_model_id").is_none()); assert!(resp.extra.get("permission_mode").is_none()); - assert_eq!( - resp.extra["assistant_snapshot"]["resolved_defaults"]["skill_ids"], - json!(["pdf"]) - ); - assert_eq!( - resp.extra["assistant_snapshot"]["resolved_defaults"]["mcp_ids"], - json!([]) - ); + assert!(resp.extra.get("assistant_snapshot").is_none()); let updated_pref = preference_repo.get("asstdef_preset_unset").await.unwrap().unwrap(); assert_eq!(updated_pref.last_model_id.as_deref(), Some("legacy-model")); diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql index dc4b6f7a..74fb8fe6 100644 --- a/crates/aionui-db/migrations/012_assistant_data_unification.sql +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -4,6 +4,7 @@ -- - assistant_definitions -- - assistant_overlays -- - assistant_preferences +-- - conversation_assistant_snapshots -- -- Legacy tables `assistants` and `assistant_overrides` are intentionally kept -- for downgrade compatibility and mirror projection. @@ -100,3 +101,43 @@ CREATE TABLE IF NOT EXISTS assistant_preferences ( updated_at INTEGER NOT NULL, FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE ); + +CREATE TABLE IF NOT EXISTS conversation_assistant_snapshots ( + conversation_id TEXT PRIMARY KEY, + assistant_definition_id TEXT NOT NULL, + assistant_key TEXT NOT NULL, + assistant_source TEXT NOT NULL, + assistant_name TEXT NOT NULL, + assistant_avatar_type TEXT NOT NULL DEFAULT 'none' + CHECK ( + assistant_avatar_type IN ( + 'none', + 'emoji', + 'builtin_asset', + 'user_asset' + ) + ), + assistant_avatar_value TEXT, + agent_backend TEXT NOT NULL, + rules_content TEXT NOT NULL DEFAULT '', + default_model_mode TEXT NOT NULL + CHECK (default_model_mode IN ('unset', 'auto', 'fixed')), + resolved_model_id TEXT, + default_permission_mode TEXT NOT NULL + CHECK (default_permission_mode IN ('unset', 'auto', 'fixed')), + resolved_permission_value TEXT, + default_skills_mode TEXT NOT NULL + CHECK (default_skills_mode IN ('auto', 'fixed')), + resolved_skill_ids TEXT NOT NULL DEFAULT '[]', + resolved_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', + default_mcps_mode TEXT NOT NULL + CHECK (default_mcps_mode IN ('unset', 'auto', 'fixed')), + resolved_mcp_ids TEXT NOT NULL DEFAULT '[]', + created_at INTEGER NOT NULL, + updated_at INTEGER NOT NULL, + FOREIGN KEY (conversation_id) REFERENCES conversations(id) ON DELETE CASCADE, + FOREIGN KEY (assistant_definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE +); + +CREATE INDEX IF NOT EXISTS idx_conversation_assistant_snapshots_assistant_definition_id + ON conversation_assistant_snapshots(assistant_definition_id); diff --git a/crates/aionui-db/src/database.rs b/crates/aionui-db/src/database.rs index 61c3caf0..5694a34e 100644 --- a/crates/aionui-db/src/database.rs +++ b/crates/aionui-db/src/database.rs @@ -7,7 +7,7 @@ use fs2::FileExt; use sqlx::migrate::Migrator; use sqlx::pool::PoolOptions; use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode}; -use sqlx::{Row, Sqlite, SqlitePool}; +use sqlx::{Sqlite, SqlitePool}; use tracing::{info, warn}; use crate::error::DbError; @@ -29,7 +29,6 @@ static DB_MIGRATOR: Migrator = sqlx::migrate!(); // Historical special-case for the MCP schema reconciliation fallback. // Keep this pinned to migration version 7 even as newer migrations land. const MCP_SCHEMA_RECONCILIATION_MIGRATION_VERSION: i64 = 7; -const ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION: i64 = 12; /// Wraps a SQLite connection pool with lifecycle management. #[derive(Clone, Debug)] @@ -371,21 +370,6 @@ async fn run_migrations_with_retry(conn: &mut sqlx::SqliteConnection) -> Result< ))) } } - Err(sqlx::migrate::MigrateError::VersionMismatch(version)) - if version == ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION => - { - if align_reconciled_assistant_migration_checksum(&mut *conn).await? { - warn!( - "Aligned checksum for reconciled assistant migration {}; retrying", - ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION - ); - DB_MIGRATOR.run(&mut *conn).await.map_err(DbError::Migration) - } else { - Err(DbError::Migration(sqlx::migrate::MigrateError::VersionMismatch( - version, - ))) - } - } Err(e) => Err(DbError::Migration(e)), } } @@ -440,7 +424,6 @@ impl Drop for MigrateLockGuard { /// safely adds any missing columns via `ALTER TABLE ADD COLUMN`. async fn ensure_schema_columns(pool: &SqlitePool) -> Result<(), DbError> { reconcile_mcp_server_schema(pool).await?; - reconcile_assistant_unification_schema(pool).await?; let expected: &[(&str, &str, &str)] = &[ ("cron_jobs", "skill_content", "TEXT"), @@ -478,28 +461,6 @@ async fn ensure_schema_columns(pool: &SqlitePool) -> Result<(), DbError> { Ok(()) } -async fn reconcile_assistant_unification_schema(pool: &SqlitePool) -> Result<(), DbError> { - let table_exists: bool = sqlx::query_scalar( - "SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='assistant_definitions'", - ) - .fetch_one(pool) - .await - .map_err(DbError::Query)?; - if !table_exists { - return Ok(()); - } - - let final_shape = assistant_unification_schema_is_final(pool).await?; - if final_shape { - return Ok(()); - } - - rebuild_legacy_assistant_unification_schema(pool).await?; - info!("Rebuilt assistant unification tables into final identity schema"); - - Ok(()) -} - async fn reconcile_mcp_server_schema(pool: &SqlitePool) -> Result<(), DbError> { let table_exists: bool = sqlx::query_scalar("SELECT COUNT(*) > 0 FROM sqlite_master WHERE type='table' AND name='mcp_servers'") @@ -652,600 +613,6 @@ async fn align_reconciled_mcp_migration_checksum(conn: &mut sqlx::SqliteConnecti Ok(updated.rows_affected() > 0) } -async fn align_reconciled_assistant_migration_checksum(conn: &mut sqlx::SqliteConnection) -> Result { - if !assistant_unification_schema_is_final_conn(conn).await? { - return Ok(false); - } - - let Some(migration) = DB_MIGRATOR - .iter() - .find(|migration| migration.version == ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION) - else { - return Ok(false); - }; - - let updated = sqlx::query("UPDATE _sqlx_migrations SET checksum = ? WHERE version = ?") - .bind(&*migration.checksum) - .bind(ASSISTANT_SCHEMA_RECONCILIATION_MIGRATION_VERSION) - .execute(&mut *conn) - .await - .map_err(DbError::Query)?; - - Ok(updated.rows_affected() > 0) -} - -async fn assistant_unification_schema_is_final(pool: &SqlitePool) -> Result { - let has_definition_id = table_has_column(pool, "assistant_definitions", "definition_id").await?; - let has_assistant_key = table_has_column(pool, "assistant_definitions", "assistant_key").await?; - let has_avatar_type = table_has_column(pool, "assistant_definitions", "avatar_type").await?; - let has_avatar_value = table_has_column(pool, "assistant_definitions", "avatar_value").await?; - let state_uses_definition_id = table_has_column(pool, "assistant_overlays", "definition_id").await?; - let preference_uses_definition_id = table_has_column(pool, "assistant_preferences", "definition_id").await?; - let scalar_default_modes_support_unset = assistant_definition_scalar_default_modes_support_unset(pool).await?; - - Ok(has_definition_id - && has_assistant_key - && has_avatar_type - && has_avatar_value - && state_uses_definition_id - && preference_uses_definition_id - && scalar_default_modes_support_unset) -} - -async fn table_exists(pool: &SqlitePool, table: &str) -> Result { - sqlx::query_scalar("SELECT COUNT(*) > 0 FROM sqlite_master WHERE type = 'table' AND name = ?") - .bind(table) - .fetch_one(pool) - .await - .map_err(DbError::Query) -} - -async fn table_has_column(pool: &SqlitePool, table: &str, column: &str) -> Result { - sqlx::query_scalar("SELECT COUNT(*) > 0 FROM pragma_table_info(?) WHERE name = ?") - .bind(table) - .bind(column) - .fetch_one(pool) - .await - .map_err(DbError::Query) -} - -async fn assistant_unification_schema_is_final_conn(conn: &mut sqlx::SqliteConnection) -> Result { - let has_definition_id = table_has_column_conn(conn, "assistant_definitions", "definition_id").await?; - let has_assistant_key = table_has_column_conn(conn, "assistant_definitions", "assistant_key").await?; - let has_avatar_type = table_has_column_conn(conn, "assistant_definitions", "avatar_type").await?; - let has_avatar_value = table_has_column_conn(conn, "assistant_definitions", "avatar_value").await?; - let state_uses_definition_id = table_has_column_conn(conn, "assistant_overlays", "definition_id").await?; - let preference_uses_definition_id = table_has_column_conn(conn, "assistant_preferences", "definition_id").await?; - let scalar_default_modes_support_unset = assistant_definition_scalar_default_modes_support_unset_conn(conn).await?; - - Ok(has_definition_id - && has_assistant_key - && has_avatar_type - && has_avatar_value - && state_uses_definition_id - && preference_uses_definition_id - && scalar_default_modes_support_unset) -} - -async fn table_has_column_conn(conn: &mut sqlx::SqliteConnection, table: &str, column: &str) -> Result { - sqlx::query_scalar("SELECT COUNT(*) > 0 FROM pragma_table_info(?) WHERE name = ?") - .bind(table) - .bind(column) - .fetch_one(&mut *conn) - .await - .map_err(DbError::Query) -} - -async fn assistant_definition_scalar_default_modes_support_unset(pool: &SqlitePool) -> Result { - let table_sql: Option = - sqlx::query_scalar("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'assistant_definitions'") - .fetch_one(pool) - .await - .map_err(DbError::Query)?; - Ok(table_sql - .as_deref() - .map(assistant_definition_sql_supports_unset_defaults) - .unwrap_or(false)) -} - -async fn assistant_definition_scalar_default_modes_support_unset_conn( - conn: &mut sqlx::SqliteConnection, -) -> Result { - let table_sql: Option = - sqlx::query_scalar("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'assistant_definitions'") - .fetch_one(&mut *conn) - .await - .map_err(DbError::Query)?; - Ok(table_sql - .as_deref() - .map(assistant_definition_sql_supports_unset_defaults) - .unwrap_or(false)) -} - -fn assistant_definition_sql_supports_unset_defaults(table_sql: &str) -> bool { - let normalized = table_sql.to_ascii_lowercase().replace(char::is_whitespace, ""); - normalized.contains("default_model_mode") - && normalized.contains("default_permission_mode") - && normalized.contains("default_mcps_mode") - && normalized.contains("('unset','auto','fixed')") -} - -async fn rebuild_legacy_assistant_unification_schema(pool: &SqlitePool) -> Result<(), DbError> { - let overlay_table = if table_exists(pool, "assistant_overlays").await? { - "assistant_overlays" - } else if table_exists(pool, "assistant_states").await? { - "assistant_states" - } else { - return Err(DbError::Init( - "assistant schema repair failed: neither assistant_overlays nor assistant_states exists".into(), - )); - }; - let definitions_use_internal_identity = table_has_column(pool, "assistant_definitions", "definition_id").await?; - let overlays_use_definition_id = table_has_column(pool, overlay_table, "definition_id").await?; - let preferences_use_definition_id = table_has_column(pool, "assistant_preferences", "definition_id").await?; - - let definition_rows = if definitions_use_internal_identity { - sqlx::query( - "SELECT definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar_type, avatar_value, - agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, - recommended_prompts, recommended_prompts_i18n, - default_model_mode, default_model_value, - default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, - default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - FROM assistant_definitions", - ) - .fetch_all(pool) - .await - .map_err(DbError::Query)? - } else { - sqlx::query( - "SELECT id, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar, - agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, - recommended_prompts, recommended_prompts_i18n, - default_model_mode, default_model_value, - default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, - default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - FROM assistant_definitions", - ) - .fetch_all(pool) - .await - .map_err(DbError::Query)? - }; - - let state_rows = sqlx::query(&format!( - "SELECT {} AS overlay_key, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at - FROM {overlay_table}", - if overlays_use_definition_id { - "definition_id" - } else { - "assistant_id" - } - )) - .fetch_all(pool) - .await - .map_err(DbError::Query)?; - - let preference_rows = sqlx::query(&format!( - "SELECT {} AS preference_key, last_model_id, last_permission_value, last_skill_ids, - last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at - FROM assistant_preferences", - if preferences_use_definition_id { - "definition_id" - } else { - "assistant_id" - } - )) - .fetch_all(pool) - .await - .map_err(DbError::Query)?; - - let mut definition_id_map = std::collections::HashMap::new(); - let mut definitions = Vec::with_capacity(definition_rows.len()); - for row in definition_rows { - if definitions_use_internal_identity { - let source: String = row.get("source"); - let owner_type: String = row.get("owner_type"); - if source == "extension" || owner_type == "extension" { - continue; - } - let definition_id: String = row.get("definition_id"); - let assistant_key: String = row.get("assistant_key"); - definition_id_map.insert(assistant_key.clone(), definition_id.clone()); - definitions.push(( - definition_id, - assistant_key, - source, - owner_type, - row.get::, _>("source_ref"), - row.get::, _>("source_version"), - row.get::, _>("source_hash"), - row.get::("name"), - row.get::("name_i18n"), - row.get::, _>("description"), - row.get::("description_i18n"), - row.get::("avatar_type"), - row.get::, _>("avatar_value"), - row.get::("agent_backend"), - row.get::("rule_resource_type"), - row.get::, _>("rule_resource_ref"), - row.get::, _>("rule_inline_content"), - row.get::("recommended_prompts"), - row.get::("recommended_prompts_i18n"), - row.get::("default_model_mode"), - row.get::, _>("default_model_value"), - row.get::("default_permission_mode"), - row.get::, _>("default_permission_value"), - row.get::("default_skills_mode"), - row.get::("default_skill_ids"), - row.get::("custom_skill_names"), - row.get::("default_disabled_builtin_skill_ids"), - row.get::("default_mcps_mode"), - row.get::("default_mcp_ids"), - row.get::("created_at"), - row.get::("updated_at"), - row.get::, _>("deleted_at"), - )); - } else { - let source: String = row.get("source"); - let owner_type: String = row.get("owner_type"); - if source == "extension" || owner_type == "extension" { - continue; - } - let assistant_key: String = row.get("id"); - let avatar: Option = row.get("avatar"); - let definition_id = aionui_common::generate_prefixed_id("asstdef"); - let (avatar_type, avatar_value) = infer_avatar_storage(&source, avatar.as_deref()); - definition_id_map.insert(assistant_key.clone(), definition_id.clone()); - definitions.push(( - definition_id, - assistant_key, - source, - owner_type, - row.get::, _>("source_ref"), - row.get::, _>("source_version"), - row.get::, _>("source_hash"), - row.get::("name"), - row.get::("name_i18n"), - row.get::, _>("description"), - row.get::("description_i18n"), - avatar_type, - avatar_value, - row.get::("agent_backend"), - row.get::("rule_resource_type"), - row.get::, _>("rule_resource_ref"), - row.get::, _>("rule_inline_content"), - row.get::("recommended_prompts"), - row.get::("recommended_prompts_i18n"), - row.get::("default_model_mode"), - row.get::, _>("default_model_value"), - row.get::("default_permission_mode"), - row.get::, _>("default_permission_value"), - row.get::("default_skills_mode"), - row.get::("default_skill_ids"), - row.get::("custom_skill_names"), - row.get::("default_disabled_builtin_skill_ids"), - row.get::("default_mcps_mode"), - row.get::("default_mcp_ids"), - row.get::("created_at"), - row.get::("updated_at"), - row.get::, _>("deleted_at"), - )); - } - } - - let mut tx = pool.begin().await.map_err(DbError::Query)?; - sqlx::query("PRAGMA foreign_keys = OFF") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - - for table in [ - "_assistant_definitions_legacy_v12", - "_assistant_overlays_legacy_v12", - "_assistant_preferences_legacy_v12", - ] { - sqlx::query(&format!("DROP TABLE IF EXISTS {table}")) - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - } - - sqlx::query("ALTER TABLE assistant_definitions RENAME TO _assistant_definitions_legacy_v12") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - sqlx::query(&format!( - "ALTER TABLE {overlay_table} RENAME TO _assistant_overlays_legacy_v12" - )) - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - sqlx::query("ALTER TABLE assistant_preferences RENAME TO _assistant_preferences_legacy_v12") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - - for index in [ - "idx_assistant_definitions_source_ref", - "idx_assistant_definitions_assistant_key", - "idx_assistant_definitions_source", - "idx_assistant_definitions_agent_backend", - "idx_assistant_states_enabled", - "idx_assistant_states_sort_order", - "idx_assistant_overlays_enabled", - "idx_assistant_overlays_sort_order", - ] { - sqlx::query(&format!("DROP INDEX IF EXISTS {index}")) - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - } - - create_final_assistant_unification_tables(&mut tx).await?; - - for row in &definitions { - sqlx::query( - "INSERT INTO assistant_definitions ( - definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar_type, avatar_value, - agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, - recommended_prompts, recommended_prompts_i18n, - default_model_mode, default_model_value, default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, - default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ) - .bind(&row.0) - .bind(&row.1) - .bind(&row.2) - .bind(&row.3) - .bind(&row.4) - .bind(&row.5) - .bind(&row.6) - .bind(&row.7) - .bind(&row.8) - .bind(&row.9) - .bind(&row.10) - .bind(&row.11) - .bind(&row.12) - .bind(&row.13) - .bind(&row.14) - .bind(&row.15) - .bind(&row.16) - .bind(&row.17) - .bind(&row.18) - .bind(&row.19) - .bind(&row.20) - .bind(&row.21) - .bind(&row.22) - .bind(&row.23) - .bind(&row.24) - .bind(&row.25) - .bind(&row.26) - .bind(&row.27) - .bind(&row.28) - .bind(row.29) - .bind(row.30) - .bind(row.31) - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - } - - for row in state_rows { - let overlay_key: String = row.get("overlay_key"); - let definition_id = if overlays_use_definition_id { - overlay_key - } else { - let Some(definition_id) = definition_id_map.get(&overlay_key) else { - continue; - }; - definition_id.clone() - }; - sqlx::query( - "INSERT INTO assistant_overlays ( - definition_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at - ) VALUES (?, ?, ?, ?, ?, ?, ?)", - ) - .bind(definition_id) - .bind(row.get::("enabled")) - .bind(row.get::("sort_order")) - .bind(row.get::, _>("agent_backend_override")) - .bind(row.get::, _>("last_used_at")) - .bind(row.get::("created_at")) - .bind(row.get::("updated_at")) - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - } - - for row in preference_rows { - let preference_key: String = row.get("preference_key"); - let definition_id = if preferences_use_definition_id { - preference_key - } else { - let Some(definition_id) = definition_id_map.get(&preference_key) else { - continue; - }; - definition_id.clone() - }; - sqlx::query( - "INSERT INTO assistant_preferences ( - definition_id, last_model_id, last_permission_value, last_skill_ids, - last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", - ) - .bind(definition_id) - .bind(row.get::, _>("last_model_id")) - .bind(row.get::, _>("last_permission_value")) - .bind(row.get::("last_skill_ids")) - .bind(row.get::("last_disabled_builtin_skill_ids")) - .bind(row.get::("last_mcp_ids")) - .bind(row.get::("created_at")) - .bind(row.get::("updated_at")) - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - } - - sqlx::query("DROP TABLE _assistant_definitions_legacy_v12") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - sqlx::query("DROP TABLE _assistant_overlays_legacy_v12") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - sqlx::query("DROP TABLE _assistant_preferences_legacy_v12") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - - sqlx::query("PRAGMA foreign_keys = ON") - .execute(&mut *tx) - .await - .map_err(DbError::Query)?; - tx.commit().await.map_err(DbError::Query)?; - Ok(()) -} - -async fn create_final_assistant_unification_tables(tx: &mut sqlx::Transaction<'_, Sqlite>) -> Result<(), DbError> { - sqlx::query( - "CREATE TABLE assistant_definitions ( - definition_id TEXT PRIMARY KEY, - assistant_key TEXT NOT NULL, - source TEXT NOT NULL - CHECK (source IN ('builtin', 'user', 'generated')), - owner_type TEXT NOT NULL - CHECK (owner_type IN ('system', 'user')), - source_ref TEXT, - source_version TEXT, - source_hash TEXT, - name TEXT NOT NULL, - name_i18n TEXT NOT NULL DEFAULT '{}', - description TEXT, - description_i18n TEXT NOT NULL DEFAULT '{}', - avatar_type TEXT NOT NULL DEFAULT 'none' - CHECK (avatar_type IN ('none', 'emoji', 'builtin_asset', 'user_asset')), - avatar_value TEXT, - agent_backend TEXT NOT NULL, - rule_resource_type TEXT NOT NULL - CHECK (rule_resource_type IN ('none', 'builtin_asset', 'user_file', 'inline', 'extension')), - rule_resource_ref TEXT, - rule_inline_content TEXT, - recommended_prompts TEXT NOT NULL DEFAULT '[]', - recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', - default_model_mode TEXT NOT NULL CHECK (default_model_mode IN ('unset', 'auto', 'fixed')), - default_model_value TEXT, - default_permission_mode TEXT NOT NULL CHECK (default_permission_mode IN ('unset', 'auto', 'fixed')), - default_permission_value TEXT, - default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), - default_skill_ids TEXT NOT NULL DEFAULT '[]', - custom_skill_names TEXT NOT NULL DEFAULT '[]', - default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - default_mcps_mode TEXT NOT NULL CHECK (default_mcps_mode IN ('unset', 'auto', 'fixed')), - default_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - deleted_at INTEGER - )", - ) - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - sqlx::query( - "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref - ON assistant_definitions(source, source_ref) - WHERE source_ref IS NOT NULL", - ) - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - sqlx::query( - "CREATE UNIQUE INDEX idx_assistant_definitions_assistant_key - ON assistant_definitions(assistant_key)", - ) - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - - sqlx::query( - "CREATE TABLE assistant_overlays ( - definition_id TEXT PRIMARY KEY, - enabled INTEGER NOT NULL DEFAULT 1, - sort_order INTEGER NOT NULL DEFAULT 0, - agent_backend_override TEXT, - last_used_at INTEGER, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE - )", - ) - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - sqlx::query("CREATE INDEX idx_assistant_overlays_enabled ON assistant_overlays(enabled)") - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - sqlx::query("CREATE INDEX idx_assistant_overlays_sort_order ON assistant_overlays(sort_order)") - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - - sqlx::query( - "CREATE TABLE assistant_preferences ( - definition_id TEXT PRIMARY KEY, - last_model_id TEXT, - last_permission_value TEXT, - last_skill_ids TEXT NOT NULL DEFAULT '[]', - last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - last_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - FOREIGN KEY (definition_id) REFERENCES assistant_definitions(definition_id) ON DELETE CASCADE - )", - ) - .execute(&mut **tx) - .await - .map_err(DbError::Query)?; - - Ok(()) -} - -fn infer_avatar_storage(source: &str, avatar: Option<&str>) -> (String, Option) { - let Some(value) = avatar.map(str::trim).filter(|value| !value.is_empty()) else { - return ("none".to_string(), None); - }; - - let avatar_type = if looks_like_avatar_asset(value) { - match source { - "builtin" => "builtin_asset", - _ => "user_asset", - } - } else { - "emoji" - }; - - (avatar_type.to_string(), Some(value.to_string())) -} - -fn looks_like_avatar_asset(value: &str) -> bool { - value.contains('/') || (Path::new(value).extension().is_some() && !value.starts_with('.')) -} - /// Ensure the system default user exists. /// /// Uses INSERT OR IGNORE so it is safe to call on every startup. diff --git a/crates/aionui-db/src/lib.rs b/crates/aionui-db/src/lib.rs index 12ca8c06..0717f059 100644 --- a/crates/aionui-db/src/lib.rs +++ b/crates/aionui-db/src/lib.rs @@ -12,9 +12,10 @@ pub use database::{ pub use error::DbError; pub use models::{ AgentMetadataRow, AssistantDefinitionRow, AssistantOverlayRow, AssistantOverrideRow, AssistantPreferenceRow, - AssistantRow, ConversationArtifactRow, CreateAssistantParams, UpdateAgentHandshakeParams, UpdateAssistantParams, - UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, UpsertAssistantOverlayParams, - UpsertAssistantPreferenceParams, UpsertOverrideParams, + AssistantRow, ConversationArtifactRow, ConversationAssistantSnapshotRow, CreateAssistantParams, + UpdateAgentHandshakeParams, UpdateAssistantParams, UpsertAgentMetadataParams, UpsertAssistantDefinitionParams, + UpsertAssistantOverlayParams, UpsertAssistantPreferenceParams, UpsertConversationAssistantSnapshotParams, + UpsertOverrideParams, }; pub use repository::channel::UpdatePluginStatusParams; pub use repository::conversation::{ diff --git a/crates/aionui-db/src/models/conversation.rs b/crates/aionui-db/src/models/conversation.rs index 687a4322..b73c35c1 100644 --- a/crates/aionui-db/src/models/conversation.rs +++ b/crates/aionui-db/src/models/conversation.rs @@ -33,3 +33,51 @@ pub struct ConversationRow { pub created_at: TimestampMs, pub updated_at: TimestampMs, } + +/// Row mapping for the `conversation_assistant_snapshots` table. +#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)] +pub struct ConversationAssistantSnapshotRow { + pub conversation_id: String, + pub assistant_definition_id: String, + pub assistant_key: String, + pub assistant_source: String, + pub assistant_name: String, + pub assistant_avatar_type: String, + pub assistant_avatar_value: Option, + pub agent_backend: String, + pub rules_content: String, + pub default_model_mode: String, + pub resolved_model_id: Option, + pub default_permission_mode: String, + pub resolved_permission_value: Option, + pub default_skills_mode: String, + pub resolved_skill_ids: String, + pub resolved_disabled_builtin_skill_ids: String, + pub default_mcps_mode: String, + pub resolved_mcp_ids: String, + pub created_at: TimestampMs, + pub updated_at: TimestampMs, +} + +/// Insert-or-update parameters for `conversation_assistant_snapshots`. +#[derive(Debug, Clone)] +pub struct UpsertConversationAssistantSnapshotParams<'a> { + pub conversation_id: &'a str, + pub assistant_definition_id: &'a str, + pub assistant_key: &'a str, + pub assistant_source: &'a str, + pub assistant_name: &'a str, + pub assistant_avatar_type: &'a str, + pub assistant_avatar_value: Option<&'a str>, + pub agent_backend: &'a str, + pub rules_content: &'a str, + pub default_model_mode: &'a str, + pub resolved_model_id: Option<&'a str>, + pub default_permission_mode: &'a str, + pub resolved_permission_value: Option<&'a str>, + pub default_skills_mode: &'a str, + pub resolved_skill_ids: &'a str, + pub resolved_disabled_builtin_skill_ids: &'a str, + pub default_mcps_mode: &'a str, + pub resolved_mcp_ids: &'a str, +} diff --git a/crates/aionui-db/src/models/mod.rs b/crates/aionui-db/src/models/mod.rs index f7ccf5f5..79573e64 100644 --- a/crates/aionui-db/src/models/mod.rs +++ b/crates/aionui-db/src/models/mod.rs @@ -24,7 +24,7 @@ pub use assistant::{ }; pub use channel::{AssistantSessionRow, AssistantUserRow, ChannelPluginRow, PairingCodeRow}; pub use client_preference::ClientPreference; -pub use conversation::ConversationRow; +pub use conversation::{ConversationAssistantSnapshotRow, ConversationRow, UpsertConversationAssistantSnapshotParams}; pub use conversation_artifact::ConversationArtifactRow; pub use cron_job::CronJobRow; pub use mcp_server::McpServerRow; diff --git a/crates/aionui-db/src/repository/conversation.rs b/crates/aionui-db/src/repository/conversation.rs index 901f2b85..4f00f061 100644 --- a/crates/aionui-db/src/repository/conversation.rs +++ b/crates/aionui-db/src/repository/conversation.rs @@ -2,7 +2,10 @@ use aionui_common::{PaginatedResult, TimestampMs}; use serde::{Deserialize, Serialize}; use crate::error::DbError; -use crate::models::{ConversationArtifactRow, ConversationRow, MessageRow}; +use crate::models::{ + ConversationArtifactRow, ConversationAssistantSnapshotRow, ConversationRow, MessageRow, + UpsertConversationAssistantSnapshotParams, +}; /// Conversation + message data access abstraction. /// @@ -53,6 +56,27 @@ pub trait IConversationRepository: Send + Sync { /// The conversation identified by `conversation_id` is excluded. async fn list_associated(&self, user_id: &str, conversation_id: &str) -> Result, DbError>; + /// Returns the persisted assistant snapshot for a conversation, if any. + async fn get_assistant_snapshot( + &self, + _conversation_id: &str, + ) -> Result, DbError> { + Ok(None) + } + + /// Inserts or updates a persisted assistant snapshot for a conversation. + async fn upsert_assistant_snapshot( + &self, + _params: &UpsertConversationAssistantSnapshotParams<'_>, + ) -> Result, DbError> { + Ok(None) + } + + /// Deletes the assistant snapshot bound to a conversation. + async fn delete_assistant_snapshot(&self, _conversation_id: &str) -> Result { + Ok(false) + } + // ── Message operations ────────────────────────────────────────── /// Returns paginated messages for a conversation, ordered by `created_at`. diff --git a/crates/aionui-db/src/repository/sqlite_conversation.rs b/crates/aionui-db/src/repository/sqlite_conversation.rs index 21bc4915..f1ea2b7e 100644 --- a/crates/aionui-db/src/repository/sqlite_conversation.rs +++ b/crates/aionui-db/src/repository/sqlite_conversation.rs @@ -3,7 +3,10 @@ use sqlx::SqlitePool; use aionui_common::PaginatedResult; use crate::error::DbError; -use crate::models::{ConversationArtifactRow, ConversationRow, MessageRow}; +use crate::models::{ + ConversationArtifactRow, ConversationAssistantSnapshotRow, ConversationRow, MessageRow, + UpsertConversationAssistantSnapshotParams, +}; use crate::repository::conversation::{ ConversationFilters, ConversationRowUpdate, IConversationRepository, MessageRowUpdate, MessageSearchRow, SortOrder, }; @@ -268,6 +271,103 @@ impl IConversationRepository for SqliteConversationRepository { Ok(rows) } + async fn get_assistant_snapshot( + &self, + conversation_id: &str, + ) -> Result, DbError> { + let row = sqlx::query_as::<_, ConversationAssistantSnapshotRow>( + "SELECT * FROM conversation_assistant_snapshots WHERE conversation_id = ?", + ) + .bind(conversation_id) + .fetch_optional(&self.pool) + .await?; + + Ok(row) + } + + async fn upsert_assistant_snapshot( + &self, + params: &UpsertConversationAssistantSnapshotParams<'_>, + ) -> Result, DbError> { + let now = aionui_common::now_ms(); + sqlx::query( + "INSERT INTO conversation_assistant_snapshots ( + conversation_id, + assistant_definition_id, + assistant_key, + assistant_source, + assistant_name, + assistant_avatar_type, + assistant_avatar_value, + agent_backend, + rules_content, + default_model_mode, + resolved_model_id, + default_permission_mode, + resolved_permission_value, + default_skills_mode, + resolved_skill_ids, + resolved_disabled_builtin_skill_ids, + default_mcps_mode, + resolved_mcp_ids, + created_at, + updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(conversation_id) DO UPDATE SET + assistant_definition_id = excluded.assistant_definition_id, + assistant_key = excluded.assistant_key, + assistant_source = excluded.assistant_source, + assistant_name = excluded.assistant_name, + assistant_avatar_type = excluded.assistant_avatar_type, + assistant_avatar_value = excluded.assistant_avatar_value, + agent_backend = excluded.agent_backend, + rules_content = excluded.rules_content, + default_model_mode = excluded.default_model_mode, + resolved_model_id = excluded.resolved_model_id, + default_permission_mode = excluded.default_permission_mode, + resolved_permission_value = excluded.resolved_permission_value, + default_skills_mode = excluded.default_skills_mode, + resolved_skill_ids = excluded.resolved_skill_ids, + resolved_disabled_builtin_skill_ids = excluded.resolved_disabled_builtin_skill_ids, + default_mcps_mode = excluded.default_mcps_mode, + resolved_mcp_ids = excluded.resolved_mcp_ids, + updated_at = excluded.updated_at", + ) + .bind(params.conversation_id) + .bind(params.assistant_definition_id) + .bind(params.assistant_key) + .bind(params.assistant_source) + .bind(params.assistant_name) + .bind(params.assistant_avatar_type) + .bind(params.assistant_avatar_value) + .bind(params.agent_backend) + .bind(params.rules_content) + .bind(params.default_model_mode) + .bind(params.resolved_model_id) + .bind(params.default_permission_mode) + .bind(params.resolved_permission_value) + .bind(params.default_skills_mode) + .bind(params.resolved_skill_ids) + .bind(params.resolved_disabled_builtin_skill_ids) + .bind(params.default_mcps_mode) + .bind(params.resolved_mcp_ids) + .bind(now) + .bind(now) + .execute(&self.pool) + .await?; + + self.get_assistant_snapshot(params.conversation_id).await + } + + async fn delete_assistant_snapshot(&self, conversation_id: &str) -> Result { + let result = sqlx::query("DELETE FROM conversation_assistant_snapshots WHERE conversation_id = ?") + .bind(conversation_id) + .execute(&self.pool) + .await?; + + Ok(result.rows_affected() > 0) + } + // ── Message operations ────────────────────────────────────────── async fn get_messages( diff --git a/crates/aionui-db/tests/assistant_data_unification_schema.rs b/crates/aionui-db/tests/assistant_data_unification_schema.rs index ed76e32d..f500dce2 100644 --- a/crates/aionui-db/tests/assistant_data_unification_schema.rs +++ b/crates/aionui-db/tests/assistant_data_unification_schema.rs @@ -9,6 +9,7 @@ async fn migration_creates_assistant_unification_tables_and_keeps_legacy_tables( 'assistant_definitions', 'assistant_overlays', 'assistant_preferences', + 'conversation_assistant_snapshots', 'assistants', 'assistant_overrides' ) ORDER BY name", @@ -25,6 +26,7 @@ async fn migration_creates_assistant_unification_tables_and_keeps_legacy_tables( "assistant_overrides".to_string(), "assistant_preferences".to_string(), "assistants".to_string(), + "conversation_assistant_snapshots".to_string(), ] ); } @@ -64,6 +66,19 @@ async fn assistant_definition_table_has_expected_default_columns() { .await .unwrap_or_default(); assert!(preference_columns.iter().any(|name| name == "definition_id")); + + let snapshot_columns: Vec = + sqlx::query_scalar("SELECT name FROM pragma_table_info('conversation_assistant_snapshots')") + .fetch_all(db.pool()) + .await + .unwrap_or_default(); + assert!(snapshot_columns.iter().any(|name| name == "conversation_id")); + assert!(snapshot_columns.iter().any(|name| name == "assistant_definition_id")); + assert!(snapshot_columns.iter().any(|name| name == "assistant_key")); + assert!(snapshot_columns.iter().any(|name| name == "default_model_mode")); + assert!(snapshot_columns.iter().any(|name| name == "resolved_model_id")); + assert!(snapshot_columns.iter().any(|name| name == "resolved_skill_ids")); + assert!(snapshot_columns.iter().any(|name| name == "resolved_mcp_ids")); } #[tokio::test] diff --git a/crates/aionui-db/tests/db_lifecycle.rs b/crates/aionui-db/tests/db_lifecycle.rs index 19beaf6e..675cd404 100644 --- a/crates/aionui-db/tests/db_lifecycle.rs +++ b/crates/aionui-db/tests/db_lifecycle.rs @@ -2,23 +2,6 @@ use std::time::Duration; use aionui_db::{init_database, init_database_memory, maybe_copy_legacy_database}; use sqlx::Row; -use sqlx::pool::PoolOptions; -use sqlx::sqlite::{SqliteConnectOptions, SqliteJournalMode}; - -async fn open_file_pool(path: &std::path::Path) -> sqlx::SqlitePool { - PoolOptions::::new() - .max_connections(1) - .connect_with( - SqliteConnectOptions::new() - .filename(path) - .create_if_missing(false) - .foreign_keys(true) - .busy_timeout(Duration::from_millis(5000)) - .journal_mode(SqliteJournalMode::Wal), - ) - .await - .unwrap() -} // -- T1.1 Initialization -- @@ -110,556 +93,6 @@ async fn idempotent_reinit_preserves_data() { db.close().await; } -#[tokio::test] -async fn idempotent_reinit_recovers_assistant_unification_checksum_mismatch() { - let dir = tempfile::tempdir().unwrap(); - let path = dir.path().join("test.db"); - - let db = init_database(&path).await.unwrap(); - db.close().await; - - let pool = PoolOptions::::new() - .max_connections(1) - .connect_with( - SqliteConnectOptions::new() - .filename(&path) - .create_if_missing(false) - .foreign_keys(true) - .busy_timeout(Duration::from_millis(5000)) - .journal_mode(SqliteJournalMode::Wal), - ) - .await - .unwrap(); - sqlx::query("UPDATE _sqlx_migrations SET checksum = x'00' WHERE version = 12") - .execute(&pool) - .await - .unwrap(); - pool.close().await; - - let db = init_database(&path).await.unwrap(); - let checksum: Vec = sqlx::query_scalar("SELECT checksum FROM _sqlx_migrations WHERE version = 12") - .fetch_one(db.pool()) - .await - .unwrap(); - assert_ne!(checksum, vec![0]); - db.close().await; -} - -#[tokio::test] -async fn idempotent_reinit_repairs_legacy_assistant_unification_tables() { - let dir = tempfile::tempdir().unwrap(); - let path = dir.path().join("test.db"); - - let db = init_database(&path).await.unwrap(); - db.close().await; - - let pool = open_file_pool(&path).await; - sqlx::query("PRAGMA foreign_keys = OFF").execute(&pool).await.unwrap(); - sqlx::query("DROP TABLE assistant_preferences") - .execute(&pool) - .await - .unwrap(); - sqlx::query("DROP TABLE assistant_overlays") - .execute(&pool) - .await - .unwrap(); - sqlx::query("DROP TABLE assistant_definitions") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - r#" -CREATE TABLE assistant_definitions ( - id TEXT PRIMARY KEY, - source TEXT NOT NULL, - owner_type TEXT NOT NULL, - source_ref TEXT, - source_version TEXT, - source_hash TEXT, - name TEXT NOT NULL, - name_i18n TEXT NOT NULL DEFAULT '{}', - description TEXT, - description_i18n TEXT NOT NULL DEFAULT '{}', - avatar TEXT, - agent_backend TEXT NOT NULL, - rule_resource_type TEXT NOT NULL, - rule_resource_ref TEXT, - rule_inline_content TEXT, - recommended_prompts TEXT NOT NULL DEFAULT '[]', - recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', - default_model_mode TEXT NOT NULL, - default_model_value TEXT, - default_permission_mode TEXT NOT NULL, - default_permission_value TEXT, - default_skills_mode TEXT NOT NULL, - default_skill_ids TEXT NOT NULL DEFAULT '[]', - custom_skill_names TEXT NOT NULL DEFAULT '[]', - default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - default_mcps_mode TEXT NOT NULL, - default_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - deleted_at INTEGER -) - "#, - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref - ON assistant_definitions(source, source_ref) - WHERE source_ref IS NOT NULL", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE TABLE assistant_states ( - assistant_id TEXT PRIMARY KEY, - enabled INTEGER NOT NULL DEFAULT 1, - sort_order INTEGER NOT NULL DEFAULT 0, - agent_backend_override TEXT, - last_used_at INTEGER, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE TABLE assistant_preferences ( - assistant_id TEXT PRIMARY KEY, - last_model_id TEXT, - last_permission_value TEXT, - last_skill_ids TEXT NOT NULL DEFAULT '[]', - last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - last_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_definitions ( - id, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar, - agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, - recommended_prompts, recommended_prompts_i18n, - default_model_mode, default_model_value, - default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, - default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - ) VALUES ( - 'u1', 'user', 'user', 'u1', NULL, NULL, - 'Mine', '{}', 'desc', '{}', '🤖', - 'aionrs', 'user_file', 'u1', NULL, - '[\"hello\"]', '{}', - 'auto', NULL, - 'auto', NULL, - 'fixed', '[\"pdf\"]', '[]', '[]', - 'auto', '[]', 1, 2, NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_states (assistant_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at) - VALUES ('u1', 0, 7, 'codex', 1234, 1, 2)", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_preferences (assistant_id, last_model_id, last_permission_value, last_skill_ids, - last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at) - VALUES ('u1', 'gpt-4.1', 'workspace-write', '[\"pdf\"]', '[]', '[\"mcp-1\"]', 1, 2)", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("PRAGMA foreign_keys = ON").execute(&pool).await.unwrap(); - pool.close().await; - - let db = init_database(&path).await.unwrap(); - let row = sqlx::query( - "SELECT definition_id, assistant_key, avatar_type, avatar_value - FROM assistant_definitions WHERE assistant_key = 'u1'", - ) - .fetch_one(db.pool()) - .await - .unwrap(); - let definition_id = row.get::("definition_id"); - assert_eq!(row.get::("assistant_key"), "u1"); - assert_eq!(row.get::("avatar_type"), "emoji"); - assert_eq!(row.get::, _>("avatar_value"), Some("🤖".to_string())); - - let state_definition_id: String = sqlx::query_scalar("SELECT definition_id FROM assistant_overlays LIMIT 1") - .fetch_one(db.pool()) - .await - .unwrap(); - assert_eq!(state_definition_id, definition_id); - - let pref_definition_id: String = sqlx::query_scalar("SELECT definition_id FROM assistant_preferences LIMIT 1") - .fetch_one(db.pool()) - .await - .unwrap(); - assert_eq!(pref_definition_id, definition_id); - db.close().await; -} - -#[tokio::test] -async fn idempotent_reinit_drops_legacy_extension_assistant_definitions() { - let dir = tempfile::tempdir().unwrap(); - let path = dir.path().join("test.db"); - - let db = init_database(&path).await.unwrap(); - db.close().await; - - let pool = open_file_pool(&path).await; - sqlx::query("PRAGMA foreign_keys = OFF").execute(&pool).await.unwrap(); - sqlx::query("DROP TABLE assistant_preferences") - .execute(&pool) - .await - .unwrap(); - sqlx::query("DROP TABLE assistant_overlays") - .execute(&pool) - .await - .unwrap(); - sqlx::query("DROP TABLE assistant_definitions") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - r#" -CREATE TABLE assistant_definitions ( - id TEXT PRIMARY KEY, - source TEXT NOT NULL, - owner_type TEXT NOT NULL, - source_ref TEXT, - source_version TEXT, - source_hash TEXT, - name TEXT NOT NULL, - name_i18n TEXT NOT NULL DEFAULT '{}', - description TEXT, - description_i18n TEXT NOT NULL DEFAULT '{}', - avatar TEXT, - agent_backend TEXT NOT NULL, - rule_resource_type TEXT NOT NULL, - rule_resource_ref TEXT, - rule_inline_content TEXT, - recommended_prompts TEXT NOT NULL DEFAULT '[]', - recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', - default_model_mode TEXT NOT NULL, - default_model_value TEXT, - default_permission_mode TEXT NOT NULL, - default_permission_value TEXT, - default_skills_mode TEXT NOT NULL, - default_skill_ids TEXT NOT NULL DEFAULT '[]', - custom_skill_names TEXT NOT NULL DEFAULT '[]', - default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - default_mcps_mode TEXT NOT NULL, - default_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - deleted_at INTEGER -) - "#, - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref - ON assistant_definitions(source, source_ref) - WHERE source_ref IS NOT NULL", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE TABLE assistant_states ( - assistant_id TEXT PRIMARY KEY, - enabled INTEGER NOT NULL DEFAULT 1, - sort_order INTEGER NOT NULL DEFAULT 0, - agent_backend_override TEXT, - last_used_at INTEGER, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE TABLE assistant_preferences ( - assistant_id TEXT PRIMARY KEY, - last_model_id TEXT, - last_permission_value TEXT, - last_skill_ids TEXT NOT NULL DEFAULT '[]', - last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - last_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_definitions ( - id, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar, - agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, - recommended_prompts, recommended_prompts_i18n, - default_model_mode, default_model_value, - default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, - default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - ) VALUES ( - 'ext-helper', 'extension', 'extension', 'ext-helper', NULL, NULL, - 'Helper', '{}', 'desc', '{}', NULL, - 'aionrs', 'inline', NULL, 'ctx', - '[]', '{}', - 'unset', NULL, - 'unset', NULL, - 'fixed', '[]', '[]', '[]', - 'unset', '[]', 1, 2, NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_states (assistant_id, enabled, sort_order, agent_backend_override, last_used_at, created_at, updated_at) - VALUES ('ext-helper', 1, 3, NULL, NULL, 1, 2)", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_preferences (assistant_id, last_model_id, last_permission_value, last_skill_ids, - last_disabled_builtin_skill_ids, last_mcp_ids, created_at, updated_at) - VALUES ('ext-helper', 'gpt-4.1', NULL, '[]', '[]', '[]', 1, 2)", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("PRAGMA foreign_keys = ON").execute(&pool).await.unwrap(); - pool.close().await; - - let db = init_database(&path).await.unwrap(); - let count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM assistant_definitions") - .fetch_one(db.pool()) - .await - .unwrap(); - assert_eq!(count, 0); - let overlay_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM assistant_overlays") - .fetch_one(db.pool()) - .await - .unwrap(); - assert_eq!(overlay_count, 0); - let preference_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM assistant_preferences") - .fetch_one(db.pool()) - .await - .unwrap(); - assert_eq!(preference_count, 0); - db.close().await; -} - -#[tokio::test] -async fn idempotent_reinit_repairs_stale_assistant_definition_default_mode_constraints() { - let dir = tempfile::tempdir().unwrap(); - let path = dir.path().join("test.db"); - - let db = init_database(&path).await.unwrap(); - db.close().await; - - let pool = open_file_pool(&path).await; - sqlx::query("PRAGMA foreign_keys = OFF").execute(&pool).await.unwrap(); - sqlx::query("DROP TABLE assistant_preferences") - .execute(&pool) - .await - .unwrap(); - sqlx::query("DROP TABLE assistant_overlays") - .execute(&pool) - .await - .unwrap(); - sqlx::query("DROP TABLE assistant_definitions") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - r#" -CREATE TABLE assistant_definitions ( - definition_id TEXT PRIMARY KEY, - assistant_key TEXT NOT NULL, - source TEXT NOT NULL, - owner_type TEXT NOT NULL, - source_ref TEXT, - source_version TEXT, - source_hash TEXT, - name TEXT NOT NULL, - name_i18n TEXT NOT NULL DEFAULT '{}', - description TEXT, - description_i18n TEXT NOT NULL DEFAULT '{}', - avatar_type TEXT NOT NULL DEFAULT 'none', - avatar_value TEXT, - agent_backend TEXT NOT NULL, - rule_resource_type TEXT NOT NULL, - rule_resource_ref TEXT, - rule_inline_content TEXT, - recommended_prompts TEXT NOT NULL DEFAULT '[]', - recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', - default_model_mode TEXT NOT NULL CHECK (default_model_mode IN ('auto', 'fixed')), - default_model_value TEXT, - default_permission_mode TEXT NOT NULL CHECK (default_permission_mode IN ('auto', 'fixed')), - default_permission_value TEXT, - default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), - default_skill_ids TEXT NOT NULL DEFAULT '[]', - custom_skill_names TEXT NOT NULL DEFAULT '[]', - default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - default_mcps_mode TEXT NOT NULL CHECK (default_mcps_mode IN ('auto', 'fixed')), - default_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL, - deleted_at INTEGER -) - "#, - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE UNIQUE INDEX idx_assistant_definitions_source_ref - ON assistant_definitions(source, source_ref) - WHERE source_ref IS NOT NULL", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE UNIQUE INDEX idx_assistant_definitions_assistant_key - ON assistant_definitions(assistant_key)", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_definitions_source ON assistant_definitions(source)") - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_definitions_agent_backend ON assistant_definitions(agent_backend)") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE TABLE assistant_overlays ( - definition_id TEXT PRIMARY KEY, - enabled INTEGER NOT NULL DEFAULT 1, - sort_order INTEGER NOT NULL DEFAULT 0, - agent_backend_override TEXT, - last_used_at INTEGER, - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_overlays_enabled ON assistant_overlays(enabled)") - .execute(&pool) - .await - .unwrap(); - sqlx::query("CREATE INDEX idx_assistant_overlays_sort_order ON assistant_overlays(sort_order)") - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "CREATE TABLE assistant_preferences ( - definition_id TEXT PRIMARY KEY, - last_model_id TEXT, - last_permission_value TEXT, - last_skill_ids TEXT NOT NULL DEFAULT '[]', - last_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', - last_mcp_ids TEXT NOT NULL DEFAULT '[]', - created_at INTEGER NOT NULL, - updated_at INTEGER NOT NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query( - "INSERT INTO assistant_definitions ( - definition_id, assistant_key, source, owner_type, source_ref, source_version, source_hash, - name, name_i18n, description, description_i18n, avatar_type, avatar_value, - agent_backend, rule_resource_type, rule_resource_ref, rule_inline_content, - recommended_prompts, recommended_prompts_i18n, - default_model_mode, default_model_value, - default_permission_mode, default_permission_value, - default_skills_mode, default_skill_ids, custom_skill_names, default_disabled_builtin_skill_ids, - default_mcps_mode, default_mcp_ids, created_at, updated_at, deleted_at - ) VALUES ( - 'def-1', 'assistant-1', 'builtin', 'system', 'assistant-1', NULL, NULL, - 'Builtin Assistant', '{}', 'desc', '{}', 'emoji', '🤖', - 'codex', 'builtin_asset', 'assistant-1', NULL, - '[]', '{}', - 'auto', NULL, - 'auto', NULL, - 'fixed', '[]', '[]', '[]', - 'auto', '[]', 1000, 1000, NULL - )", - ) - .execute(&pool) - .await - .unwrap(); - sqlx::query("PRAGMA foreign_keys = ON").execute(&pool).await.unwrap(); - pool.close().await; - - let db = init_database(&path).await.unwrap(); - let table_sql: String = - sqlx::query_scalar("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'assistant_definitions'") - .fetch_one(db.pool()) - .await - .unwrap(); - assert!(table_sql.contains("default_model_mode IN ('unset', 'auto', 'fixed')")); - assert!(table_sql.contains("default_permission_mode IN ('unset', 'auto', 'fixed')")); - assert!(table_sql.contains("default_mcps_mode IN ('unset', 'auto', 'fixed')")); - - sqlx::query( - "UPDATE assistant_definitions - SET default_model_mode = 'unset', - default_permission_mode = 'unset', - default_mcps_mode = 'unset' - WHERE definition_id = 'def-1'", - ) - .execute(db.pool()) - .await - .unwrap(); - db.close().await; -} - // -- T1.4 Migrations -- #[tokio::test] From e8606bcba0cb7310060eb0ee492772b1ffc084c3 Mon Sep 17 00:00:00 2001 From: zk <> Date: Thu, 11 Jun 2026 15:52:15 +0800 Subject: [PATCH 12/19] refactor(assistant): simplify default mode semantics --- crates/aionui-assistant/src/service.rs | 46 ++++++------ crates/aionui-conversation/src/service.rs | 54 +++++++++++++- crates/aionui-conversation/src/service_ops.rs | 21 +++++- .../aionui-conversation/src/service_test.rs | 72 +++++++++++-------- .../012_assistant_data_unification.sql | 12 ++-- .../assistant_data_unification_schema.rs | 8 +-- 6 files changed, 146 insertions(+), 67 deletions(-) diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 87c1ada0..c734d129 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -145,15 +145,15 @@ impl AssistantService { rule_inline_content: None, recommended_prompts: &recommended_prompts, recommended_prompts_i18n: &recommended_prompts_i18n, - default_model_mode: "unset", + default_model_mode: "auto", default_model_value: None, - default_permission_mode: "unset", + default_permission_mode: "auto", default_permission_value: None, default_skills_mode: "fixed", default_skill_ids: &default_skill_ids, custom_skill_names: &custom_skill_names, default_disabled_builtin_skill_ids: &default_disabled_builtin_skill_ids, - default_mcps_mode: "unset", + default_mcps_mode: "auto", default_mcp_ids: "[]", }) .await @@ -234,15 +234,15 @@ impl AssistantService { rule_inline_content: None, recommended_prompts: &recommended_prompts, recommended_prompts_i18n: &recommended_prompts_i18n, - default_model_mode: "unset", + default_model_mode: "auto", default_model_value: None, - default_permission_mode: "unset", + default_permission_mode: "auto", default_permission_value: None, default_skills_mode: "fixed", default_skill_ids: &default_skill_ids, custom_skill_names: &custom_skill_names, default_disabled_builtin_skill_ids: &default_disabled_builtin_skill_ids, - default_mcps_mode: "unset", + default_mcps_mode: "auto", default_mcp_ids: "[]", }) .await @@ -272,9 +272,9 @@ impl AssistantService { let mut patched = existing.clone(); if reset_model_and_permission { - patched.default_model_mode = "unset".to_string(); + patched.default_model_mode = "auto".to_string(); patched.default_model_value = None; - patched.default_permission_mode = "unset".to_string(); + patched.default_permission_mode = "auto".to_string(); patched.default_permission_value = None; } if let Some(value) = overrides.recommended_prompts.as_deref() { @@ -1569,7 +1569,6 @@ fn validate_scalar_default( field_name: &str, ) -> Result<(String, Option), AssistantError> { match value.mode.as_str() { - "unset" => Ok(("unset".into(), None)), "auto" => Ok(("auto".into(), None)), "fixed" => { let fixed = value.value.clone().filter(|v| !v.trim().is_empty()).ok_or_else(|| { @@ -1578,7 +1577,7 @@ fn validate_scalar_default( Ok(("fixed".into(), Some(fixed))) } other => Err(AssistantError::BadRequest(format!( - "{field_name}.mode must be 'unset', 'auto' or 'fixed', got '{other}'" + "{field_name}.mode must be 'auto' or 'fixed', got '{other}'" ))), } } @@ -1588,7 +1587,6 @@ fn validate_list_default( field_name: &str, ) -> Result<(String, String), AssistantError> { match value.mode.as_str() { - "unset" => Ok(("unset".into(), "[]".into())), "auto" => Ok(("auto".into(), "[]".into())), "fixed" => Ok(( "fixed".into(), @@ -1596,7 +1594,7 @@ fn validate_list_default( .map_err(|e| AssistantError::Internal(format!("encode {field_name}: {e}")))?, )), other => Err(AssistantError::BadRequest(format!( - "{field_name}.mode must be 'unset', 'auto' or 'fixed', got '{other}'" + "{field_name}.mode must be 'auto' or 'fixed', got '{other}'" ))), } } @@ -2154,22 +2152,22 @@ mod tests { let detail = fx.service.get_detail("builtin-office", Some("en-US")).await.unwrap(); assert_eq!(detail.engine.agent_backend, "claude"); - assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.model.mode, "auto"); assert_eq!(detail.defaults.model.value, None); - assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.permission.mode, "auto"); assert_eq!(detail.defaults.permission.value, None); } #[tokio::test] - async fn builtin_detail_defaults_start_unset_for_model_permission_and_mcps() { + async fn builtin_detail_defaults_start_auto_for_model_permission_and_mcps() { let fx = fixture_with_builtins(vec![mk_builtin("builtin-office", "Office")]).await; let detail = fx.service.get_detail("builtin-office", Some("en-US")).await.unwrap(); - assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.model.mode, "auto"); assert_eq!(detail.defaults.model.value, None); - assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.permission.mode, "auto"); assert_eq!(detail.defaults.permission.value, None); - assert_eq!(detail.defaults.mcps.mode, "unset"); + assert_eq!(detail.defaults.mcps.mode, "auto"); assert!(detail.defaults.mcps.value.is_empty()); } @@ -2236,14 +2234,14 @@ mod tests { let detail = fx.service.get_detail("u1", Some("en-US")).await.unwrap(); assert_eq!(detail.engine.agent_backend, "codex"); - assert_eq!(detail.defaults.model.mode, "unset"); + assert_eq!(detail.defaults.model.mode, "auto"); assert_eq!(detail.defaults.model.value, None); - assert_eq!(detail.defaults.permission.mode, "unset"); + assert_eq!(detail.defaults.permission.mode, "auto"); assert_eq!(detail.defaults.permission.value, None); } #[tokio::test] - async fn create_user_without_governance_defaults_starts_unset() { + async fn create_user_without_governance_defaults_starts_auto() { let fx = fixture().await; fx.service .create(CreateAssistantRequest { @@ -2255,9 +2253,9 @@ mod tests { .unwrap(); let detail = fx.service.get_detail("u1", Some("en-US")).await.unwrap(); - assert_eq!(detail.defaults.model.mode, "unset"); - assert_eq!(detail.defaults.permission.mode, "unset"); - assert_eq!(detail.defaults.mcps.mode, "unset"); + assert_eq!(detail.defaults.model.mode, "auto"); + assert_eq!(detail.defaults.permission.mode, "auto"); + assert_eq!(detail.defaults.mcps.mode, "auto"); } #[tokio::test] diff --git a/crates/aionui-conversation/src/service.rs b/crates/aionui-conversation/src/service.rs index bac30ad1..dd46338c 100644 --- a/crates/aionui-conversation/src/service.rs +++ b/crates/aionui-conversation/src/service.rs @@ -1003,7 +1003,6 @@ impl ConversationService { None if definition.default_mcps_mode == "fixed" => { parse_json_string_list(Some(definition.default_mcp_ids.as_str()), "default_mcp_ids")? } - None if definition.default_mcps_mode == "unset" => Vec::new(), None => preference .as_ref() .map(|row| parse_json_string_list(Some(row.last_mcp_ids.as_str()), "last_mcp_ids")) @@ -1145,6 +1144,51 @@ impl ConversationService { Ok(()) } + pub(crate) async fn persist_runtime_assistant_snapshot( + &self, + conversation_id: &str, + updates: AssistantRuntimePreferenceUpdate<'_>, + ) -> Result<(), ConversationError> { + let Some(snapshot) = self + .conversation_repo + .get_assistant_snapshot(conversation_id) + .await + .map_err(|e| { + ConversationError::internal(format!( + "Failed to load persisted assistant snapshot for runtime sync: {e}" + )) + })? + else { + return Ok(()); + }; + + self.conversation_repo + .upsert_assistant_snapshot(&UpsertConversationAssistantSnapshotParams { + conversation_id: &snapshot.conversation_id, + assistant_definition_id: &snapshot.assistant_definition_id, + assistant_key: &snapshot.assistant_key, + assistant_source: &snapshot.assistant_source, + assistant_name: &snapshot.assistant_name, + assistant_avatar_type: &snapshot.assistant_avatar_type, + assistant_avatar_value: snapshot.assistant_avatar_value.as_deref(), + agent_backend: &snapshot.agent_backend, + rules_content: &snapshot.rules_content, + default_model_mode: &snapshot.default_model_mode, + resolved_model_id: updates.model.or(snapshot.resolved_model_id.as_deref()), + default_permission_mode: &snapshot.default_permission_mode, + resolved_permission_value: updates.permission.or(snapshot.resolved_permission_value.as_deref()), + default_skills_mode: &snapshot.default_skills_mode, + resolved_skill_ids: &snapshot.resolved_skill_ids, + resolved_disabled_builtin_skill_ids: &snapshot.resolved_disabled_builtin_skill_ids, + default_mcps_mode: &snapshot.default_mcps_mode, + resolved_mcp_ids: &snapshot.resolved_mcp_ids, + }) + .await + .map_err(|e| ConversationError::internal(format!("assistant snapshot upsert failed: {e}")))?; + + Ok(()) + } + pub(crate) async fn persist_runtime_assistant_preferences( &self, conversation_id: &str, @@ -1483,6 +1527,14 @@ impl ConversationService { if let Some(model) = req.model.as_ref() { let selected_model = model.use_model.as_deref().unwrap_or(model.model.as_str()); + self.persist_runtime_assistant_snapshot( + id, + AssistantRuntimePreferenceUpdate { + model: Some(selected_model), + ..Default::default() + }, + ) + .await?; self.persist_runtime_assistant_preferences( id, AssistantRuntimePreferenceUpdate { diff --git a/crates/aionui-conversation/src/service_ops.rs b/crates/aionui-conversation/src/service_ops.rs index abe8e648..beef55a6 100644 --- a/crates/aionui-conversation/src/service_ops.rs +++ b/crates/aionui-conversation/src/service_ops.rs @@ -41,6 +41,14 @@ impl ConversationService { } let task = self.task(conversation_id)?; task.set_mode(&req.mode).await.map_err(ConversationError::from)?; + self.persist_runtime_assistant_snapshot( + conversation_id, + crate::service::AssistantRuntimePreferenceUpdate { + permission: Some(&req.mode), + ..Default::default() + }, + ) + .await?; self.persist_runtime_assistant_preferences( conversation_id, crate::service::AssistantRuntimePreferenceUpdate { @@ -83,9 +91,18 @@ impl ConversationService { return Err(err); } }; - task.set_model_confirmed(&req.model_id) + let response = task + .set_model_confirmed(&req.model_id) .await .map_err(ConversationError::from)?; + self.persist_runtime_assistant_snapshot( + conversation_id, + crate::service::AssistantRuntimePreferenceUpdate { + model: Some(&req.model_id), + ..Default::default() + }, + ) + .await?; self.persist_runtime_assistant_preferences( conversation_id, crate::service::AssistantRuntimePreferenceUpdate { @@ -94,7 +111,7 @@ impl ConversationService { }, ) .await?; - task.get_model().await.map_err(ConversationError::from) + Ok(response) } // ── Usage / Slash commands ────────────────────────────────────── diff --git a/crates/aionui-conversation/src/service_test.rs b/crates/aionui-conversation/src/service_test.rs index 30ef9bbe..3e374cc6 100644 --- a/crates/aionui-conversation/src/service_test.rs +++ b/crates/aionui-conversation/src/service_test.rs @@ -809,7 +809,7 @@ async fn upsert_test_assistant_definition( default_skill_ids: "[]", custom_skill_names: "[]", default_disabled_builtin_skill_ids: "[]", - default_mcps_mode: "unset", + default_mcps_mode: "auto", default_mcp_ids: "[]", }) .await @@ -2378,7 +2378,7 @@ async fn set_model_returns_confirmed_model_even_if_get_model_is_stale() { #[tokio::test] async fn set_model_updates_assistant_preference_only_when_snapshot_model_mode_is_auto() { let task_mgr = Arc::new(MockTaskManager::new()); - let (svc, _broadcaster, _repo, definition_repo, overlay_repo, preference_repo) = + let (svc, _broadcaster, repo, definition_repo, overlay_repo, preference_repo) = make_service_with_mock_task_manager_and_assistant_support(task_mgr.clone()).await; upsert_test_assistant_definition( @@ -2387,7 +2387,7 @@ async fn set_model_updates_assistant_preference_only_when_snapshot_model_mode_is "assistant-model-auto", "claude", "auto", - "unset", + "auto", ) .await; overlay_repo @@ -2437,6 +2437,8 @@ async fn set_model_updates_assistant_preference_only_when_snapshot_model_mode_is ); let auto_pref = preference_repo.get("asstdef_model_auto").await.unwrap().unwrap(); assert_eq!(auto_pref.last_model_id.as_deref(), Some("model-b")); + let auto_snapshot = repo.get_assistant_snapshot(&auto_conv.id).await.unwrap().unwrap(); + assert_eq!(auto_snapshot.resolved_model_id.as_deref(), Some("model-b")); upsert_test_assistant_definition( &definition_repo, @@ -2444,7 +2446,7 @@ async fn set_model_updates_assistant_preference_only_when_snapshot_model_mode_is "assistant-model-fixed", "claude", "fixed", - "unset", + "auto", ) .await; overlay_repo @@ -2488,12 +2490,14 @@ async fn set_model_updates_assistant_preference_only_when_snapshot_model_mode_is let fixed_pref = preference_repo.get("asstdef_model_fixed").await.unwrap().unwrap(); assert_eq!(fixed_pref.last_model_id.as_deref(), Some("legacy-fixed-model")); + let fixed_snapshot = repo.get_assistant_snapshot(&fixed_conv.id).await.unwrap().unwrap(); + assert_eq!(fixed_snapshot.resolved_model_id.as_deref(), Some("model-c")); } #[tokio::test] async fn set_mode_updates_assistant_preference_only_when_snapshot_permission_mode_is_auto() { let task_mgr = Arc::new(MockTaskManager::new()); - let (svc, _broadcaster, _repo, definition_repo, overlay_repo, preference_repo) = + let (svc, _broadcaster, repo, definition_repo, overlay_repo, preference_repo) = make_service_with_mock_task_manager_and_assistant_support(task_mgr.clone()).await; upsert_test_assistant_definition( @@ -2501,7 +2505,7 @@ async fn set_mode_updates_assistant_preference_only_when_snapshot_permission_mod "asstdef_mode_auto", "assistant-mode-auto", "claude", - "unset", + "auto", "auto", ) .await; @@ -2546,13 +2550,15 @@ async fn set_mode_updates_assistant_preference_only_when_snapshot_permission_mod assert_eq!(response.mode, "plan"); let auto_pref = preference_repo.get("asstdef_mode_auto").await.unwrap().unwrap(); assert_eq!(auto_pref.last_permission_value.as_deref(), Some("plan")); + let auto_snapshot = repo.get_assistant_snapshot(&auto_conv.id).await.unwrap().unwrap(); + assert_eq!(auto_snapshot.resolved_permission_value.as_deref(), Some("plan")); upsert_test_assistant_definition( &definition_repo, "asstdef_mode_fixed", "assistant-mode-fixed", "claude", - "unset", + "auto", "fixed", ) .await; @@ -2597,6 +2603,8 @@ async fn set_mode_updates_assistant_preference_only_when_snapshot_permission_mod let fixed_pref = preference_repo.get("asstdef_mode_fixed").await.unwrap().unwrap(); assert_eq!(fixed_pref.last_permission_value.as_deref(), Some("legacy-fixed-mode")); + let fixed_snapshot = repo.get_assistant_snapshot(&fixed_conv.id).await.unwrap().unwrap(); + assert_eq!(fixed_snapshot.resolved_permission_value.as_deref(), Some("acceptEdits")); } #[tokio::test] @@ -2611,7 +2619,7 @@ async fn update_aionrs_model_updates_assistant_preference_only_when_snapshot_mod "assistant-aionrs-auto", "aionrs", "auto", - "unset", + "auto", ) .await; overlay_repo @@ -2663,6 +2671,8 @@ async fn update_aionrs_model_updates_assistant_preference_only_when_snapshot_mod ); let auto_pref = preference_repo.get("asstdef_aionrs_auto").await.unwrap().unwrap(); assert_eq!(auto_pref.last_model_id.as_deref(), Some("model-z")); + let auto_snapshot = repo.get_assistant_snapshot(&auto_conv.id).await.unwrap().unwrap(); + assert_eq!(auto_snapshot.resolved_model_id.as_deref(), Some("model-z")); upsert_test_assistant_definition( &definition_repo, @@ -2670,7 +2680,7 @@ async fn update_aionrs_model_updates_assistant_preference_only_when_snapshot_mod "assistant-aionrs-fixed", "aionrs", "fixed", - "unset", + "auto", ) .await; overlay_repo @@ -2718,6 +2728,8 @@ async fn update_aionrs_model_updates_assistant_preference_only_when_snapshot_mod let fixed_pref = preference_repo.get("asstdef_aionrs_fixed").await.unwrap().unwrap(); assert_eq!(fixed_pref.last_model_id.as_deref(), Some("legacy-aionrs-fixed-model")); + let fixed_snapshot = repo.get_assistant_snapshot(&fixed_conv.id).await.unwrap().unwrap(); + assert_eq!(fixed_snapshot.resolved_model_id.as_deref(), Some("model-y")); // Ensure the update path used the repository row, not a no-op. let updated_row = repo.get(&fixed_conv.id).await.unwrap().unwrap(); @@ -4092,12 +4104,12 @@ async fn create_does_not_overwrite_preferences_for_fixed_skills_and_mcps() { } #[tokio::test] -async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() { +async fn create_with_auto_builtin_defaults_without_preferences_keeps_snapshot_values_empty() { let resolver = Arc::new(FixedSkillResolver { names: vec!["cron".into(), "todo-tracker".into()], }); let dispatcher = Arc::new(StaticAssistantDispatcher { - rules: std::collections::HashMap::from([("preset-unset".to_string(), "assistant rule body".to_string())]), + rules: std::collections::HashMap::from([("preset-auto".to_string(), "assistant rule body".to_string())]), }); let (svc, _broadcaster, _repo, definition_repo, state_repo, preference_repo) = make_service_with_assistant_support(resolver, dispatcher).await; @@ -4105,11 +4117,11 @@ async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() definition_repo .upsert(&UpsertAssistantDefinitionParams { - definition_id: "asstdef_preset_unset", - assistant_key: "preset-unset", + definition_id: "asstdef_preset_auto", + assistant_key: "preset-auto", source: "builtin", owner_type: "system", - source_ref: Some("preset-unset"), + source_ref: Some("preset-auto"), source_version: None, source_hash: None, name: "Preset Unset", @@ -4120,26 +4132,26 @@ async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() avatar_value: Some("🤖"), agent_backend: "claude", rule_resource_type: "builtin_asset", - rule_resource_ref: Some("preset-unset"), + rule_resource_ref: Some("preset-auto"), rule_inline_content: None, recommended_prompts: "[]", recommended_prompts_i18n: "{}", - default_model_mode: "unset", + default_model_mode: "auto", default_model_value: None, - default_permission_mode: "unset", + default_permission_mode: "auto", default_permission_value: None, default_skills_mode: "fixed", default_skill_ids: r#"["pdf"]"#, custom_skill_names: "[]", default_disabled_builtin_skill_ids: "[]", - default_mcps_mode: "unset", + default_mcps_mode: "auto", default_mcp_ids: "[]", }) .await .unwrap(); state_repo .upsert(&UpsertAssistantOverlayParams { - definition_id: "asstdef_preset_unset", + definition_id: "asstdef_preset_auto", enabled: true, sort_order: 0, agent_backend_override: Some("codex"), @@ -4149,12 +4161,12 @@ async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() .unwrap(); preference_repo .upsert(&UpsertAssistantPreferenceParams { - definition_id: "asstdef_preset_unset", - last_model_id: Some("legacy-model"), - last_permission_value: Some("workspace-write"), - last_skill_ids: r#"["legacy-skill"]"#, - last_disabled_builtin_skill_ids: r#"["legacy-disabled"]"#, - last_mcp_ids: r#"["legacy-mcp"]"#, + definition_id: "asstdef_preset_auto", + last_model_id: None, + last_permission_value: None, + last_skill_ids: "[]", + last_disabled_builtin_skill_ids: "[]", + last_mcp_ids: "[]", }) .await .unwrap(); @@ -4165,7 +4177,7 @@ async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() "extra": { "workspace": workspace, "backend": "claude", - "assistant_id": "preset-unset", + "assistant_id": "preset-auto", "assistant_locale": "zh-CN" }, })) @@ -4176,10 +4188,10 @@ async fn create_with_unset_builtin_defaults_does_not_resolve_from_preferences() assert!(resp.extra.get("permission_mode").is_none()); assert!(resp.extra.get("assistant_snapshot").is_none()); - let updated_pref = preference_repo.get("asstdef_preset_unset").await.unwrap().unwrap(); - assert_eq!(updated_pref.last_model_id.as_deref(), Some("legacy-model")); - assert_eq!(updated_pref.last_permission_value.as_deref(), Some("workspace-write")); - assert_eq!(updated_pref.last_mcp_ids, r#"["legacy-mcp"]"#); + let updated_pref = preference_repo.get("asstdef_preset_auto").await.unwrap().unwrap(); + assert_eq!(updated_pref.last_model_id, None); + assert_eq!(updated_pref.last_permission_value, None); + assert_eq!(updated_pref.last_mcp_ids, "[]"); } #[tokio::test] diff --git a/crates/aionui-db/migrations/012_assistant_data_unification.sql b/crates/aionui-db/migrations/012_assistant_data_unification.sql index 74fb8fe6..5a77f6bd 100644 --- a/crates/aionui-db/migrations/012_assistant_data_unification.sql +++ b/crates/aionui-db/migrations/012_assistant_data_unification.sql @@ -42,10 +42,10 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( recommended_prompts TEXT NOT NULL DEFAULT '[]', recommended_prompts_i18n TEXT NOT NULL DEFAULT '{}', default_model_mode TEXT NOT NULL - CHECK (default_model_mode IN ('unset', 'auto', 'fixed')), + CHECK (default_model_mode IN ('auto', 'fixed')), default_model_value TEXT, default_permission_mode TEXT NOT NULL - CHECK (default_permission_mode IN ('unset', 'auto', 'fixed')), + CHECK (default_permission_mode IN ('auto', 'fixed')), default_permission_value TEXT, default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS assistant_definitions ( custom_skill_names TEXT NOT NULL DEFAULT '[]', default_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', default_mcps_mode TEXT NOT NULL - CHECK (default_mcps_mode IN ('unset', 'auto', 'fixed')), + CHECK (default_mcps_mode IN ('auto', 'fixed')), default_mcp_ids TEXT NOT NULL DEFAULT '[]', created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, @@ -121,17 +121,17 @@ CREATE TABLE IF NOT EXISTS conversation_assistant_snapshots ( agent_backend TEXT NOT NULL, rules_content TEXT NOT NULL DEFAULT '', default_model_mode TEXT NOT NULL - CHECK (default_model_mode IN ('unset', 'auto', 'fixed')), + CHECK (default_model_mode IN ('auto', 'fixed')), resolved_model_id TEXT, default_permission_mode TEXT NOT NULL - CHECK (default_permission_mode IN ('unset', 'auto', 'fixed')), + CHECK (default_permission_mode IN ('auto', 'fixed')), resolved_permission_value TEXT, default_skills_mode TEXT NOT NULL CHECK (default_skills_mode IN ('auto', 'fixed')), resolved_skill_ids TEXT NOT NULL DEFAULT '[]', resolved_disabled_builtin_skill_ids TEXT NOT NULL DEFAULT '[]', default_mcps_mode TEXT NOT NULL - CHECK (default_mcps_mode IN ('unset', 'auto', 'fixed')), + CHECK (default_mcps_mode IN ('auto', 'fixed')), resolved_mcp_ids TEXT NOT NULL DEFAULT '[]', created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, diff --git a/crates/aionui-db/tests/assistant_data_unification_schema.rs b/crates/aionui-db/tests/assistant_data_unification_schema.rs index f500dce2..82e3df98 100644 --- a/crates/aionui-db/tests/assistant_data_unification_schema.rs +++ b/crates/aionui-db/tests/assistant_data_unification_schema.rs @@ -98,8 +98,8 @@ async fn assistant_definition_table_rejects_extension_source_and_owner_type() { 'd-ext-source', 'ext-source', 'extension', 'system', 'ext-source', 'Ext Source', '{}', '{}', 'none', 'aionrs', 'none', '[]', '{}', - 'unset', 'unset', 'fixed', '[]', - '[]', '[]', 'unset', '[]', + 'auto', 'auto', 'fixed', '[]', + '[]', '[]', 'auto', '[]', 1, 1 ) "#, @@ -122,8 +122,8 @@ async fn assistant_definition_table_rejects_extension_source_and_owner_type() { 'd-ext-owner', 'ext-owner', 'builtin', 'extension', 'ext-owner', 'Ext Owner', '{}', '{}', 'none', 'aionrs', 'none', '[]', '{}', - 'unset', 'unset', 'fixed', '[]', - '[]', '[]', 'unset', '[]', + 'auto', 'auto', 'fixed', '[]', + '[]', '[]', 'auto', '[]', 1, 1 ) "#, From 3f811e8d8089769dcd171797693791ad343f9c7b Mon Sep 17 00:00:00 2001 From: zk <> Date: Thu, 11 Jun 2026 19:38:29 +0800 Subject: [PATCH 13/19] fix(assistant): align defaults and preferences semantics --- crates/aionui-api-types/src/conversation.rs | 50 +++ crates/aionui-api-types/src/lib.rs | 15 +- crates/aionui-app/tests/conversation_e2e.rs | 11 +- crates/aionui-app/tests/work_dir_e2e.rs | 3 + crates/aionui-assistant/src/service.rs | 296 +++++++++++++++++- crates/aionui-channel/src/message_service.rs | 1 + crates/aionui-conversation/src/service.rs | 64 ++-- .../aionui-conversation/src/service_test.rs | 44 +-- crates/aionui-cron/src/executor.rs | 1 + crates/aionui-team/src/service.rs | 2 + .../aionui-team/src/service/spawn_support.rs | 1 + 11 files changed, 429 insertions(+), 59 deletions(-) diff --git a/crates/aionui-api-types/src/conversation.rs b/crates/aionui-api-types/src/conversation.rs index b3cd8559..5bf49934 100644 --- a/crates/aionui-api-types/src/conversation.rs +++ b/crates/aionui-api-types/src/conversation.rs @@ -25,12 +25,36 @@ pub struct ConversationMcpStatus { // ── Request types ────────────────────────────────────────────────── +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Default)] +pub struct AssistantConversationOverridesRequest { + #[serde(default)] + pub model: Option, + #[serde(default)] + pub permission: Option, + #[serde(default)] + pub skill_ids: Option>, + #[serde(default)] + pub disabled_builtin_skill_ids: Option>, + #[serde(default)] + pub mcp_ids: Option>, +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +pub struct AssistantConversationRequest { + pub id: String, + #[serde(default)] + pub locale: Option, + #[serde(default)] + pub conversation_overrides: Option, +} + /// Body for `POST /api/conversations`. #[derive(Debug, Deserialize)] pub struct CreateConversationRequest { pub r#type: AgentType, pub name: Option, pub model: Option, + pub assistant: Option, pub source: Option, pub channel_chat_id: Option, pub extra: serde_json::Value, @@ -269,6 +293,17 @@ mod tests { "type": "acp", "name": "Code Review", "model": { "provider_id": "p1", "model": "claude-sonnet-4-20250514" }, + "assistant": { + "id": "assistant-1", + "locale": "zh-CN", + "conversation_overrides": { + "model": "opus-4.1", + "permission": "yolo", + "skill_ids": ["skill-a"], + "disabled_builtin_skill_ids": ["builtin-a"], + "mcp_ids": ["mcp-a"] + } + }, "source": "aionui", "channel_chat_id": "user:123", "extra": { "workspace": "/project" } @@ -277,6 +312,20 @@ mod tests { assert_eq!(req.r#type, AgentType::Acp); assert_eq!(req.name.as_deref(), Some("Code Review")); assert_eq!(req.model.unwrap().model, "claude-sonnet-4-20250514"); + assert_eq!( + req.assistant, + Some(AssistantConversationRequest { + id: "assistant-1".into(), + locale: Some("zh-CN".into()), + conversation_overrides: Some(AssistantConversationOverridesRequest { + model: Some("opus-4.1".into()), + permission: Some("yolo".into()), + skill_ids: Some(vec!["skill-a".into()]), + disabled_builtin_skill_ids: Some(vec!["builtin-a".into()]), + mcp_ids: Some(vec!["mcp-a".into()]), + }), + }) + ); assert_eq!(req.source, Some(ConversationSource::Aionui)); assert_eq!(req.channel_chat_id.as_deref(), Some("user:123")); assert_eq!(req.extra["workspace"], "/project"); @@ -292,6 +341,7 @@ mod tests { let req: CreateConversationRequest = serde_json::from_value(raw).unwrap(); assert_eq!(req.r#type, AgentType::Acp); assert!(req.name.is_none()); + assert!(req.assistant.is_none()); assert!(req.source.is_none()); assert!(req.channel_chat_id.is_none()); } diff --git a/crates/aionui-api-types/src/lib.rs b/crates/aionui-api-types/src/lib.rs index b3a2df14..2b5d6f8a 100644 --- a/crates/aionui-api-types/src/lib.rs +++ b/crates/aionui-api-types/src/lib.rs @@ -68,13 +68,14 @@ pub use channel::{ pub use confirmation::{ApprovalCheckQuery, ApprovalCheckResponse, ConfirmRequest, ConfirmationListResponse}; pub use connection_test::TestBedrockConnectionRequest; pub use conversation::{ - ActiveCountResponse, CancelConversationRequest, CancelConversationResponse, CloneConversationRequest, - ConversationArtifactKind, ConversationArtifactListResponse, ConversationArtifactResponse, - ConversationArtifactStatus, ConversationListResponse, ConversationMcpStatus, ConversationMcpStatusKind, - ConversationResponse, ConversationRuntimeStateKind, ConversationRuntimeSummary, CreateConversationRequest, - ListConversationsQuery, ListMessagesQuery, MessageListResponse, MessageResponse, MessageSearchItem, - MessageSearchResponse, SearchMessagesQuery, SendMessageRequest, SendMessageResponse, - UpdateConversationArtifactRequest, UpdateConversationRequest, + ActiveCountResponse, AssistantConversationOverridesRequest, AssistantConversationRequest, + CancelConversationRequest, CancelConversationResponse, CloneConversationRequest, ConversationArtifactKind, + ConversationArtifactListResponse, ConversationArtifactResponse, ConversationArtifactStatus, + ConversationListResponse, ConversationMcpStatus, ConversationMcpStatusKind, ConversationResponse, + ConversationRuntimeStateKind, ConversationRuntimeSummary, CreateConversationRequest, ListConversationsQuery, + ListMessagesQuery, MessageListResponse, MessageResponse, MessageSearchItem, MessageSearchResponse, + SearchMessagesQuery, SendMessageRequest, SendMessageResponse, UpdateConversationArtifactRequest, + UpdateConversationRequest, }; pub use cron::{ CreateCronJobRequest, CronAgentConfigDto, CronJobExecutedEvent, CronJobMetadataDto, CronJobPayloadDto, diff --git a/crates/aionui-app/tests/conversation_e2e.rs b/crates/aionui-app/tests/conversation_e2e.rs index de5ef1e1..42ab49d1 100644 --- a/crates/aionui-app/tests/conversation_e2e.rs +++ b/crates/aionui-app/tests/conversation_e2e.rs @@ -211,15 +211,18 @@ async fn t1_3b_create_persists_assistant_snapshot_and_updates_preferences() { json!({ "type": "acp", "name": "Snapshot Flow", - "extra": { - "assistant_id": "u1", - "assistant_locale": "en-US", - "assistant_overrides": { + "assistant": { + "id": "u1", + "locale": "en-US", + "conversation_overrides": { "model": "override-model", "skill_ids": ["override-skill"], "disabled_builtin_skill_ids": ["override-disabled"], "mcp_ids": ["override-mcp"] } + }, + "extra": { + "preset_assistant_id": "u1" } }), &token, diff --git a/crates/aionui-app/tests/work_dir_e2e.rs b/crates/aionui-app/tests/work_dir_e2e.rs index b57413af..59271929 100644 --- a/crates/aionui-app/tests/work_dir_e2e.rs +++ b/crates/aionui-app/tests/work_dir_e2e.rs @@ -23,6 +23,7 @@ async fn conversation_workspace_uses_work_dir() { r#type: AgentType::Acp, name: Some("test".to_string()), model: None, + assistant: None, source: None, channel_chat_id: None, extra: serde_json::json!({}), @@ -60,6 +61,7 @@ async fn user_specified_workspace_is_not_overridden() { r#type: AgentType::Acp, name: Some("test".to_string()), model: None, + assistant: None, source: None, channel_chat_id: None, extra: serde_json::json!({ @@ -93,6 +95,7 @@ async fn workspace_defaults_to_data_dir_when_work_dir_equals_data_dir() { r#type: AgentType::Acp, name: Some("test".to_string()), model: None, + assistant: None, source: None, channel_chat_id: None, extra: serde_json::json!({}), diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index c734d129..1f20df33 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -18,7 +18,7 @@ use aionui_db::{ AssistantDefinitionRow, AssistantOverlayRow, AssistantRow, CreateAssistantParams, IAssistantDefinitionRepository, IAssistantOverlayRepository, IAssistantOverrideRepository, IAssistantPreferenceRepository, IAssistantRepository, IProviderRepository, SqlitePool, UpdateAssistantParams, UpsertAssistantDefinitionParams, - UpsertAssistantOverlayParams, rebuild_legacy_assistant_mirror, + UpsertAssistantOverlayParams, UpsertAssistantPreferenceParams, rebuild_legacy_assistant_mirror, }; use aionui_extension::{AssistantClassifier, AssistantRuleDispatcher, ExtensionError}; use serde_json; @@ -553,6 +553,10 @@ impl AssistantService { let row = self.repo.create(¶ms).await?; self.upsert_definition_from_legacy_user_row(&row).await?; self.apply_detail_overrides(&row.id, detail_overrides, false).await?; + if let Some(definition) = self.definition_repo.get_by_key(&row.id).await? { + self.sync_preferences_from_defaults_request(&definition, None, req.defaults.as_ref()) + .await?; + } self.get(&id).await } @@ -630,6 +634,8 @@ impl AssistantService { .get_by_key(id) .await? .ok_or_else(|| AssistantError::NotFound(format!("assistant '{id}' not found")))?; + self.sync_preferences_from_defaults_request(&definition, Some(&definition), req.defaults.as_ref()) + .await?; let state = self.state_repo.get(&definition.definition_id).await?; rebuild_legacy_assistant_mirror(&self.pool, &definition, state.as_ref()) .await @@ -678,9 +684,173 @@ impl AssistantService { self.upsert_definition_from_legacy_user_row(&row).await?; self.apply_detail_overrides(id, detail_overrides, reset_model_and_permission) .await?; + if let Some(definition) = self.definition_repo.get_by_key(id).await? { + self.sync_preferences_from_defaults_request(&definition, Some(¤t_definition), req.defaults.as_ref()) + .await?; + } self.get(id).await } + async fn sync_preferences_from_defaults_request( + &self, + definition: &AssistantDefinitionRow, + previous_definition: Option<&AssistantDefinitionRow>, + defaults: Option<&AssistantDefaultsRequest>, + ) -> Result<(), AssistantError> { + let Some(defaults) = defaults else { + return Ok(()); + }; + + let existing = self + .preference_repo + .get(&definition.definition_id) + .await + .map_err(|e| AssistantError::Internal(format!("get assistant preference: {e}")))?; + + let mut last_model_id = existing.as_ref().and_then(|row| row.last_model_id.clone()); + let mut last_permission_value = existing + .as_ref() + .and_then(|row| row.last_permission_value.clone()); + let mut last_skill_ids = existing + .as_ref() + .map(|row| decode_str_list(Some(row.last_skill_ids.as_str()))) + .transpose()? + .unwrap_or_default(); + let mut last_disabled_builtin_skill_ids = existing + .as_ref() + .map(|row| decode_str_list(Some(row.last_disabled_builtin_skill_ids.as_str()))) + .transpose()? + .unwrap_or_default(); + let mut last_mcp_ids = existing + .as_ref() + .map(|row| decode_str_list(Some(row.last_mcp_ids.as_str()))) + .transpose()? + .unwrap_or_default(); + + if let Some(model) = defaults.model.as_ref() { + match model.mode.as_str() { + "fixed" => { + last_model_id = model.value.clone().filter(|value| !value.trim().is_empty()); + } + "auto" => { + if previous_definition + .is_some_and(|current| current.default_model_mode == "fixed") + { + last_model_id = None; + } + } + other => { + return Err(AssistantError::BadRequest(format!( + "defaults.model.mode must be 'auto' or 'fixed', got '{other}'" + ))); + } + } + } + + if let Some(permission) = defaults.permission.as_ref() { + match permission.mode.as_str() { + "fixed" => { + last_permission_value = permission + .value + .clone() + .filter(|value| !value.trim().is_empty()); + } + "auto" => { + if previous_definition + .is_some_and(|current| current.default_permission_mode == "fixed") + { + last_permission_value = None; + } + } + other => { + return Err(AssistantError::BadRequest(format!( + "defaults.permission.mode must be 'auto' or 'fixed', got '{other}'" + ))); + } + } + } + + if let Some(skills) = defaults.skills.as_ref() { + match skills.mode.as_str() { + "fixed" => { + last_skill_ids = skills.value.clone(); + last_disabled_builtin_skill_ids.clear(); + } + "auto" => { + if previous_definition + .is_some_and(|current| current.default_skills_mode == "fixed") + { + last_skill_ids.clear(); + last_disabled_builtin_skill_ids.clear(); + } + } + other => { + return Err(AssistantError::BadRequest(format!( + "defaults.skills.mode must be 'auto' or 'fixed', got '{other}'" + ))); + } + } + } + + if let Some(mcps) = defaults.mcps.as_ref() { + match mcps.mode.as_str() { + "fixed" => { + last_mcp_ids = mcps.value.clone(); + } + "auto" => { + if previous_definition + .is_some_and(|current| current.default_mcps_mode == "fixed") + { + last_mcp_ids.clear(); + } + } + other => { + return Err(AssistantError::BadRequest(format!( + "defaults.mcps.mode must be 'auto' or 'fixed', got '{other}'" + ))); + } + } + } + + if last_model_id.is_none() + && last_permission_value.is_none() + && last_skill_ids.is_empty() + && last_disabled_builtin_skill_ids.is_empty() + && last_mcp_ids.is_empty() + { + if existing.is_some() { + self.preference_repo + .delete(&definition.definition_id) + .await + .map_err(|e| AssistantError::Internal(format!("delete assistant preference: {e}")))?; + } + return Ok(()); + } + + let last_skill_ids_json = serde_json::to_string(&last_skill_ids) + .map_err(|e| AssistantError::Internal(format!("encode assistant skills preference: {e}")))?; + let last_disabled_builtin_skill_ids_json = + serde_json::to_string(&last_disabled_builtin_skill_ids).map_err(|e| { + AssistantError::Internal(format!("encode disabled assistant skills preference: {e}")) + })?; + let last_mcp_ids_json = serde_json::to_string(&last_mcp_ids) + .map_err(|e| AssistantError::Internal(format!("encode assistant mcp preference: {e}")))?; + + self.preference_repo + .upsert(&UpsertAssistantPreferenceParams { + definition_id: &definition.definition_id, + last_model_id: last_model_id.as_deref(), + last_permission_value: last_permission_value.as_deref(), + last_skill_ids: &last_skill_ids_json, + last_disabled_builtin_skill_ids: &last_disabled_builtin_skill_ids_json, + last_mcp_ids: &last_mcp_ids_json, + }) + .await + .map_err(|e| AssistantError::Internal(format!("upsert assistant preference: {e}")))?; + + Ok(()) + } + pub async fn delete(&self, id: &str) -> Result<(), AssistantError> { match self.classify_source(id).await { AssistantSource::Builtin => { @@ -1741,6 +1911,7 @@ mod tests { service: AssistantService, definition_repo: Arc, state_repo: Arc, + preference_repo: Arc, provider_repo: Arc, _tmp: TempDir, _db: aionui_db::Database, @@ -1821,7 +1992,7 @@ mod tests { db.pool().clone(), definition_repo.clone(), state_repo.clone(), - preference_repo, + preference_repo.clone(), repo, orepo, provider_repo.clone(), @@ -1834,6 +2005,7 @@ mod tests { service, definition_repo, state_repo, + preference_repo, provider_repo, _tmp: tmp, _db: db, @@ -2354,6 +2526,126 @@ mod tests { assert!(detail.defaults.mcps.value.is_empty()); } + #[tokio::test] + async fn update_switching_defaults_to_fixed_seeds_preferences() { + let fx = fixture().await; + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + ..req_default() + }) + .await + .unwrap(); + + fx.service + .update( + "u1", + UpdateAssistantRequest { + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("openai/gpt-5".into()), + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("strict".into()), + }), + skills: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["skill-z".into()], + }), + mcps: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["mcp-z".into()], + }), + }), + ..Default::default() + }, + ) + .await + .unwrap(); + + let definition = fx.definition_repo.get_by_key("u1").await.unwrap().unwrap(); + let pref = fx + .preference_repo + .get(&definition.definition_id) + .await + .unwrap() + .unwrap(); + assert_eq!(pref.last_model_id.as_deref(), Some("openai/gpt-5")); + assert_eq!(pref.last_permission_value.as_deref(), Some("strict")); + assert_eq!(pref.last_skill_ids, r#"["skill-z"]"#); + assert_eq!(pref.last_mcp_ids, r#"["mcp-z"]"#); + } + + #[tokio::test] + async fn update_switching_defaults_from_fixed_to_auto_clears_preferences() { + let fx = fixture().await; + fx.service + .create(CreateAssistantRequest { + id: Some("u1".into()), + name: "Planner".into(), + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("openai/gpt-5".into()), + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "fixed".into(), + value: Some("strict".into()), + }), + skills: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["skill-z".into()], + }), + mcps: Some(AssistantDefaultListRequest { + mode: "fixed".into(), + value: vec!["mcp-z".into()], + }), + }), + ..req_default() + }) + .await + .unwrap(); + + fx.service + .update( + "u1", + UpdateAssistantRequest { + defaults: Some(AssistantDefaultsRequest { + model: Some(AssistantDefaultScalarRequest { + mode: "auto".into(), + value: None, + }), + permission: Some(AssistantDefaultScalarRequest { + mode: "auto".into(), + value: None, + }), + skills: Some(AssistantDefaultListRequest { + mode: "auto".into(), + value: vec![], + }), + mcps: Some(AssistantDefaultListRequest { + mode: "auto".into(), + value: vec![], + }), + }), + ..Default::default() + }, + ) + .await + .unwrap(); + + let definition = fx.definition_repo.get_by_key("u1").await.unwrap().unwrap(); + assert!(fx + .preference_repo + .get(&definition.definition_id) + .await + .unwrap() + .is_none()); + } + #[tokio::test] async fn delete_user_removes_row_and_override() { let fx = fixture().await; diff --git a/crates/aionui-channel/src/message_service.rs b/crates/aionui-channel/src/message_service.rs index f914a049..f7614787 100644 --- a/crates/aionui-channel/src/message_service.rs +++ b/crates/aionui-channel/src/message_service.rs @@ -150,6 +150,7 @@ impl ChannelMessageService { r#type: agent_type, name: Some(name), model: top_level_model, + assistant: None, source: Some(source), channel_chat_id: session.chat_id.clone(), extra, diff --git a/crates/aionui-conversation/src/service.rs b/crates/aionui-conversation/src/service.rs index dd46338c..df093c8d 100644 --- a/crates/aionui-conversation/src/service.rs +++ b/crates/aionui-conversation/src/service.rs @@ -10,13 +10,13 @@ use crate::runtime_completion::RuntimeCompletionPublisher; use crate::runtime_persistence::{RuntimePersistenceCoordinator, RuntimeWriteKind}; use crate::runtime_state::ConversationRuntimeStateService; use aionui_api_types::{ - ApprovalCheckResponse, CancelConversationResponse, CloneConversationRequest, ConfirmRequest, - ConfirmationListResponse, ConversationArtifactKind, ConversationArtifactListResponse, ConversationArtifactResponse, - ConversationArtifactStatus, ConversationListResponse, ConversationMcpStatus, ConversationMcpStatusKind, - ConversationResponse, ConversationRuntimeSummary, CreateConversationRequest, ListConversationsQuery, - ListMessagesQuery, MessageListResponse, MessageResponse, MessageSearchResponse, SearchMessagesQuery, - SendMessageRequest, SendMessageResponse, SessionMcpServer, SessionMcpTransport, UpdateConversationArtifactRequest, - UpdateConversationRequest, WebSocketMessage, + ApprovalCheckResponse, AssistantConversationOverridesRequest, CancelConversationResponse, CloneConversationRequest, + ConfirmRequest, ConfirmationListResponse, ConversationArtifactKind, ConversationArtifactListResponse, + ConversationArtifactResponse, ConversationArtifactStatus, ConversationListResponse, ConversationMcpStatus, + ConversationMcpStatusKind, ConversationResponse, ConversationRuntimeSummary, CreateConversationRequest, + ListConversationsQuery, ListMessagesQuery, MessageListResponse, MessageResponse, MessageSearchResponse, + SearchMessagesQuery, SendMessageRequest, SendMessageResponse, SessionMcpServer, SessionMcpTransport, + UpdateConversationArtifactRequest, UpdateConversationRequest, WebSocketMessage, }; use aionui_common::{ AgentType, ConversationSource, ConversationStatus, ErrorChain, MessageType, OnConversationDelete, PaginatedResult, @@ -65,6 +65,18 @@ struct AssistantConversationOverrides { mcp_ids: Option>, } +impl From for AssistantConversationOverrides { + fn from(value: AssistantConversationOverridesRequest) -> Self { + Self { + model: value.model, + permission: value.permission, + skill_ids: value.skill_ids, + disabled_builtin_skill_ids: value.disabled_builtin_skill_ids, + mcp_ids: value.mcp_ids, + } + } +} + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] struct AssistantSnapshotResolvedDefaults { #[serde(default)] @@ -545,27 +557,23 @@ impl ConversationService { obj.remove("custom_workspace"); } - let (assistant_id, assistant_locale, assistant_overrides) = match extra.as_object_mut() { - Some(obj) => { - let assistant_id = obj - .remove("assistant_id") - .or_else(|| obj.get("preset_assistant_id").cloned()) - .and_then(|value| value.as_str().map(ToOwned::to_owned)); - let assistant_locale = obj - .remove("assistant_locale") - .and_then(|value| value.as_str().map(ToOwned::to_owned)); - let overrides = obj - .remove("assistant_overrides") - .map(serde_json::from_value::) - .transpose() - .map_err(|e| ConversationError::BadRequest { - reason: format!("Invalid assistant_overrides: {e}"), - })? - .unwrap_or_default(); - (assistant_id, assistant_locale, overrides) - } - None => (None, None, AssistantConversationOverrides::default()), - }; + let assistant_id = req + .assistant + .as_ref() + .map(|assistant| assistant.id.clone()) + .or_else(|| { + extra + .as_object() + .and_then(|obj| obj.get("preset_assistant_id")) + .and_then(|value| value.as_str().map(ToOwned::to_owned)) + }); + let assistant_locale = req.assistant.as_ref().and_then(|assistant| assistant.locale.clone()); + let assistant_overrides = req + .assistant + .clone() + .and_then(|assistant| assistant.conversation_overrides) + .map(AssistantConversationOverrides::from) + .unwrap_or_default(); let assistant_snapshot = match assistant_id.as_deref() { Some(id) => { self.resolve_assistant_snapshot(id, assistant_locale.as_deref(), &assistant_overrides, &extra) diff --git a/crates/aionui-conversation/src/service_test.rs b/crates/aionui-conversation/src/service_test.rs index 3e374cc6..6605484c 100644 --- a/crates/aionui-conversation/src/service_test.rs +++ b/crates/aionui-conversation/src/service_test.rs @@ -827,11 +827,13 @@ async fn create_assistant_backed_conversation( let mut payload = json!({ "type": conversation_type, "name": "assistant conversation", + "assistant": { + "id": assistant_id, + "locale": "en-US" + }, "extra": { "workspace": workspace, - "backend": backend, - "assistant_id": assistant_id, - "assistant_locale": "en-US" + "backend": backend } }); @@ -3969,17 +3971,19 @@ async fn create_resolves_assistant_snapshot_and_updates_preferences() { let req: CreateConversationRequest = serde_json::from_value(json!({ "type": "acp", "name": "t", - "extra": { - "workspace": workspace, - "backend": "claude", - "assistant_id": "preset-1", - "assistant_locale": "zh-CN", - "assistant_overrides": { + "assistant": { + "id": "preset-1", + "locale": "zh-CN", + "conversation_overrides": { "model": "new-model", "skill_ids": ["pdf"], "disabled_builtin_skill_ids": ["todo-tracker"], } }, + "extra": { + "workspace": workspace, + "backend": "claude" + }, })) .unwrap(); let resp = svc.create("user-1", req).await.unwrap(); @@ -4078,12 +4082,10 @@ async fn create_does_not_overwrite_preferences_for_fixed_skills_and_mcps() { let req: CreateConversationRequest = serde_json::from_value(json!({ "type": "acp", "name": "t", - "extra": { - "workspace": workspace, - "backend": "claude", - "assistant_id": "preset-fixed", - "assistant_locale": "zh-CN", - "assistant_overrides": { + "assistant": { + "id": "preset-fixed", + "locale": "zh-CN", + "conversation_overrides": { "model": "new-model", "permission": "workspace-read", "skill_ids": ["pdf", "cron"], @@ -4091,6 +4093,10 @@ async fn create_does_not_overwrite_preferences_for_fixed_skills_and_mcps() { "mcp_ids": ["mcp-temp"] } }, + "extra": { + "workspace": workspace, + "backend": "claude" + }, })) .unwrap(); let _resp = svc.create("user-1", req).await.unwrap(); @@ -4174,11 +4180,13 @@ async fn create_with_auto_builtin_defaults_without_preferences_keeps_snapshot_va let req: CreateConversationRequest = serde_json::from_value(json!({ "type": "acp", "name": "t", + "assistant": { + "id": "preset-auto", + "locale": "zh-CN" + }, "extra": { "workspace": workspace, - "backend": "claude", - "assistant_id": "preset-auto", - "assistant_locale": "zh-CN" + "backend": "claude" }, })) .unwrap(); diff --git a/crates/aionui-cron/src/executor.rs b/crates/aionui-cron/src/executor.rs index 4bfe2c60..f02c2f35 100644 --- a/crates/aionui-cron/src/executor.rs +++ b/crates/aionui-cron/src/executor.rs @@ -439,6 +439,7 @@ impl JobExecutor { r#type: agent_type, name: Some(job.name.clone()), model, + assistant: None, source: None, channel_chat_id: None, extra, diff --git a/crates/aionui-team/src/service.rs b/crates/aionui-team/src/service.rs index 7d5913c6..ad3f81c2 100644 --- a/crates/aionui-team/src/service.rs +++ b/crates/aionui-team/src/service.rs @@ -232,6 +232,7 @@ impl TeamSessionService { r#type: agent_type, name: Some(input.name.clone()), model: top_level_model, + assistant: None, source: None, channel_chat_id: None, extra, @@ -450,6 +451,7 @@ impl TeamSessionService { r#type: agent_type, name: Some(req.name.clone()), model: top_level_model, + assistant: None, source: None, channel_chat_id: None, extra, diff --git a/crates/aionui-team/src/service/spawn_support.rs b/crates/aionui-team/src/service/spawn_support.rs index d2707391..fd233253 100644 --- a/crates/aionui-team/src/service/spawn_support.rs +++ b/crates/aionui-team/src/service/spawn_support.rs @@ -292,6 +292,7 @@ impl TeamSessionService { r#type: agent_type, name: Some(name.clone()), model: top_level_model, + assistant: None, source: None, channel_chat_id: None, extra, From f8bb69ddf309caa056ac150bf8d2c69c290aad2e Mon Sep 17 00:00:00 2001 From: zk <> Date: Fri, 12 Jun 2026 10:12:40 +0800 Subject: [PATCH 14/19] chore: apply auto-fixes (fmt + clippy) --- crates/aionui-assistant/src/service.rs | 44 +++++++++----------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 1f20df33..4b67925d 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -708,9 +708,7 @@ impl AssistantService { .map_err(|e| AssistantError::Internal(format!("get assistant preference: {e}")))?; let mut last_model_id = existing.as_ref().and_then(|row| row.last_model_id.clone()); - let mut last_permission_value = existing - .as_ref() - .and_then(|row| row.last_permission_value.clone()); + let mut last_permission_value = existing.as_ref().and_then(|row| row.last_permission_value.clone()); let mut last_skill_ids = existing .as_ref() .map(|row| decode_str_list(Some(row.last_skill_ids.as_str()))) @@ -733,9 +731,7 @@ impl AssistantService { last_model_id = model.value.clone().filter(|value| !value.trim().is_empty()); } "auto" => { - if previous_definition - .is_some_and(|current| current.default_model_mode == "fixed") - { + if previous_definition.is_some_and(|current| current.default_model_mode == "fixed") { last_model_id = None; } } @@ -750,15 +746,10 @@ impl AssistantService { if let Some(permission) = defaults.permission.as_ref() { match permission.mode.as_str() { "fixed" => { - last_permission_value = permission - .value - .clone() - .filter(|value| !value.trim().is_empty()); + last_permission_value = permission.value.clone().filter(|value| !value.trim().is_empty()); } "auto" => { - if previous_definition - .is_some_and(|current| current.default_permission_mode == "fixed") - { + if previous_definition.is_some_and(|current| current.default_permission_mode == "fixed") { last_permission_value = None; } } @@ -777,9 +768,7 @@ impl AssistantService { last_disabled_builtin_skill_ids.clear(); } "auto" => { - if previous_definition - .is_some_and(|current| current.default_skills_mode == "fixed") - { + if previous_definition.is_some_and(|current| current.default_skills_mode == "fixed") { last_skill_ids.clear(); last_disabled_builtin_skill_ids.clear(); } @@ -798,9 +787,7 @@ impl AssistantService { last_mcp_ids = mcps.value.clone(); } "auto" => { - if previous_definition - .is_some_and(|current| current.default_mcps_mode == "fixed") - { + if previous_definition.is_some_and(|current| current.default_mcps_mode == "fixed") { last_mcp_ids.clear(); } } @@ -829,10 +816,8 @@ impl AssistantService { let last_skill_ids_json = serde_json::to_string(&last_skill_ids) .map_err(|e| AssistantError::Internal(format!("encode assistant skills preference: {e}")))?; - let last_disabled_builtin_skill_ids_json = - serde_json::to_string(&last_disabled_builtin_skill_ids).map_err(|e| { - AssistantError::Internal(format!("encode disabled assistant skills preference: {e}")) - })?; + let last_disabled_builtin_skill_ids_json = serde_json::to_string(&last_disabled_builtin_skill_ids) + .map_err(|e| AssistantError::Internal(format!("encode disabled assistant skills preference: {e}")))?; let last_mcp_ids_json = serde_json::to_string(&last_mcp_ids) .map_err(|e| AssistantError::Internal(format!("encode assistant mcp preference: {e}")))?; @@ -2638,12 +2623,13 @@ mod tests { .unwrap(); let definition = fx.definition_repo.get_by_key("u1").await.unwrap().unwrap(); - assert!(fx - .preference_repo - .get(&definition.definition_id) - .await - .unwrap() - .is_none()); + assert!( + fx.preference_repo + .get(&definition.definition_id) + .await + .unwrap() + .is_none() + ); } #[tokio::test] From be93b16d990f486763a7a11ff6a0af752c9995c0 Mon Sep 17 00:00:00 2001 From: zk <> Date: Fri, 12 Jun 2026 15:13:41 +0800 Subject: [PATCH 15/19] chore: apply auto-fixes (fmt + clippy) --- crates/aionui-app/src/router/state.rs | 16 +++--- crates/aionui-app/tests/assistants_e2e.rs | 16 +++--- crates/aionui-assistant/src/service.rs | 64 ++++++++++++++--------- 3 files changed, 57 insertions(+), 39 deletions(-) diff --git a/crates/aionui-app/src/router/state.rs b/crates/aionui-app/src/router/state.rs index 75718897..c3a6aadf 100644 --- a/crates/aionui-app/src/router/state.rs +++ b/crates/aionui-app/src/router/state.rs @@ -308,13 +308,15 @@ pub fn build_assistant_state(services: &AppServices) -> AssistantRouterState { // under `~/.aionui-dev/`). let service = Arc::new(AssistantService::new( pool, - definition_repo, - state_repo, - preference_repo, - repo, - override_repo, - provider_repo, - builtin, + aionui_assistant::service::AssistantServiceDeps { + definition_repo, + state_repo, + preference_repo, + repo, + override_repo, + provider_repo, + builtin, + }, services.data_dir.clone(), )); AssistantRouterState { service } diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index 6c49ccf7..90652522 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -224,13 +224,15 @@ async fn fixture() -> Fixture { let builtin = Arc::new(BuiltinAssistantRegistry::load_from_dir(builtin_assets_dir.clone())); let service = Arc::new(AssistantService::new( pool, - definition_repo, - state_repo, - preference_repo, - repo, - override_repo, - provider_repo, - builtin, + aionui_assistant::service::AssistantServiceDeps { + definition_repo, + state_repo, + preference_repo, + repo, + override_repo, + provider_repo, + builtin, + }, user_data_dir.clone(), )); service.bootstrap_assistant_storage().await.unwrap(); diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 4b67925d..fef2accb 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -48,6 +48,16 @@ pub struct AssistantService { user_data_dir: PathBuf, } +pub struct AssistantServiceDeps { + pub definition_repo: Arc, + pub state_repo: Arc, + pub preference_repo: Arc, + pub repo: Arc, + pub override_repo: Arc, + pub provider_repo: Arc, + pub builtin: Arc, +} + impl AssistantService { /// Construct an `AssistantService` pinned to the runtime data directory. /// @@ -64,17 +74,16 @@ impl AssistantService { /// release directory while the db lived under `~/.aionui-dev/`, /// resulting in `read_rule` returning empty in dev mode. Forcing the /// caller to pass a path makes the wiring explicit. - pub fn new( - pool: SqlitePool, - definition_repo: Arc, - state_repo: Arc, - preference_repo: Arc, - repo: Arc, - override_repo: Arc, - provider_repo: Arc, - builtin: Arc, - user_data_dir: PathBuf, - ) -> Self { + pub fn new(pool: SqlitePool, deps: AssistantServiceDeps, user_data_dir: PathBuf) -> Self { + let AssistantServiceDeps { + definition_repo, + state_repo, + preference_repo, + repo, + override_repo, + provider_repo, + builtin, + } = deps; Self { pool, definition_repo, @@ -1170,6 +1179,7 @@ impl AssistantService { /// override when `AIONUI_BUILTIN_ASSISTANTS_PATH` is set). /// - User source → scan the user-writable avatars directory for a file /// whose stem equals `id`. + /// /// Built-ins whose manifest `avatar` field is an inline emoji (and thus /// has no on-disk file) also return `None`; clients fall back to the /// text avatar for those. @@ -1975,13 +1985,15 @@ mod tests { let service = AssistantService::new( db.pool().clone(), - definition_repo.clone(), - state_repo.clone(), - preference_repo.clone(), - repo, - orepo, - provider_repo.clone(), - builtin_reg, + AssistantServiceDeps { + definition_repo: definition_repo.clone(), + state_repo: state_repo.clone(), + preference_repo: preference_repo.clone(), + repo, + override_repo: orepo, + provider_repo: provider_repo.clone(), + builtin: builtin_reg, + }, tmp.path().to_path_buf(), ); service.bootstrap_assistant_storage().await.unwrap(); @@ -2876,13 +2888,15 @@ mod tests { let provider_repo: Arc = Arc::new(SqliteProviderRepository::new(db.pool().clone())); let service = AssistantService::new( db.pool().clone(), - definition_repo, - state_repo, - preference_repo, - repo, - orepo, - provider_repo, - builtin_reg, + AssistantServiceDeps { + definition_repo, + state_repo, + preference_repo, + repo, + override_repo: orepo, + provider_repo, + builtin: builtin_reg, + }, tmp.path().to_path_buf(), ); let content = service.read_rule("builtin-office", Some("en-US")).await.unwrap(); From 0b84813c74194137eb0a5c8e7620608b2f710362 Mon Sep 17 00:00:00 2001 From: zk <> Date: Fri, 12 Jun 2026 15:53:25 +0800 Subject: [PATCH 16/19] test(db): remove unused db lifecycle import --- crates/aionui-db/tests/db_lifecycle.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/aionui-db/tests/db_lifecycle.rs b/crates/aionui-db/tests/db_lifecycle.rs index 675cd404..a2198327 100644 --- a/crates/aionui-db/tests/db_lifecycle.rs +++ b/crates/aionui-db/tests/db_lifecycle.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - use aionui_db::{init_database, init_database_memory, maybe_copy_legacy_database}; use sqlx::Row; From 2231238942ce360cb64c19dd046524e8e30a0094 Mon Sep 17 00:00:00 2001 From: zk <> Date: Fri, 12 Jun 2026 17:28:58 +0800 Subject: [PATCH 17/19] feat(assistant): ship builtin image avatars --- .../assets/builtin-assistants/assistants.json | 40 +++++----- .../avatars/academic-paper.jpg | Bin 0 -> 56366 bytes .../avatars/beautiful-mermaid.jpg | Bin 0 -> 52295 bytes .../builtin-assistants/avatars/cowork.jpg | Bin 0 -> 48577 bytes .../avatars/dashboard-creator.jpg | Bin 0 -> 47119 bytes .../avatars/excel-creator.jpg | Bin 0 -> 50469 bytes .../avatars/financial-model-creator.jpg | Bin 0 -> 84177 bytes .../builtin-assistants/avatars/game-3d.jpg | Bin 0 -> 63971 bytes .../avatars/human-3-coach.jpg | Bin 0 -> 49628 bytes .../builtin-assistants/avatars/moltbook.jpg | Bin 0 -> 54122 bytes .../avatars/morph-ppt-3d.jpg | Bin 0 -> 57770 bytes .../builtin-assistants/avatars/morph-ppt.jpg | Bin 0 -> 64069 bytes .../avatars/openclaw-setup.jpg | Bin 0 -> 50953 bytes .../avatars/pitch-deck-creator.jpg | Bin 0 -> 58683 bytes .../avatars/planning-with-files.jpg | Bin 0 -> 45713 bytes .../avatars/ppt-creator.jpg | Bin 0 -> 49784 bytes .../avatars/social-job-publisher.jpg | Bin 0 -> 50159 bytes .../avatars/star-office-helper.jpg | Bin 0 -> 59326 bytes .../avatars/story-roleplay.jpg | Bin 0 -> 52114 bytes .../avatars/ui-ux-pro-max.jpg | Bin 0 -> 52263 bytes .../avatars/word-creator.jpg | Bin 0 -> 50702 bytes crates/aionui-app/tests/assistants_e2e.rs | 74 ++++++++++++++++++ crates/aionui-assistant/src/service.rs | 36 ++++++++- 23 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/academic-paper.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/beautiful-mermaid.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/cowork.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/dashboard-creator.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/excel-creator.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/financial-model-creator.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/game-3d.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/human-3-coach.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/moltbook.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/morph-ppt-3d.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/morph-ppt.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/openclaw-setup.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/pitch-deck-creator.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/planning-with-files.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/ppt-creator.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/social-job-publisher.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/star-office-helper.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/story-roleplay.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/ui-ux-pro-max.jpg create mode 100644 crates/aionui-app/assets/builtin-assistants/avatars/word-creator.jpg diff --git a/crates/aionui-app/assets/builtin-assistants/assistants.json b/crates/aionui-app/assets/builtin-assistants/assistants.json index cd3ff8ce..830949f3 100644 --- a/crates/aionui-app/assets/builtin-assistants/assistants.json +++ b/crates/aionui-app/assets/builtin-assistants/assistants.json @@ -17,7 +17,7 @@ "ru-RU": "Создаёт, редактирует и анализирует профессиональные документы Word с помощью officecli: отчёты, предложения, письма, служебные Саписки и другое.", "uk-UA": "Створюйте, редагуйте та аналізуйте професійні документи Word Са допомогою officecli: звіти, пропозиції, листи, нотатки тощо." }, - "avatar": "📝", + "avatar": "avatars/word-creator.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-docx" @@ -70,7 +70,7 @@ "ru-RU": "Создаёт, редактирует и анализирует профессиональные презентации PowerPoint с помощью officecli: выразительный диСаКн, разнообразные макеты и сильная визуальная подача.", "uk-UA": "Створюйте, редагуйте та аналізуйте професійні презентації PowerPoint Са допомогою officecli: виразний диСаКн, різноманітні макети та візуальний впНив." }, - "avatar": "📊", + "avatar": "avatars/ppt-creator.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-pptx" @@ -123,7 +123,7 @@ "ru-RU": "Создаёт, редактирует и анализирует профессиональные таблицы Excel с помощью officecli: финансовые ПОдоНи, дашборды, трекеры и анаНиС данных.", "uk-UA": "Створюйте, редагуйте та аналізуйте професійні таблиці Excel Са допомогою officecli: фінансові моделі, дашборди, трекери та аналіз даних." }, - "avatar": "📈", + "avatar": "avatars/excel-creator.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-xlsx" @@ -176,7 +176,7 @@ "ru-RU": "Создаёт профессиональные презентации с анимацией Morph через officecli. Поддерживает разные визуальные стили и полный цикл от идои Đ´Đž готовых сНаКдОв.", "uk-UA": "Створюйте професійні презентації С анімацією Morph Са допомогою officecli. Підтримує різні візуальні стилі та пОвниК робочий процес від ідеї Đ´Đž готових слайдів." }, - "avatar": "✨", + "avatar": "avatars/morph-ppt.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "morph-ppt" @@ -225,7 +225,7 @@ "en-US": "Turn a GLB 3D model into a cinematic Morph presentation. The model is the visual hero — close-up for details, bird's eye for structure, low angle for drama, with smooth Morph transitions between every shot. Note: 3D models and Morph transitions require Microsoft PowerPoint to display correctly.", "zh-CN": "㊊ GLB 3D 模型变成电影感 Morph 演示文稿。模型是视觉主角——特写看细节、俯视看结构、仰拍看气势,每页之间用 Morph 转场做流畅的镜头运动。注意:3D 模型和 Morph 转场效果需要在微软 PowerPoint 中打开才能正常显示。" }, - "avatar": "🎬", + "avatar": "avatars/morph-ppt-3d.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "morph-ppt-3d", @@ -269,7 +269,7 @@ "ru-RU": "Создаёт инвесторские питч-доки, презентации СапускОв и корпоративные продажи: градиентный диСаКн, графики, таблицы конкурентов, слайды команды и заметки спикера. Подходит для стадий от seed Đ´Đž Series A и выше.", "uk-UA": "Створюйте інвесторські пітч-доки, презентації продуктів та корпоративні продажі: градієнтний диСаКн, графіки, таблиці конкурентів, сНаКди кОПанди та нотатки доповідача. Підходить для стадій від Seed Đ´Đž Series A+." }, - "avatar": "🎯", + "avatar": "avatars/pitch-deck-creator.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-pitch-deck" @@ -322,7 +322,7 @@ "ru-RU": "Преобразует CSV и табличные данные в аккуратные Excel-дашборды: KPI-карточки, графики с привязкой Đş данным, спарклайны и усНОвнОо форматирование. Масштабирует сложность пОд объём данных - от краткой свОдки Đ´Đž полноценной аналитической паноНи.", "uk-UA": "Перетворюйте CSV айО табличні дані на професійні дашборди Excel: KPI-картки, графіки С прив'язкою Đ´Đž даних, спарклайни та уПОвно форматування. Автоматично масштабує складність під обсяг даних." }, - "avatar": "📊", + "avatar": "avatars/dashboard-creator.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-data-dashboard" @@ -375,7 +375,7 @@ "ru-RU": "Создаёт академические статьи, научные работы и white paper сО строгой структурой: нативное ОгНавНонио Word, формулы LaTeX в OMML, библиография в форматах APA/Physics/Chicago, снОски, многоколоночная вёрстка и стили пОд тип работы.", "uk-UA": "Створюйте структуровані академічні статті, наукові роботи та White Papers: зміст Word, формули LaTeX в OMML, бібліографія (APA/Physics/Chicago), винОски та багатоколонкова верстка." }, - "avatar": "📚", + "avatar": "avatars/academic-paper.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-academic-paper" @@ -428,7 +428,7 @@ "ru-RU": "Строит финансовые ПОдоНи на ОснОво текстового запроса: три финансовые формы, DCF-оценка, cap table, сценарный анаНиС, таблицы чувствительности и долговые графики. Все значения выводятся через связные формульные цепочки от исходных предположений.", "uk-UA": "Будуйте фінансові моделі на основі формул Са текстовим запитом: три фінансові форми, DCF-оцінка, Cap Tables, сценарний аналіз та графіки боргів." }, - "avatar": "💰", + "avatar": "avatars/financial-model-creator.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "officecli-financial-model" @@ -481,7 +481,7 @@ "ru-RU": "Помогает установить, подключить и диагностировать визуализацию Star-Office-UI для предпросмотра в Aion.", "uk-UA": "Допомагає встановлювати, підключати та діагностувати візуалізацію Star-Office-UI для попереднього перегляду в Aion." }, - "avatar": "📺", + "avatar": "avatars/star-office-helper.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "star-office-helper" @@ -534,7 +534,7 @@ "ru-RU": "Эксперт пО установке, развёртыванию, настройке и устранению нопОНадОк OpenClaw. Помогает пройти настройку, диагностирует проблемы и подсказывает безопасные практики.", "uk-UA": "Експертний посібник зі встановлення, розгортання, налаштування та усунення несправностей OpenClaw. Допомагає С налаштуванням та безпекою." }, - "avatar": "🦞", + "avatar": "avatars/openclaw-setup.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "openclaw-setup", @@ -588,7 +588,7 @@ "ru-RU": "Автономный помощник для выполнения задач с работой с файлами, обработкой документов и многошаговым планированием.", "uk-UA": "Автономне виконання завдань С роботою С файлами, обробкою документів та багатокроковим плануванням робочих процесів." }, - "avatar": "cowork.svg", + "avatar": "avatars/cowork.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "skill-creator", @@ -645,7 +645,7 @@ "ru-RU": "Генерирует полноценную 3D-игру-платформер сО сбором предметов в ОднОП HTML-файле.", "uk-UA": "Генеруйте повноцінну 3D-гру-платформер зі збором предметів в ОднОПу HTML-файлі." }, - "avatar": "🎮", + "avatar": "avatars/game-3d.jpg", "preset_agent_type": "aionrs", "enabled_skills": [], "custom_skill_names": [], @@ -696,7 +696,7 @@ "ru-RU": "Профессиональный UI/UX-помощник с 57 стилями, 95 цветовыми палитрами, 56 сочетаниями шрифтов и лучшими практиками для разных стеков.", "uk-UA": "Професійний UI/UX-помічник С 57 стилями, 95 кольоровими палітрами, 56 поєднаннями шрифтів та найкращими практиками для різних технологій." }, - "avatar": "🎨", + "avatar": "avatars/ui-ux-pro-max.jpg", "preset_agent_type": "aionrs", "enabled_skills": [], "custom_skill_names": [], @@ -747,7 +747,7 @@ "ru-RU": "ФаКНОвОо планирование в стиле Manus для сложных задач. Использует task_plan.md, findings.md и progress.md для сохранения устойчивого контекста.", "uk-UA": "ФаКНОво планування в стилі Manus для складних завдань. Використовує task_plan.md, findings.md та progress.md для збереження контексту." }, - "avatar": "📋", + "avatar": "avatars/planning-with-files.jpg", "preset_agent_type": "aionrs", "enabled_skills": [], "custom_skill_names": [], @@ -798,7 +798,7 @@ "ru-RU": "Коуч пО личному развитию на ОснОво фреймворка HUMAN 3.0: 4 квадранта (уП, тело, дух, призвание), 3 уровня и 3 фазы роста.", "uk-UA": "Коуч С особистого розвитку на основі фреймворка HUMAN 3.0: 4 квадранти (РОСуП/Тіло/Дух/Призвання), 3 рівні та 3 фази росту." }, - "avatar": "🧭", + "avatar": "avatars/human-3-coach.jpg", "preset_agent_type": "aionrs", "enabled_skills": [], "custom_skill_names": [], @@ -849,7 +849,7 @@ "ru-RU": "Разворачивает запрос на наКП в полноценное Описанио вакансии и изображения, а затем публикует это в соцсетях через коннекторы.", "uk-UA": "Розгортає запит на наКП у повноцінний Опис вакансії та зображення, а потім публікує це в соцмережах через конектори." }, - "avatar": "📣", + "avatar": "avatars/social-job-publisher.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "xiaohongshu-recruiter", @@ -903,7 +903,7 @@ "ru-RU": "Социальная сеть для AI-агентов: публикации, комментарии, голосования и сОСданио сообществ.", "uk-UA": "Соціальна мережа для AI-агентів. Публікації, коментарі, голосування та створення спільнот." }, - "avatar": "🦞", + "avatar": "avatars/moltbook.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "moltbook" @@ -956,7 +956,7 @@ "ru-RU": "Создаёт йНОк-схемы, sequence-, state-, class- и ER-диаграммы с красивыми темами оформления.", "uk-UA": "Створюйте йНОк-схеми, діаграми послідовності, станів, класів та ER-діаграми С красивими темами оформлення." }, - "avatar": "📈", + "avatar": "avatars/beautiful-mermaid.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "mermaid" @@ -1009,7 +1009,7 @@ "ru-RU": "Иммерсивный сюжетный ролевой режим. Можно начать тремя спОсОйаПи: описать персонажей сНОваПи, вставить PNG-изображения иНи открыть папку с карточками персонажей и лором мира.", "uk-UA": "Іммерсивний сюжетний рольовий режим. Можна почати трьома спОсОйаПи: описати персонажів сНОваПи, вставити PNG-зображення айО відкрити папку С картками персонажів та лором світу." }, - "avatar": "📖", + "avatar": "avatars/story-roleplay.jpg", "preset_agent_type": "aionrs", "enabled_skills": [ "story-roleplay" diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/academic-paper.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/academic-paper.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1a611106660746fb3be86172681d9ae14614d2b2 GIT binary patch literal 56366 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 literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/beautiful-mermaid.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/beautiful-mermaid.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3101d73973dd51698d573aaf28c30ba9ae4c4ca1 GIT binary patch literal 52295 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 E2Wr%jQvd(} literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/cowork.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/cowork.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9bc3f512bad30248ab114f172454bc29489a8588 GIT binary patch literal 48577 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'a+1Bele6&jl0?(86 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 Lka(>8Z|eU5Wm5U{ literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/dashboard-creator.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/dashboard-creator.jpg new file mode 100644 index 0000000000000000000000000000000000000000..53fe8b568e43a998d9e72138692cb30832caef67 GIT binary patch literal 47119 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 G+5ZC{PN)q4 literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/financial-model-creator.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/financial-model-creator.jpg new file mode 100644 index 0000000000000000000000000000000000000000..87a846a565d9a316ebd9239e601935450a9ab4a0 GIT binary patch literal 84177 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

_UX-(EDfI+8Vh2 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 uUh_5x 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�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 z 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 literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/morph-ppt-3d.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/morph-ppt-3d.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9cd499fe8e4ed7402dbb9f631099b7c1f600a5e1 GIT binary patch literal 57770 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�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�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

J{EfRO< zX;jFCYW?iM{=WFJ$snvWr~qI=I$k*}Fl-EW1Q06bGOy+8mFPrOUU ziUNA22Q)vE}ui+L%EgGs<+HTIPuuPcu;4<1pcd>K~4)d?*v_ z{4fO@{$2p6IcZHzP|XV22l9vGeBDbYTLPb~IIt#{qM=V;(!L&Y9_fs)$Hv~5^a=p> zQ~2WK+(Axf<*u5|yv!kdQz{~ddZ99;Wv8!1WM{FUSdUFXPDtg&Z3|%9CB15Tm(nF< zI{TO#2(uz}QspI9i&`$XHcR6We%PRVYIe6^-c)7_Wh%KFm*bO~9Q$t4UT`32Y(_>4 z>$aCdA=sKYCW;*`@Dt{Vszx9w{4nv>s?|^yR@=xtR@Mjk+F8w8gE>p8w z!D!}X^yNK(Gme_>M6+j!B{B#iMtX^K7`Ww{F{BLZZPHH&XE__|mSH3*3U4Mi2>ztt zajl`d#u6FmDL~R^LR1*wdrwUEW9JLYQ~BLW^SG9h7IE_rkvuG?dgcA{q}RIxMpdZ) z{WIypbkCXcej}E%*`$^W9+lDg)hQ!>PLitDp6Lb9<|KncpzsF&oZ|RUz*a>qH&I!{ zI?KJ>xECCpr1bWxzGASVwO*#*jCc@m;_Y+E-!Ffd8q~e@wkr$!ti? K)A!}y{Qm(o{MU;B literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/pitch-deck-creator.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/pitch-deck-creator.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c9613a11eb1ecd8e509e9e57210918a9e02dab4a GIT binary patch literal 58683 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 W;%vM}7ApU(|5TqdCEhL9_x}K7h_4I) literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/planning-with-files.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/planning-with-files.jpg new file mode 100644 index 0000000000000000000000000000000000000000..72aaef75c4e62801c1e8b7fcf5175c62494449af GIT binary patch literal 45713 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

9Tp+hZTylk}ljTXHd5M&UAlKeKd*<$zv(5I-?O zj_R1~iF=WOPcp9Urk#r%&0AY?{W&_lgN~zo~uZC*Uh?%s%w;wV){)|Nb;QA z_ziOW)9M>o3bamc(k1(&?T;zRo&jq7E_Ffk%R^iR5e9yd4t6%)&ALg&~6x;sH(r@^F=l-APsBaqJxG<{@PGHoxGD)*ONZ>j%{L4_Q zb>-c{z2{N+)>&-f_Q#Zwo{D%}rl@{-dOMC{lI~?0W*fv&B$7{VtDl+o>a!W&TaWQm z`O)9@W|6LV1>dm&{OEeCgOpw-gFb`WMoB^YS5^8{V>D+;~72zkEsBi!mn|h zGQ%-@cT4j%q$pZhJ7Of8I48lv%#M5}xU* z*H7@tc3j(B!SHcb7`7jYE_OF@P3#9I_?(7s*=9*xZq=lXCPY4pG z@`(@ZFu70TlnOpkE_*Pjee)VmD5vY;KMCp|D0TJb7ImY0;KEgMTq3H%C{gZ**-hFf&n8z181xX{zE6FRDcR8~i$V9$L)+8xkzveZvEGiQ+V>%y4hPg+ z_1D8zh$eW}eaKtv)$0nxW9G3-xcExit-fo(^zK_|LE?2__793;*49b;SILhB?KK=} z6iF07Dj*7=b^*Jij$?LsC8s-bc~ZB{!o6p#YZ|@A?s?0{^a1oCUZQ&47?8!KIBO2s z!1&SLeud>aQkXT2UHSh2koBOIV9H2kIf4#E8qr-d>R97X?2hO3ewLeIrxMY*xdS<^ zzF9rn#SKuuE--s{9-YC?bL<0Fg{F6xkKK$9iTgWAW9ISupTCp*Myp-UI!r>TC$fnw zNjmH7g9PFN)@3I)UpXpcEw>XXC-QG%Mna=+J&~P5R zL~YH^mDniyl5>Z_euw2Q6DA93H)J#a05R*b&a@{=3@(^fBL4s)c0ntBL)|?e5DjTQ z7;ubwdtfqzo?Ksm>bHJNJMQ3LXv;!!iK#S12xr)xxYnj`V6iQi*V>q1H#wjJ_ z{{UNJCvkfRPcg(&MJ%5-jNS@OCLM@L)Uvp52wH{-j2+lz*ZU@p3yZG&HtYSCsVuJ| z`O8_C#wHcJV{A1Ha!(+R1ZiYDl?G(ig=p*H5Ix=K%Jy-WBll_aJNr0s3kj_*MsZ5H z9wUJjjp+UU4Lb>Evx{{Y!)I36%J;g?_R znrtf+PPQL(JYZ^jTbTZG2@~-~MH81y)`Vk+6~eiTmd@_iC2lUgjnVRng!$$WFX9=? zXV><|b;R7X2c^7|t3+euV5R%=vHLqsBF+m*xH~4Oj#8=Uk`xkXlFV54>hfuX0Ben}E0(a%~7xSw>C$4fg_u)9C13%2v z8WDj**M@2RvddQZHWzL47=5y3_W`8=21ubt1sPW;@im#^Ycs^xDY%-F+TLHCf+ze) z4MT4P8S@ZF7JbAE^kHRY8nLHYZ$dS-=Ng{aVP|>(5%6mcISmqk|PBU?2+oNpI@k6-kwrrTG+K#HK^?SDG>7UUl4}XjJL{aE z5|mlT-0R6$R*vCVPzKuAJion{(rPC^vPEB5T4FHsSJv^)zkF@@)+?Y8K5vCx7*Fn| z+P@mauslx-Ki@4RRQ=%eko(1QmyKwa7d|VF+ZfQ8AdpEkoq!5snJ1&=8wm59IWai8 z_S+=(q1C#Pxk?X0bCfNsB6bbuWkVQ>7~>m}6@CNk>_#4c4Z4TF6ABulImV~iuW%&O zH!X{C)#TR;`TSZ@#u$H7)1L{$Zl&jLY%QgJ^F}kPYioN%63iTEK}8e5Nz*pvIwY7IQcBl**BKjVt9?W?$Bnrhes|UjgN4V$a8{&h~HF@O@;Ow!mia%`5T-4fUkITC8 zBK9OAhL-67{{ZMcn9eBCriPa8}zK+M9*S?;nU#vbqOG46HL&2QWv`v3yp~2ejw!Wy`pO zuKohCy)49WQe#Ipw!M)@y!e{Pa1;*QyH909hGH{qhYq}uaab7C*lr^T&Rjb22Nt(s zS>$;n5O@){RBq8ovPA5Tr!dHJBi~pKolgc(V_DA*;X3u#$BkRh4b8ewZz9VRjMdca zKCczAOiu~9v6FPjR2~i3el;X-46hWUlOi!z90)lbR_&Z#(XL~h&G6NsaO}IE!3WwJ zX%DAqal{zU^BSNzOf@mc6R*kbsDnk)Zrhnz{{TVi^vg;=vca*iAm2A#yCEOeiD!|X zMlS4gW@DKr+G;S;NU@@qcR4Dk%#-XDfcZ4Py#j1vZ!(MbNw!MDv@-$1_QPV5$={#T zG>DO?SkNdNfEf)>8c3yNMRh%lGptuZ@ElAMY{j&_`+q>zKjiBb!?T+XK7R+oS|FF`KSjqeXfRwc?&sQfM;~joVpxUNDSY==j$T9X zQNUIYg5o&b{MH$2X2|64xf8_J3FN}k5FZ-3H!^m`51^HY;J98Gfh=rbhru@db>Cqa zb|Qr@tYDwrL4 zX)rt`r{6pJ5T_R7;3{cko_Qvn%gZAccRR_fD-68F@fhsvAu>$=00kUR0a_=awmLl! zmt^oz_h;x#|Vzr z=aE0|CiGuj<(;+ttJ_{clS2E^#$vSFLT14;zQc2y4fwPgv>zTgW%#qXf9_W&+>h93 zjE}1Fp$Go}4!Qhs>PF-^ZWL#3zy%pyff?!`)(v%OHG~k_%&cOJDNV=W_I1_FHjo*v z93*4&_6o%GhUV;;?X$Oo+1GCq({7`9Rv0qD>_-cD{{Z&-ky>Mm99tihq0R_CN-xya zt-QB)G27drd8J^8gS48_4H|<-Frg61?&aG&yiUC-(mP!o!+H7rIp1V3jqYn1#xL>Q zN1wis%IB#X?m@vtO>J{;k)GOULEL4DkROQG1k&429QN|OQpR&fLy-ow6HULia>KDq zlKgcavTD-37_-t#5R?3s%zI&+Z%V*0MZhc`%bqhil)R6YTYiaw`8l;1%ii8k&)Em% z!w2=OQxdbmu*okk97O~}9nhM{;@MVY3J1t;X*Y#MF>a6kMvPNMW=Qu!_(jitJ?ZfSOz6VqK!)Ncy2UPXnf zcVR*KdYvf0IA)GsT%pQByxf0@wo>d`@=bvUmV9n;)Xo?@ezDhaGF#ipG^`dl)Uz?{ z0<@PLmmbEZzLb#`=o7e=p&Bn~f?-h3@Q1&d1Ia1gGy0;gE#bO>p}2`9iN;Khpo3a{ zqtRd(=u1tOmndY2cQ~%NWs(WfcwEOUY#Cj5f;Sq`ENElc1Q(m8>P);GRwo!)gZIbK z)l0ZRyqu~u5ylX111j>9kG3t2y_7Hg&cu}bZ`y0gmWtZ>f@4?kiD#Q^0rw)*u*Eb+ zIb&BsGAhF`Ysx;0L4n-GePQTX+_45O}`5QghP&C zmlhL!ap*U3#^Y1NCA9L}&b*nSa*n(RIU4eNd~I}-&5u&?3LnHak5%OyXQQzDE=2)I zjUpzw;We4gC_ovr*b`yC3_CxYTw zQ9gZY$eVHR3ts$;{{R6*5;9SlI{@NqM=;@p==GI|-xNSU;@*EfepGQ2W1-VT zoqNX+d$+YP;l8jt_;EZI(((cdOBg-}v}*Ffa*|@!7Q?R$Okdy7@<)i6v75X&^(Tv* zABk%bPF1Nrs&nZ}EO4hTR|vdKLp(ErVUb@h93|0z>U^SY(T@qzg=ph)G@A`S{K8jh z*2=Dh9YZ1BtTP6*k3ylH9_t1IDaQCdtN2r+#Un>56p;>0tTG_#(Y#RE-FdvtmAuFO z4fal!-;ff*Gr!Z9^ctXsTZ!X>1TQR%6%=-pS~r0~fmjIBCb^Sr^6@+ev!kWo@P;Y= zPNdrEII#Y8*gOZR@}PhH%MKhMYSCLkeWh4kxf!XQS-cl-L(43uEG`em`m}RO@l74g zEgdDdbD4r&)i;$p$A>7es8RTtiL1-Ii|fg5?Bbm%yC=m>PQ0sm z2i-j^THw!m<3B<($x&9)JU21CXC@3N`n)81a<{Mw@~GuB9)G_qV^)l5RwJX6KbvJW zw1+o=>Q5@b!RTQmP3@ayV|c~xIf$Ff`7?dWtJOu|Iu;p1D98DYhFmg9==lI1Vq>G$xt~jaAw9MtA7?=5fuBZlgFpe@W^P~EDpD8$O zv%zV95*Ao9j$dFk~*c}Lwx)!{p(_g9q|jJgkX_Z=Ja^%hZ?aVtpFW?p0i zOkwS(D7iQ;zFkb=fX9Is;bn%T20z+^p7lppw2{{YU8gKFh~kst z6EicFhw4T*0a*?e1oK-;B)65LVcNBg<7t1P_>2?emmvp(`a@Nw+uMKhlm7s4t{xtw zZXRUs|ABn2% zxi+#NXGb5Kk!X<(@-}C{YSHL@Ii@{;AoZA2Wizi4T18>~r=!=_U9&>Le0wV8GACUvM0Z`jpK<@Bc#S_0-kph$IwEqD96_@tBYCDCy>c*b`aZ2`$4Va zFmoET{=i;n*_?Il97sGj9ZJO*I`x$1JVik$o(Se$(kO3_*xF|%P+CRB%ltKHrLeow zn+VR~FD(0pdi0N>6h2oV%BZ91_aR#)b1d{;AX0khB z>%iPoq=@o5#~PQB$W>9jiQENfb_g&X9fHvO`~0N;0F2ftCP=aI+Il$5-1Z>AZj5qu zVG#2;Y2iA-HTFw-2044EWL74m(pk7rA=5d?oyApRF{zq1cobYxX*_-TbF#iDJ zuz!+2nbqXu{v?yzY~RdL-gQs5;!hrilMM7`{{Zk%tn%Byic_3Oc%VM4Y&nXvy%J=S z?0!6Y7`72%j9MFPM%gEi^IrqJRwv}F7cYe3J`vpi08vNDjy>5mm;0^#D#yuH-uwJc zBu)^aYQQvC3BU$+P-j1E^6h%uD*o@BCMeIKH=aEla$au3kT=NLYQSRU-k)&n37nWWXR(%YZ&rjhfYi3cQ0gnophF5rs-8xz7G^+c!{nEe)FHnIS^XYT|aC^KF1`9<$0O%^2~W zHDNn(n<4%>e>ywQLdX9AG5-Kb)Hl{Yw@EQC{-OT>o~;r80O6B=oPUt}8%&cc>qp}e z9|NmEACaYyj{Huvcb!)QE15ic82HaeaS!rM4b3eR`43+k zv~9{pAk-L$-7w4V3Q1#-W{eL;OPFKpNGe=QvK9B5cWE1x>{$BWDCaF5i`#O#utAo}u$gQ}#_yne(L z=aO(*7mwPjOL)Io2&9@f+{0LwMcpG0eR<5^y=wD`zk2k}&DLUkPpH3_p1+;`_Cr;i zT+N(O_fUNYIupvfrEiUS)c*jzYV(PY?OKbwb)Aoi)JPl16xT5?ZhjPR2h~rBqj>#_ zwday|R)y*9Pl2SniMQsorC4U95!3RN`C#^m#(i2iGtx^R^G8O-a)h^d>cuA(xJ~5$ z0K0{c+B|CvyBGLfwc7sLAm_)o zRn%PMBn{(e=wGid4Z2=1xcsSlqQ0r{trmV>is7gH06H>Av9Br3OLFpTUqyXHR}UX= zDR>%+Rh4s7;yqlg$c9JmsWrZ>Q=PkoJI+3jHP}K`Jtq8xJG_TCVtQ)KhczS`g6}<& z?EBp>DbJKxdU0nuv{iG`Yd;cyBhXbY;YRaFp%5tCHEI3ln&`{L_3m6oJU5+6hDTIh zvyh|TQAQ$(B3;O#N4xA|s_Mx7Rv8}yR}hRhC;Q?lqwDa`Z;e?iXLrph#6LcM6t6EQOBl!Rn)SjrmJR!O$}9 zKC2UMMj3E^=2R;PUREg&u#@?H8uDVlCcDo19;(V>eoejIA1TkB{vRI*oa)fk&q-nX zvAO73MadlFZ#%X5Ld1OU8y0ADj?r>IjPKQ>w*GUB!`+KH54(5S8eM2&y^ifiqd3XG z5Y?l&p~3OEF8=^!)Rb{UO3LUR7&5TUNZdix>KzKO%o>^&g|_Wexa+x2Zt7(2$iws1 znu)jFyMVwFSiSyz)-9qg5r?-$I+#3RL*_At~1G%PXp2N zk0yFY3U@7s=1#2!T=D4}y8~;swk|`+GG4*QUNMMAg<&(^$@?|*M|qCnQb_YnB(jpy zNX4A-Csv7C^LA2QHu;WA_($0orI5rh>23bG+J}P;)InA%z=j7R4`J1y7~q}{?2D)Q zShm1>%fnd#fdpm^OJ~~=_Znnq&!nVQIUhBSUZ)A0SCc7ogAs>=qx3FUmu}#A(Dimn z$%8)e&(&PV&sxhLc?i`Tv~nx2Sx#cDr%Q+uRNTYhdT~z-q==o|5Xay_U_%k7}LhcN(_D?PvP@+xK3E-N!w5H`eyU z(~uVKuG3f8jJJM>^djz#-x^0~oJkof>$r-E`N&cG$`7r%hn-BSQNp3F&|wMqo%q{AxSX2IrEt8oV@aWSrCwBSGGWA4Er&^l-WZN%CfgJ78lakMYnbjWq-ds$=B~A) z8d(M`1-0f-Uwjr{3d>)Vc)1!!484-u56GQb6+bbhcBj4>dQ#dc%*Jv&J1OFL`s>m} zXE`7yqO z5-q#ik49JIM9g~yT}WoUo@2e_X8iSeJByK{vPt{d&b`AkT2rPd5$tex&G$)j`X;>| z!o2o>IGlfWjQ;?v@cT0U&Kvtyf^o3!VZBcgScQc6b3ek501)#xlkeYWz%RPeds9K zM0aK@%#*&e z%#Ixxs}0N!L{*lRV|IHI^vb*@0qYvldz@2|u;^K)5|NTF!ob!1$U=3q7B8g*(0wRo+M&b5` zC!>&DlP#eTOnW||{*`%$-PpEQFtU!v8&v!HS{r%KVAhOxpyr$1^c&m0beQAncAhi= zBmgret!x1F=h}Oe00S?iU0Mk5Nx%nI7aDIewM?>6D!KGPr&LD~;ttE>wSx!cV1 zPu`1VPoj^$+U$5pl-f0k4Z;`jdYUJKcZOk%sdPofaxzQ68%tKI;A5Z4fy?3uZvdlSVNU*DxoG)EX!^+})GxjVjj$u(Tk@ZW)KylhQwI z>0BJ%EG6uj0r!oER*GGDu8_gpn>dfYtY0T+&u-D{nSvo>xD4so$n58P8pC1bIh5{Q zgU4P*w|yG(NU&=glLgKENhscsJvIEss|k6? zIVXC5FJE^$gDmgVKwI1@d5y)?)4y6*E`9p6Mjl2TEa!Z(enaieEw|@z#GG$|{{SPY zS&@~{ZXm=e3c)n16T-5Lznt6l#WDUyux%y7F<=%sxtaT6n_>5H`W`2X z*kMs}@2*ll3B8YitaDAS?}I^xskDQ&{{U#;(tym@lWUnszqH>Be2Ej-PP>@-x!HR+ zim-k~$Q_O{_1BVeBIJ$jT48tQxCDqg_Y5K)9lEyc0A^~!-_0x_x9%VZ$G7dvh*sv> zSRbn*l{Dzl$kDjTkd;0oR)XI0?I*Eq@g7=u9ra@__>YM7xS{!>;%OI@>byuA*0i%m z=fdwMy0(nTVIeLUe#?k74P{tHmEzcDNG2CB_a@u$HDRZCUCv2(lG(q-D$?%S_AYYH zc;`+rus*ffV?y#WqK)jwAy@iegIMMS=H^c18-G33ifPUxcbZuuSw-=Bk=|KaNu8vT zww805IJ**EMdp2#MI>*_6)(R73JM01=@NW!3MFN48yS!(_4RY zoc5toGRaq3XO3L;CrAef zV-<6Eb#~mVyP2mvWOCZ@+#3f?Gk9xU{0>{{V8E5~7YcVOXI> zjx-r6D98?l`sZp-1Dy@Nw)SpH^J9B&@T=>kvaz1&_e6yFp21Q`^Gfo_b9Z9QeWzB4 z+VU-CyJ5Cd$X@~W_L157-V)^oazXNo`i*)kf9LotVa{^F@=y92wVRrgBh+tLKsya8 zs`Wq~1E-1Tt__J2^4kbyJLH4VHHhd9>|1c_l(|mio`Y5H8HiXCFKnlTcZ%%z?xDA( zkl;EyhIMIacY6GrJ6Wec;h{B$Xf7*rlU^9?)9?Ck@D+w=W)WkP%#C?38M?peq*RRp zMyiN6DvW^XWC$SA+QP5P3Affr;xsPZl$+wST)n_*-b8L2v-$m@m z?%`LOJ%irnXRwDp@(w}#s^>s(sdF$-bqBmKsr;SI`wU4R@y10?4=0yL=kXX5@F8l0 z$@UzZZf|a8@X0FAMlee}j8+l54%vM(`O<)h6#!Kmf{cgJuBPW?$aNQWTuzp@vfN5? zjwLK={_XGY=DU}zD`((42CWja<=shm{aA-3KN0=_(u*HCuon@G<+t17y}I;k6aLb| zRJqQ0a!G$fLoh)b2&g3!CVyCOA4$trLbCc*V~ld0 z$O<@`!>ty^!YgIogVH=(xA+6ZXIRyN!|^AGeAD`IpJxwttOFA`Rwk2gh5ZSK-KAja z83<)zm?Lo&8?;UtYBv%fW&2X*aT@Yhu7539wfuNq9VOJea@dL9ZoyMaB=fw}F=-u( zG2(S-orf+~zL0EBMlT-I`~{BT{{Y$+1yFpvUX*{R_v_HiU!0HoGIsRSY$u5B>V{Jj z<~MeVMh>Br<`2O1C(Qr7S(5MCFR_9@pYW#;5$uQK^?8McJPd&jATE6 z^rH^uE`{Vn z^3^UaWD-RCh}H=QFmkAF$k{H@#*vlAYI7f9Nis*)J9r9~<>c7Diu5t8X4?pZIXyYs zsSw}deU*QIbBNs;?xf|nVC+%A4N;@XBF7q+b~!4I=CC{&Y!jZJCc0tnLBM|o!SHDNfd))jJOwrtV5@i$eg2*xcjXtRO2GLEz@)*S_ALzrr@ zkY=n8)1;a>`pvh1sV<$iC!#+-jyt6>T4x3vR%!P$??nElrrTHGqqP*ES$5+ul9F{5TqAWO9xQvg{y?h}9Fk zGOVz>B#LuZQ;`*d>1s=q7`90Lla0s5fefLPf~RO8<_|z-4q~Ibkv2D^Dm$p(w~}}t zq>>bRL=PH!xYwzhnv&v2?Z|K)8{6A!2n^S9tZDhTfUIvxt}pY3*E@S({{T0vwOH8P zU(LKk<+NeQeHUgfYg_9o%yXSi2YUv z=uJFJy~Q=^j-nG!bt`TmN3w}5b0nUNFhnloDz4H_z$+Kh*dWdLwRLvDd19fSBzcw)GO#XMq2&h<5lX!O?E z%VV6;cBj{0>(IiqqWZ@u=l=Bv2kQ?5SZ+6m;#(k`ET6iQV|s;o7pmk^-Aq2PJ|dR! zzOo7ziQ0rvyM*?ULgEwk#R;PQ;@3GJeQTVL_lsQYU%Xo9;{D>$xrBXsH<5M*G;de2 z4I9VoP$=9?-(N2ZC7Z0o^vMdPn1G{sI{>UtO6+YjOJDC(ecgyX^@-yb*qQ$IH_7%y zn-^WRyw_6*t>ZE|>>sURT0IrEQ(k2>!*YE^{=dTbmJMrvo1c=O_lf$7zrt?p2{NZH zF3D49);17(MPb@aiCJWf;^r>wzoD!@N^twEmSSyW;U`z)NXqCP8CeeIQ zFNuae;On31R<^KN!XmbeMxUASKf_ptkJ{a4@PBug+0{NGuW-xD5=`-DA7qKOYdu+2 zo$cL=@~ti;i@@yoRhF6ECd=DooN-S;)uxl-S6k*VHwlJS6Qs$@h1Nylgc0;HncOPs z_SVo7b#oM7iH3g)yVCqR9hS*0$^QUK)$WzzR~f7YEmQ7oZ;7d0<&eoUw2pqWu_vKn zqxW}NJpTaQ;``lW?yC$g*1&v7>>^&glEe7Yp~f)D{%ZaM;`vfK zNHdMq{{RaESsn+bD=fFvmv*p><++7F6oRJG93Bq6`X9mRRQhFyC(J`U-vkvtnqEH3 zYiMEd&COk7n5EXquVu@E9zgu7X(W@G)s`D)W3~uDe*5ij z;o?99laL$9tK4?p4A$6l@9pyg#v=n@)1i=T&eV12z}5xei;omhhe94+%NrNj)hwNOWDVW6m%gwFWcW09SPxx{9>>C z68`}Di2nd;hJoDJq$*62B z;2$Gr0(eF%7Q_rOn`ll>-E6+7*I{M-jiES}DK^WAt(dQ|eyt$M0N^!Qry|ZJ`?=F1 zx|MYdI2yjN=8($=RCSk!KoSmMkVfJw4##DODDLx?KK}sLAJ(9rDdG}B;n4Pv;apQ2 zOKjq`%2~TxdaX+=lgeb3%emf9M+lG8c~0fnHR8*ipl<68SZw}li`m?M>U4jD3esF4 zV;EUT_D>(D5&b>%%E;`JDOXdIDc%mN3+JFJOvF_QFAt^y}4$5PP??{ zEahLjo~8tX2K)B|^VS?aNh_?6z)7dPsMn zt4p|Ula&)~8`SR}s}RM6dBZF`)OKX|F4j?8B_T9NMf?mw6E2bLe96+E5xi@^E+>zQD-M z?2doopU~4QBNcE}hVVw9NI8N*6@}xQp}sy6{{UJ95wrL{^6ncb470XFuy(QbRwIc` ze*T}K5bDN1T||LceiJ3mQcaw2{%ugj91#fNK!`g9X%zgqqPH89(r**0&MtcC6SF+e zfaqnO&O0fWknFq|jb2P{x&01`F578dEm~8e#$xx_T70hgVek7zZ46a`3=Tvd%~89> zAb8lT4a8O*jllUwh_4{_Oq;#plGZ6uJW}$I?q%92*>IEcuQG4m3iBrY;Gt#4N)}7n z?N^f6SSEKb>2@GFvG-OZi_LeMM1tN9>hC@$UIT&MV>dZR@^lUUbJhcr-XgE8 zA-qhV(Q&!P`n|H6$?}wDr*nh+o5D4=PQr zdZ;&=ySke4b2ROl>>Y|Y4N9e$DuPMa0IWL*Sn`(a27bis9y+!GncOy-xtQEtOE-P9 z)r3Wo$uaHpM@JA&MeL)A&sUO5t(cXc;FxRD9T>L7ftnnkyzhkhdvUP5Dj z&I~w%uG04E$@x~(G<-*4_f?jZ1G4%YzWjgEt!}OE)0J&9$UU3JtK3G?$b7uOH*t2i z!msp};#|_rIfU<>tZA8@%exk1ys^xkdOxBw-j%q-fr8t3k8{8D6>kJq&@3=UvBrZX zRT%-O);V+MnEoMi*(B^ohItKGLS+Px-fX@d8>qRPr$M_s$AQ(O)8#CXAFt^zh~KJ6 z(pb!LC}lgrtVaoZeC4;z;_Y75p{oqUrLdE~3w4wA6>mIuFs!h*DI54N5x$DT*vR`_ z>_qPxxSm^?+G(4V?W!oGnpKV^EbX{f9fwC`yrYxMcef7>Ou<(&autf-6|;0roadvc zW==zWK^TezjD1nj##1Tde)8q3$-Up3X?!W!aTCS*iW=|iEpZ!T1>_<`{K4W4V;UQG zYn-@oH&FLJxTjW*LXM?bcZL}e?$;Z~wDyDA(T~$!7k>5^8SjO<>-vh0M3EKa zV93KTNAOME%vP4|G{+@hi97{f-OGD&(@Ws1*rSH1B6;Ol;!@7rg<cOB5)v#-kvrG6SRKI`hr6N#X6fl_J!u z%XLxOK%fHb8-~t+tBAz5@<+sM@z;h*UfYs)q08M-O7U*myecUcMa^hdFNJft+}jV7 z-snEIycZKTlJhekkaPZnK>q*(yDB3)kgB6HPhhN95NrFK#$puN8veSGS==fDS&l#o z!t55x9M0LBtbakOTYxNU9&*VB+$%HGUv**k?bAA&$GtbPt@AIUqMGe_T@;!#TJ{`Kw z&$r;o`;oVb_AU_h;Ew5K9Ifa-(S(e<@K`Gv{bQ8Gcq+{ivU}w>9RwnJW^O?(Cjz>@ zwg;1aiDA-rGOCN0h{YYW2T&OYCb%FyX@B;1=oh?|vv@C*K70zR9u?lWjNt@Z8s zBd+aLp?7BHo?<$5axq44^i;}_vLGmWZ2YU8c;Mr1(f#Jgjx|36uk|l;McfD|qZK>L z=^aN6XP~_k7xH9J!a+L2m;H^{mk4?09m9GYmbZ9a#~F)%&t8|+H*WT}>m)h>)1{`! zzs#?HlARYg0iWBlY}FCy?xx??p*q z{LLAQ`Xc+2w)sM4*inG>jPTznbhlu6$DYosOBUqxFi-4iYGMpb_6+bi~} zM>8`=7P-4{jMGQD4g(hNm~*=5n&hE)*z?TIW$8wwmEw%r-&8mF)AjFbT+{X8JE4;+ zzGK@`c`N8zLhi;YNq@|O{HDT*4CACofM`hcUoYiMA1bV2;@x)Mp}~34^741VUz1iX zQDg;j)Vdzz1vO<sO1>UCLk5tC<#Fu3`B#DRzx?krA5?{N^sS!1Qd?nDHCr2NU z5My6V^@bx~YKnDJxC%L?qzwrXH@SoE1qM1!uwMejN9c8)_2%qhS?RW}kMf`RlE`0G$ml*AT!l+X zS{2=LU<{j>#<}7-3&&-rK}LnkgC)MwxHCPJw4MDYH!JeI>wE07xuKSW!UC@P)9!-L zvZ?}(jZw?luV!3u+S`tcL&tq#tgk7|3;yyW}#l$CSVnQfLt*ECN#-!0m{R}RE?he40;L&Lme`=8ri zgoKPqwIdTLX1wh%Y@YelVXNmGUp3{aqLxRkuY-RmL$7ed$5t!*L5%_i zXSrud>Zrk7&CRJ468(BXY4fn(FqxK`GKb@fSzOWfbrU=ro;uNZI>_kUDBO9 z?9``$i#N%nUaB0h)Y3Mv}E&I0O`C@nF>*vYcig4xi`n&>Z;1Z_wTu@UEkYSszVAS+z zu1UjfUyR}Y?IEaJ*Q)o}ZSSPlqO=cH`BiH4i4*P5?AmXVFP&MZ?DcmK~rdL}BSJQrQ{3X11JVXgfSAzzxejMJ?G}_`(+ORH3Ul@p^i7n0^! z(x!wZ>{nl^YphesN`}GilHxx%Aj& z_d|L04WB&My?VV2diC3=q>VImySEKvGVBd>AX{I#UoN!c7FUR3i90)9eD3OgGAA_H zo{FtMz}rinW0z|BiY;Nr%=*S&eCwJ!xFW|sBod?BDZ+@aL#w-;{D-OC<}=ZAGj;S! z>^#-Tlg#vTHO)nG<=Uh$#<1mtuYxJm-afZwN$mjr`My{UrIQRMuM!)Dr*h%fDY02A zf_TZjla=Oj?J1I_R@Ww)6rB2p;d9*|ta8s~>3prCwNpu=IqAu3Cse36?A>`dwhl3} zfiZuUc-;2<9=&Vq%fOgD{YKo!ijB_4e);Ve(jDR{_^9G-XSdud0TF#yZyqO^CSrH@ z)hhS4?oR|YZ*#b(2mLkEdhPI2l@Eo2)--S7u4nbiqhEesTHi}2j4X?ct}3) zj+Y3M-Wp;<+ZP(PYJELPl)1D1-r(e>o?I~IHuf%NUPoJ67uQ>0Xj!DkS@T99x73W5 zdy@RaN7m*v$?gy5r82LuYkj>T>#-!RL((nfPW$ zGgkUH$5K4yLBQ}Oh|lp`sBz5Ua6`|xn}k$l1HDjdxcKM%ZKI43LV3Jfe{CT@6=y}p z*ZC#!RYmO9Cn%E&+c5P4JVg4|{HLr*pZf*5Gy%fwV%p@C;0Td@yEJd(i&}X?MGhqs z3dX=UYDeFs5|S6cSYt9KJcqF^+3+)Zk}~06!yX+7#jFD1{p)U`Je|i>;!Z!76;tA5 zAxUI`YrabI>;Wzu;_T5ciX5}Q7dw8fW9f03mP|NW{=x8b#%IL-s3V^JUca78wA26O z{l&qy_l4nw%W~#9_4s1!`UN;hWj>^;G?een!L4$!cEZ4q$2c4;r3ZZc7*1>Wkb-yY zMSP#4Zh+ss0lrt7<2@Sdx#bVu@p?QC!P%z_Z9#x#1L>~}XgNLYyDmb;ZW$yK z+Iu+J=030oUwNCl7%#cop9L==3z;OskCbWZE{qTVz+87P6OiET|GvM)?Wy*!K)T_t zIrgWqECR}T5qx$?45hOjt@>}uu8&9g%7cTgCODj*OCjhnM~3sjz>f3Dffo-NCMnG$ zGkaVZpR!Otk7j|o!M?zJ120)|TfXd8#gLD>{Zy??7^j+rdHP)^#t)vG;-1RC(V)!F0Q|kDyHAMKZHs&6}!*o zkx@1oF2?c{Y!QAhn3ES>6#wLA^IcYQi7@s4rBIydM=m+248OU?5m%;WeMm!mYdXYFZBHySbpY~CE;w85k6Qdwc+d7`#tY~ z`rV0!yHgLNS>e;0n7HqleJKT}V5=8GC~-?3NhgYsZ*K&=+N|CuV)m4&!n%Qa_4>*U zrC_Dzl!XM_b4AY-V=f;<|xwz z?r+GVf`v1Nrkk7i^XK~#BL{X~=SOc7&}(6k7~@Q#FFSDg%}@QukMWO7F+5l2vHl%% zlOyI2DkjgRvG&JAmBmT=as9~K0+y)#9yfKnl-|Po73AB0xL*hmGm`gN=r(MAEY(Na z>tA5ceJr#>%`x9*d5H}*bEUZI+aC@zeAvJo@TvcGZw<&FNHPD$8=}r$xJ$Rw!Oj%Q zQB5I{yyJ*DUAG$L-8f`CZs5+zPS9XI*=8*w8laVfS#?(Qs;y4UJpThF8)fs!%5 z{^o`M?jpWDv;qWwF)B?fwl{AufM3HKJMKK7YdEguga_g$0CB~L}IkIYqhz#>og&qh_Qn*V= zcS7+=4R5CcTrD!BVx=V(-b8gyO0B4kh@(1hn8r=AX2(m$ZMM{>sU_2 zdsBXsnkN<7+5Dy@QYDw5=@K;A1Vv(#klN~8h4x3P8Z+3w44R7hT(#^#sN6c6|L92t zJhsH$60IPYuey=*T)TUr#v~G>^5@bgm8I7&me^GBl%A-BY8lZ!7Hq+r%bhL>;XgYt z5ucksa~Iix1lm8|cIw0xyVLr2Q_l8~CIMl9jZue^>;Pxe>Cl+Z70SY&HrnOYpfR^aztQSGDsph3%$T{q_Ea3 z#7RT;IGI~!^N)4W)}f?vnxe*>S-g`vOG|W$N~l;OTmRdLW!d~DbqX-rx>*p!!$R)? zrFT(;hgZcMR&vQy?|USq*=w;f7sag1xF^FD6D}lsY>Dn_bV)O#uA5n`BThpsi;q83 zi^U{Vk=r3tQHo{ht>d3So3qzre%eF)e)4@9dzo((%a)Cby#+-i;6Bxhxv4bx&1e=w zdQFc<5a#77IqhdZhWZayNDM53lZg?eGUbN_6T#zIv8QKO?EtVmZ-xSJC{mloq`+~? zszABX=i1HSkTDwvMHw$8SoN7_?~#N-(K0d2>VnODDNx4$ElIw?aQ*JK7d{7n}QIwQWb z%{tQlz>cs5O$5H9Gv9yY^B*j>7j&+Qcs83UmHk69mcO`0w1!)J+9mN(zCwn zs{T}kLS%Bp^ftjcQN9wSdLr{XS+=7@F-K0i{eS82^&c=_q58EO9{DNm(3NQj`sXAQ zq6UHdyeo=~i2+`yRNYYdNa8aP6zN5D)|$k<$t4K*9La`6r18R*=GAcQv_0!101@{F zdNE0I4*ju*$8Lie=q?Uy0*|CWer~d#BtxeN+SF_SE=FRM)5TT0KMA6CmjvBOeSteK zt?UbjL`QsNCB~OP+zO}V@J`4O@OA2^OPK~=?vIOQe+e#6w2Jys{Xihq+ER&aM##KXq3nMeBIutE?pOy@bK(?{5Jw8mDf62&wmJI9PS z*aCpd#R6@TqGUGt86zUu|q<`4%V(q>>VlkpA!3ulRG0Wma@PSClgz7bR>#!Nfx%QIS$X#QTG0mCey?(l*T4Hz(S(q!f zO9Tn*-D*H=pifXZfz59g&P$Xk|3R3cD@%bYP<|ju%BR1Wx83Z7S3*nma*gfXH_vK$ zB}1tv+y6ReS&b1w8*{~9`9&V~h~*-x)7K4OVBIC-$C6_hnB_KFCDv}4YaBBh)tNP5 z!fPxg6?~MOPHfv3Y_VYCXc)^FfeL=V6r%GLh#Jch&QH7Lxo z`uS`6={8lVAR9|SY1u6G>4|Ilez+r1n4p;XP*;o9UbrKni_7-LDw}Cwm?Z$<;GqQ5Q{uu?tN}Ko}H?E2W7t#A_0w=){%&u{{_y=+n@j17pjY&qns!}1_w8>z}+`R zZ*%q>i6RV_wfl5IDp(lb*IZ=iu2nhlv$s3{!Kx;Tu(22AK)aBaqeLu;LNQTsZAtk9 z#)=TmE=nBVU{3~p2Ut1D8$i(?_5o_D?^9Xdhk#fV)?wc?MzDKeL$ZKb^FIRsE!9mi z5N9xa%8>yZwvv(9!pyF~=>seb8%kO)cjnj{32)lQ!y2ataajB@ng@I0uyHzgHB@bB zD3`<1#M3$W_sLIfeDSc{*q&fqu>Zh%oN9VTI3bWL15^qs!nCv`i-?X1U-NdylR-5T zvh~EC<;(9;guSQ~X=mn1@__z3b~j6UQdHzg@{aAB{;{zmvS2?|dIpk|)$37JC$NnJ z1T`naPSzoTnY<#sDGX;7ID&z*M_51 z(*g1Sdc{~k$*tozo4!dRNbyN2{RQ#UB1=*aF}e1tf+j*V!$0VbVpWb z7Y9D6(1#`((S|^-%)&huYUUsFXM@+nc_oCi`GfO}ao^*dIM1DI1ysNR~8K^?ANT%vsG0JZZg=F9v?8|W{9Xuk^&5LXm!;-f)GcaZ*qk&4N|r0e)>8anSF!{jS5}q6Q^wzeL6vNXZeKMip(8 zW!Vs*ZZGv<)j!$iK}WE`yw3+wK@%} zBd|f9?nctZgFhIGCI!Ds2;9qJB$r&6OIMgT(ALcYS~PSiNbxeUX>is|1ZWUQcs5f| zJGl9`R8G&BtS~(Kf($M(+4=WZax~fnMDQj$JB_`4QBehO1ppoy6kytXTX>UHqCm=G zTe|5s;E4p6r4@LP$AnX=8XVdoweilLkw2?D z5cv>`>a*rrQ9)c9!K#>Go4IH)1}UahRSi1*!v45RC^JqKhvKD1~vWU9eJxY5)2x~#{e#>3r(wtZy(CGgYl>y zPVv5AR-lWl7An^;5_NB!kqxu+581sQR?BFsrK?^Kfk3N-w_qL{5;i-iM8n^A-|Oce zmS_sF15q3&q>$l>LjH%EuYac{kK<_GzD5#IdDZ=`^8YFJy#sQZ>KVYp@Tpe*@3i7k zEbnj9AOB5Wdds%V`x}>38$%Z^|99e93v)o`k%7>=%d562szHvl5JnT*zV_Z)b*nMq zVy}Z#?)ty8ZMzmDaz;n(FZY(63`XgG$EKRR_|~oYI(W=zN9`SN8yYI7QGuAe_sbpZ zjNu`;@`@We?LnE6bT1o0(K36{ECW>b0WNgT@_%=8`Saea*h_CIr>ZFkl@EplSb7Vd z{l@JP9GoZ^vl{pY<{;dWWBBk2#L=Uyq~Gwser~d6Sgq`4PqGp)6X5LoBr(3zi?ChW zrT@%VC@1KY%PDu$n<>SINABaMHkH=1Xa?T4sL?l-ow6e#@B=Nrw)lThO^K02MOuI4 zsyOBv^wz7EMe+ho+WLD-W<{CYp_E^_kDa_=rPWf1Hmbj#`P&PF3S8Q;<=A{lAgkyx zQ@+u$PLuBn^p5NV=l3*HqQ0o|}6(O99u?(HYVB zLeadHaRcuU3)YyQ>wO|bX>j=(T(=&?vZ;v|c!t8CC`z!#wo@Fn_QvqyiRF8ztc%Byu34U*e0< zrZc8+GdwpZtR(WVScF1tGQxh~gkweuwr>TR!T__yc4bK>1J@{31f9uO4t5)!JpM%c z8L=T^xp8#$s#}eMs=cX()lKr z6L+6u)xfjVq3p#nk+DdFCYKSj@E<7eYcx_$6;XTtT_&c?~=AD9? zyJh;nB9O|yV54&72w|!XV?OL`Hs=@v*<2!D3K_L>J34JQ%6mOW4_U9*GVd-9+G1&J zP8vl)TzGMm==y~6b2aDB~6l(kI1T&pY-^(7&_9Y5k1;;2aY_3E*ehuijq+4 zPI^6W^d>BmD&$G-U90-JBiuT2y*tI?weXStP^_I(9WvljIn0#zonw?zwq3u+;cDch z^~J_fyD8^rb=iHRo=;NbLPUxlG?3+WK*6cu0XZ8vzLeaQh}4FS!w>=>G*NdgF2A1i zw@BOq9Jq4ABO}e1N8^pH7RB4?#8)4sq|s;g5iB~$H{xA59$iz%EpNM?YD>hrEOoZHXta z$({c14LQA&8IM@7C^xm6CM!1PMT7UiXq_h-PTBcrg3*pYkDL#rA9Sn<==EKzQ?YoS zLwJ^5Os#c_mRm{LB%f>+)Tx+YRB#As?AXa<8DGi-H|;A;cn9MFZxyOvIv(a1)nkNV z>$=7=LPpZ(R$7Syb_vS>ffsPQ8E_yfEVfdnozAXk4fBjQ2xma9@ZVAn=p zA~3AB+q?INq#M%q&1$q9a$ci;XUtY350kv3^wu)9cdpNh#`%byBRyK`&P&}p>II!> zTOgcVeXVLdHKg+OGMhuzmcpYOia@L^AWwmb-_k_&@yu^jzX`v)TdwQwt!M6vYMEPY z%^9oG+~S%o4lj3>Y8l76aEDjx*Ea3i`*yQ`H$+U)Z0R98pHB^FH|LWm8F zZS_PR&D(MLZXffLLe1uP#9P9mjFZ;t1{sRacP{0{oxrYO(U%e?8ZqEDULq>QpYWEj zMCm1NnzF_noc*Lg+idlcSFS{Ou2#Hpr-N~@pU4fG%?}OxncH|1fElF3!csWV%l$U~ zH&mnegspmGSyn8~4N7Y9QEp}>HU@q>iW>7vYc?hJ7L8qm(^n8}7a?7ChtB~vrnNb5 z%YE7~*2po(ez?_fm;L1>D_zj|0_pxz^M=lQUOLMVjnfi`{@L(?fk#IBkuUIUtO@d3 z3mK?`e(d7UV@FplgkrKq0y#j%t0l;7uEOGM5S9PFT$l58R(n zc#tWrC~L_YIF!FV@!_3zmtB>K9D)wE>PBq0ViEwuV3Q#{k;H|ST+?>8PuTK5b`2I* z&IeDc55xcPg58-SJ0+rqK{!n}hQnF}A zEKHmKEwFA>ip;7J@UlwSFx&n>-PthV{TN%;aQ1Btm-LUND2-(tLprtasEJ0xj~SG{ zY~ovAy|GdUd>x{Ed6&7Q(R&1`^;ltBFC7z&U(eN~op$`Uh{ONN`7Z#3(Ns3EV(YF! zyvVO?L}(=l;%Q6aO_g$TNb^Pp2oHv;MvUidfaB1{L71?YN8+-MhFZTVU`q(wY+)3o z@8#7*5oXYY+SORVQt}q9lm6f`X)14iTDgep@n2kH&a=!&{V{z6)Hzl*pA~^6bx@_B>5n1##mXB2zoAkMZe>g>=Cn?)&4Qfe%p*ty5 zij0s|n}EbtZA5+gm_$>pa{#15do@C3uQ8{zP0#qDK7NR9`kIL&EcIQR9q#lfvCPm% zbis$#lbMHo()7jZ#kz!V%owWA=-3d6~F7o~AA zB8Y3IBZgu?JQ-c;YXB|NyD;vKUv67!s4O77!{|@v2$ZSndmF-wF=;wK`fC9+WHcpY zpN`aMfHJ6iIw6~v5h(Nkn+o|EFoK^R^Q(Eh*ZP{i7<(vWbB6^7lprBR3|%R67>u%) zDmob+B^Wv_keHdWsGK?6DfD9X`v#kG1sgOE!69!)L|N5nm{d5tP&1kJNE%xMIs7=U Jx03%^{Xa<<)fWH& literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/ppt-creator.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/ppt-creator.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e2713d323fb6a09f135ab7d96e6e0e8d08983e36 GIT binary patch literal 49784 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 JH~44n{{UkE{dWKW literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/social-job-publisher.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/social-job-publisher.jpg new file mode 100644 index 0000000000000000000000000000000000000000..35f58ea7029eded413c98ff7f66a1055430ee468 GIT binary patch literal 50159 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%0A{bfaA zfr5}$TFC=mvw6)r9cq5)NsUIft^hA5>0lV^`R;r$#E_f@fzwzZG4fVz2CM53f1bYt z_TAH=h8SHs4406G7+sJGz&pDE_f5`%8TuOvI%cV$Cs6 z$p-$+!F#qGuKq#buvj?3M{8?qyM%Rb80kFhOm%@EM(5VZ#zomo>qr#PjO$&1Iw5vTS~^IPT=adU^MSk>Q)9^q#m^$hI)2c! zu}gx0sU!1=&dku8;)f~CTbSLj6+-!%rWuWZyxEHJ(TAE3n!choutOat0bAlv^;i`r z)NWwC9{0Dpi*LK=bo1dSY`A=rn};!15yB$D!o}?Y*|#nt7-I|N@P*Ggne@>-#+AZBTm=y|JOR7lk55|*2lpL-pW%w9Jo1q6GGiAPmo^Co8Lk@g(qH*4 ztP*P>CDf2dEfpt0X1Iqe*u-pn9>W4Xsg!lZT9MKV0=j?1#lbo&`e!{Jo@d> z%^x}?aV$qu?jA)GhGez1Hrq>!h~av;aV0Ip++}ENN?KfYYvxgkpH*LPWOv5z8q0Yn z7-@Tn%j2ouqXJ_-y=fTvU0kph>UL`rq?m2KNW~DHOn8@y0U40epd&T7l3lS5<%SgZ^rl1}h8JywC;mmyeZJw5F7=b9g(EX;le9MnT}`sz5;nr&2+O8j1|_fOhTCQy$@HX3 ze!lw(Kc?FO>&g+~;e$T#Fg-P_TwM7kpY2yo`!!@uUo@bbVZq~8m|p0Zo+-?FWO8nD zR!#mQa6Kp8yPlP4tS_9HVLba)Exo|ANioXE#{NZ6d&bksKQ+sl`Q7?R+9Ux^*a)Tj H`|bY$p2`LV literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/star-office-helper.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/star-office-helper.jpg new file mode 100644 index 0000000000000000000000000000000000000000..482c96ff6ffd3f3314e941304be92ec9ecefdf64 GIT binary patch literal 59326 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 C`(20t literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/story-roleplay.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/story-roleplay.jpg new file mode 100644 index 0000000000000000000000000000000000000000..360c2d4bf9e1f008aa2bc30b2d551a038a617cf2 GIT binary patch literal 52114 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 literal 0 HcmV?d00001 diff --git a/crates/aionui-app/assets/builtin-assistants/avatars/word-creator.jpg b/crates/aionui-app/assets/builtin-assistants/avatars/word-creator.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5c5ff9330d8f6223d5a82a5b2ace30487f54326 GIT binary patch literal 50702 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 literal 0 HcmV?d00001 diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index 90652522..caa948f8 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -290,6 +290,30 @@ async fn list_populated_excludes_extension_assistants() { assert!(!sources.contains(&"extension")); } +#[tokio::test] +async fn list_builtin_file_avatar_is_served_via_assistant_avatar_route() { + let fx = fixture().await; + + let resp = fx + .app + .clone() + .oneshot(get_with_token("/api/assistants", &fx.token)) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + let json = body_json(resp).await; + let list = json["data"].as_array().unwrap(); + let builtin_office = list + .iter() + .find(|assistant| assistant["id"] == "builtin-office") + .expect("builtin-office missing from assistant list"); + + assert_eq!( + builtin_office["avatar"].as_str(), + Some("/api/assistants/builtin-office/avatar") + ); +} + #[tokio::test] async fn list_requires_auth() { let fx = fixture().await; @@ -533,6 +557,56 @@ async fn create_user_avatar_from_local_file_is_served_via_assistant_avatar_route assert_eq!(&bytes[..], b"picked-avatar-bytes"); } +#[tokio::test] +async fn create_user_avatar_from_builtin_avatar_route_copies_builtin_asset() { + let fx = fixture().await; + + let req = json_with_token( + "POST", + "/api/assistants", + json!({ + "id": "u-avatar-from-builtin", + "name": "Builtin Avatar Copy", + "avatar": "/api/assistants/builtin-office/avatar", + "preset_agent_type": "aionrs", + }), + &fx.token, + &fx.csrf, + ); + let resp = fx.app.clone().oneshot(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + let body = body_json(resp).await; + assert_eq!(body["data"]["avatar"], "/api/assistants/u-avatar-from-builtin/avatar"); + + let persisted_avatar = fx.user_data_dir.join("assistant-avatars/u-avatar-from-builtin.png"); + assert!( + persisted_avatar.exists(), + "persisted avatar missing: {}", + persisted_avatar.display() + ); + assert_eq!(std::fs::read(&persisted_avatar).unwrap(), b"not-a-real-png"); + + let resp = fx + .app + .clone() + .oneshot(get_with_token( + "/api/assistants/u-avatar-from-builtin/avatar", + &fx.token, + )) + .await + .unwrap(); + assert_eq!(resp.status(), StatusCode::OK); + assert_eq!( + resp.headers().get("content-type").and_then(|v| v.to_str().ok()), + Some("image/png") + ); + let bytes = http_body_util::BodyExt::collect(resp.into_body()) + .await + .unwrap() + .to_bytes(); + assert_eq!(&bytes[..], b"not-a-real-png"); +} + #[tokio::test] async fn update_user_avatar_with_existing_route_preserves_served_file() { let fx = fixture().await; diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index fef2accb..2269a6bb 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -1242,6 +1242,11 @@ impl AssistantService { } return self.persist_user_avatar_file(id, &existing_avatar_path).map(Some); } + if let Some(builtin_avatar) = self.builtin.avatar_asset(&source_assistant_id) { + return self + .persist_user_avatar_bytes(id, &builtin_avatar.bytes, builtin_avatar.extension.as_deref()) + .map(Some); + } return Ok(Some(value.to_string())); } @@ -1283,6 +1288,35 @@ impl AssistantService { Ok(destination.to_string_lossy().to_string()) } + fn persist_user_avatar_bytes( + &self, + id: &str, + bytes: &[u8], + extension: Option<&str>, + ) -> Result { + let extension = extension + .map(str::to_ascii_lowercase) + .ok_or_else(|| AssistantError::BadRequest("assistant avatar must have a file extension".into()))?; + + if !is_supported_avatar_extension(&extension) { + return Err(AssistantError::BadRequest(format!( + "unsupported assistant avatar format: .{extension}" + ))); + } + + let destination_dir = self.user_avatars_dir(); + std::fs::create_dir_all(&destination_dir) + .map_err(|e| AssistantError::Internal(format!("create assistant avatar directory: {e}")))?; + remove_assistant_avatar_files(&destination_dir, id); + + let destination = destination_dir.join(format!("{id}.{extension}")); + std::fs::write(&destination, bytes).map_err(|e| { + AssistantError::Internal(format!("write assistant avatar to '{}': {e}", destination.display())) + })?; + + Ok(destination.to_string_lossy().to_string()) + } + fn find_existing_user_avatar_file(&self, id: &str) -> Option { let entries = std::fs::read_dir(self.user_avatars_dir()).ok()?; for entry in entries.flatten() { @@ -1399,7 +1433,7 @@ fn assistant_error_to_extension_error(error: AssistantError) -> ExtensionError { fn avatar_display_value(definition: &AssistantDefinitionRow) -> Option { match definition.avatar_type.as_str() { - "user_asset" => definition.avatar_value.as_deref().map(|value| { + "builtin_asset" | "user_asset" => definition.avatar_value.as_deref().map(|value| { if is_direct_avatar_url(value) { value.to_string() } else { From 0c509d51ac2615d5e6f9ea348e38303c987a7cb5 Mon Sep 17 00:00:00 2001 From: zk <> Date: Fri, 12 Jun 2026 17:49:39 +0800 Subject: [PATCH 18/19] chore: apply auto-fixes (fmt + clippy) --- crates/aionui-assistant/src/builtin.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/aionui-assistant/src/builtin.rs b/crates/aionui-assistant/src/builtin.rs index 5a2f0259..0c190ba6 100644 --- a/crates/aionui-assistant/src/builtin.rs +++ b/crates/aionui-assistant/src/builtin.rs @@ -442,10 +442,20 @@ mod tests { // ----------------------------------------------------------------------- #[test] - fn avatar_asset_is_none_for_emoji_avatar() { + fn avatar_asset_is_none_for_inline_emoji_avatar() { let reg = BuiltinAssistantRegistry::load_embedded(); - // word-creator ships with avatar: "📝" in the manifest. - assert!(reg.avatar_asset("word-creator").is_none()); + // word-form-creator still ships with an inline emoji avatar. + assert!(reg.avatar_asset("word-form-creator").is_none()); + } + + #[test] + fn embedded_avatar_asset_returns_bytes_and_extension_for_shipped_file_avatar() { + let reg = BuiltinAssistantRegistry::load_embedded(); + let asset = reg + .avatar_asset("word-creator") + .expect("shipped word-creator avatar should resolve from the embedded bundle"); + assert!(!asset.bytes.is_empty()); + assert_eq!(asset.extension.as_deref(), Some("jpg")); } #[test] From 78d11cf2c7f819217b56deea5c497c89c22550d2 Mon Sep 17 00:00:00 2001 From: zk <> Date: Fri, 12 Jun 2026 18:04:42 +0800 Subject: [PATCH 19/19] chore: apply auto-fixes (fmt + clippy) --- crates/aionui-app/tests/assistants_e2e.rs | 35 +++++++++++++++++++++++ crates/aionui-assistant/src/service.rs | 6 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/crates/aionui-app/tests/assistants_e2e.rs b/crates/aionui-app/tests/assistants_e2e.rs index caa948f8..cbdd965f 100644 --- a/crates/aionui-app/tests/assistants_e2e.rs +++ b/crates/aionui-app/tests/assistants_e2e.rs @@ -607,6 +607,41 @@ async fn create_user_avatar_from_builtin_avatar_route_copies_builtin_asset() { assert_eq!(&bytes[..], b"not-a-real-png"); } +#[tokio::test] +async fn create_user_avatar_from_absolute_builtin_avatar_route_copies_builtin_asset() { + let fx = fixture().await; + + let req = json_with_token( + "POST", + "/api/assistants", + json!({ + "id": "u-avatar-from-builtin-absolute", + "name": "Builtin Avatar Absolute Copy", + "avatar": "http://127.0.0.1:56663/api/assistants/builtin-office/avatar", + "preset_agent_type": "aionrs", + }), + &fx.token, + &fx.csrf, + ); + let resp = fx.app.clone().oneshot(req).await.unwrap(); + assert_eq!(resp.status(), StatusCode::CREATED); + let body = body_json(resp).await; + assert_eq!( + body["data"]["avatar"], + "/api/assistants/u-avatar-from-builtin-absolute/avatar" + ); + + let persisted_avatar = fx + .user_data_dir + .join("assistant-avatars/u-avatar-from-builtin-absolute.png"); + assert!( + persisted_avatar.exists(), + "persisted avatar missing: {}", + persisted_avatar.display() + ); + assert_eq!(std::fs::read(&persisted_avatar).unwrap(), b"not-a-real-png"); +} + #[tokio::test] async fn update_user_avatar_with_existing_route_preserves_served_file() { let fx = fixture().await; diff --git a/crates/aionui-assistant/src/service.rs b/crates/aionui-assistant/src/service.rs index 2269a6bb..12e673d3 100644 --- a/crates/aionui-assistant/src/service.rs +++ b/crates/aionui-assistant/src/service.rs @@ -1488,7 +1488,11 @@ fn is_direct_avatar_url(value: &str) -> bool { fn parse_assistant_avatar_route(value: &str) -> Option { let prefix = "/api/assistants/"; let suffix = "/avatar"; - let id = value.strip_prefix(prefix)?.strip_suffix(suffix)?.trim(); + let route = value + .strip_prefix(prefix) + .map(|rest| format!("{prefix}{rest}")) + .or_else(|| value.find(prefix).map(|index| value[index..].to_string()))?; + let id = route.strip_prefix(prefix)?.strip_suffix(suffix)?.trim(); (!id.is_empty()).then(|| id.to_string()) }