mirror of
https://github.com/Darkatse/TauriTavern.git
synced 2026-10-19 15:45:12 +00:00
refactor(rust): remove domain shim and enforce direct tt-domain imports
This commit is contained in:
parent
15b1aaf741
commit
db52d807ae
47 changed files with 95 additions and 96 deletions
|
|
@ -91,7 +91,7 @@ AgentTaskRecord {
|
|||
Invocation 与 task 文件由 `AgentInvocationRepository` 管理,当前文件实现位于:
|
||||
|
||||
```text
|
||||
src-tauri/src/domain/repositories/agent_invocation_repository.rs
|
||||
src-tauri/crates/tt-ports/src/repositories/agent_invocation_repository.rs
|
||||
src-tauri/src/infrastructure/repositories/file_agent_repository/invocation_store.rs
|
||||
```
|
||||
|
||||
|
|
@ -277,7 +277,7 @@ src-tauri/src/infrastructure/repositories/file_agent_profile_repository/mod.rs
|
|||
Persistence:
|
||||
|
||||
```text
|
||||
src-tauri/src/domain/repositories/agent_invocation_repository.rs
|
||||
src-tauri/crates/tt-ports/src/repositories/agent_invocation_repository.rs
|
||||
src-tauri/src/infrastructure/repositories/file_agent_repository/invocation_store.rs
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ MCP / Tool Direct Call
|
|||
- 应用服务由 `AppState` 管理并在 `composition::build_services()` 装配。见 `src-tauri/src/app.rs`、`src-tauri/src/app/composition.rs`。
|
||||
- 当前 LLM 请求经过 `ChatCompletionService`,该服务负责 provider 解析、iOS policy、endpoint override policy、payload build、prompt caching 和取消注册。见 `src-tauri/src/application/services/chat_completion_service/mod.rs:32`、`src-tauri/src/application/services/chat_completion_service/mod.rs:302`、`src-tauri/src/application/services/chat_completion_service/mod.rs:358`。
|
||||
- 当前 LLM API 日志依赖 composition root 中装配的 `LoggingChatCompletionRepository` wrapper;Agent 不得直接调用 `HttpChatCompletionRepository` 绕过日志、secret 或 policy。Responses WebSocket 建连已复用 `HttpClientPool` 的 ChatCompletion WebSocket profile,不应扩散成第二套 LLM 调用链。见 `src-tauri/src/app/composition/repositories.rs`。
|
||||
- 当前 chat payload 分片读写由 `ChatService` 和 `ChatRepository` 承担,windowed save/patch 是正式契约。见 `src-tauri/src/application/services/chat_service.rs:495`、`src-tauri/src/application/services/chat_service.rs:563`、`src-tauri/src/domain/repositories/chat_repository.rs:145`、`src-tauri/src/domain/repositories/chat_repository.rs:162`。
|
||||
- 当前 chat payload 分片读写由 `ChatService` 和 `ChatRepository` 承担,windowed save/patch 是正式契约。见 `src-tauri/crates/tt-application/src/services/chat_service.rs`、`src-tauri/crates/tt-ports/src/repositories/chat_repository.rs`。
|
||||
- 前端 Public ABI 的统一入口是 `window.__TAURITAVERN__`,应保持小而稳定。见 `docs/FrontendHostContract.md` 第 3.6 节、`src/tauri/main/bootstrap.js:139`。
|
||||
- 当前 `Generate()` 支持 dryRun,并在 `GENERATE_AFTER_DATA` 提供生成请求数据。见 `src/script.js:4660`、`src/script.js:5743`。
|
||||
- 当前 SillyTavern 工具调用会递归回 `Generate()`,并把工具调用结果保存成 `is_system` chat message。这是 Agent 必须摆脱的旧结构。见 `src/script.js:5826`、`src/script.js:5847`、`src/script.js:5959`、`src/scripts/tool-calling.js:868`、`src/scripts/tool-calling.js:887`。
|
||||
|
|
|
|||
|
|
@ -57,10 +57,11 @@ src-tauri/
|
|||
│ │ ├── composition/ # 仓库/服务/适配器装配子模块
|
||||
│ │ ├── host/ # Tauri host shell(插件、setup、窗口、资源、shutdown)
|
||||
│ │ ├── startup_profile.rs # 启动期 settings / iOS policy 快照
|
||||
│ ├── domain/ # 领域层
|
||||
│ │ ├── models/ # 领域模型
|
||||
│ │ ├── repositories/ # 仓库接口
|
||||
│ │ └── errors.rs # 领域错误
|
||||
│ ├── crates/
|
||||
│ │ ├── tt-domain/ # 领域模型、领域错误与纯逻辑
|
||||
│ │ ├── tt-ports/ # 仓库接口与出站端口
|
||||
│ │ ├── tt-contracts/ # 跨 crate DTO / 事件契约
|
||||
│ │ └── tt-application/ # 应用服务与用例编排
|
||||
│ ├── application/ # 应用层
|
||||
│ │ ├── services/ # 业务服务
|
||||
│ │ └── dto/ # 数据传输对象
|
||||
|
|
@ -438,7 +439,7 @@ tauri::Builder::default()
|
|||
|
||||
#### 3.5.2 分层职责
|
||||
|
||||
- `domain/repositories/chat_repository.rs`
|
||||
- `crates/tt-ports/src/repositories/chat_repository.rs`
|
||||
- 保留 typed API(`get_chat` / `save` / `search_chats` 等)用于领域操作。
|
||||
- payload API:path/from-file(大文件,data plane)+ windowed(tail/before/windowed-save,小窗口,control plane)。
|
||||
- windowed 数据结构:`ChatPayloadCursor` / `ChatPayloadTail` / `ChatPayloadChunk`。
|
||||
|
|
@ -803,8 +804,8 @@ service
|
|||
|
||||
添加新模型时,应遵循以下步骤:
|
||||
|
||||
1. 在`domain/models`中定义模型结构
|
||||
2. 在`domain/repositories`中定义仓库接口
|
||||
1. 在`crates/tt-domain/src/models`中定义模型结构
|
||||
2. 在`crates/tt-ports/src/repositories`中定义仓库接口
|
||||
3. 在`infrastructure/repositories`中实现仓库接口
|
||||
4. 在`application/services`中创建服务
|
||||
5. 在`application/dto`中定义数据传输对象
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ windowed payload 的底层存储是 JSONL 文件:
|
|||
|
||||
Rust 侧定义:`ChatPayloadCursor { offset, size, modified_millis }`(序列化为 camelCase)。见:
|
||||
|
||||
- `src-tauri/src/domain/repositories/chat_repository.rs`
|
||||
- `src-tauri/crates/tt-ports/src/repositories/chat_repository.rs`
|
||||
|
||||
含义:
|
||||
|
||||
|
|
|
|||
|
|
@ -355,6 +355,10 @@ const CRATES = [
|
|||
];
|
||||
|
||||
const MAIN_CRATE_SOURCE_RULES = [
|
||||
sourceRule('main crate domain shim', path.join(REPO_ROOT, 'src-tauri', 'src'), [
|
||||
['domain module declaration', /^\s*(pub\s+)?mod\s+domain\s*;/],
|
||||
['domain shim path', /\bcrate::domain::/],
|
||||
]),
|
||||
sourceRule('infrastructure', path.join(REPO_ROOT, 'src-tauri', 'src', 'infrastructure'), [
|
||||
['application facade', /\bcrate::application::/],
|
||||
['tt-application crate', /\btt_application::/],
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use std::path::Path;
|
|||
|
||||
use tauri::AppHandle;
|
||||
|
||||
use crate::domain::errors::DomainError;
|
||||
use tt_adapter_storage_core::file_system::DataDirectory;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
use super::{AppServices, StartupProfile};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::application::services::chat_service::ChatService;
|
|||
use crate::application::services::group_chat_service::GroupChatService;
|
||||
use crate::application::services::group_service::GroupService;
|
||||
use crate::application::services::secret_service::SecretService;
|
||||
use crate::domain::errors::DomainError;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_ports::sync::DataChangeReconciler;
|
||||
|
||||
pub(in crate::app::composition) fn data_change_reconciler(
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ use ttsync_contract::sync::SyncMode;
|
|||
|
||||
use crate::application::services::lan_sync_service::LanSyncService;
|
||||
use crate::application::services::tt_sync_service::TtSyncService;
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::domain::models::lan_sync::LanSyncPairRequestEvent;
|
||||
use tt_contracts::sync::SyncJobEvent;
|
||||
use tt_contracts::sync_automation::{
|
||||
SyncAutomationStatus, SyncAutomationTarget, SyncAutomationToastEvent,
|
||||
};
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::models::lan_sync::LanSyncPairRequestEvent;
|
||||
use tt_ports::lan_sync::{LanPairingApprovalRequest, LanServerErrorReporter, PairingApproval};
|
||||
use tt_ports::sync::SyncJobEventPublisher;
|
||||
use tt_ports::sync_automation::{
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ use crate::application::services::update_service::UpdateService;
|
|||
use crate::application::services::user_directory_service::UserDirectoryService;
|
||||
use crate::application::services::user_service::UserService;
|
||||
use crate::application::services::world_info_service::WorldInfoService;
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::infrastructure::apis::http_external_import_downloader::HttpExternalImportDownloader;
|
||||
use tt_adapter_http::HttpClientPool;
|
||||
use tt_adapter_storage_core::file_system::DataDirectory;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
use super::{adapters, repositories};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ use crate::application::services::lan_sync_service::{
|
|||
use crate::application::services::sync_automation_service::SyncAutomationService;
|
||||
use crate::application::services::sync_job_coordinator::SyncJobCoordinator;
|
||||
use crate::application::services::tt_sync_service::TtSyncService;
|
||||
use crate::domain::ios_policy::IosPolicyActivationReport;
|
||||
use tt_adapter_storage_core::file_system::DataDirectory;
|
||||
use tt_adapter_sync::{
|
||||
AxumLanServerControl, HttpLanPairingClient, HttpTtPairingClient, InfrastructureSyncJobExecutor,
|
||||
LanPeerStore, LanSyncStore, LocalLanAddressDiscovery, SyncAutomationStore, TtSyncRuntime,
|
||||
};
|
||||
use tt_domain::ios_policy::IosPolicyActivationReport;
|
||||
use tt_ports::lan_sync::{LanPeerRepository, LanServerControl, LanSyncSettingsRepository};
|
||||
use tt_ports::sync::DataChangeReconciler;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,13 +38,6 @@ use crate::application::services::agent_workspace_lifecycle_service::{
|
|||
use crate::application::services::character_service::CharacterService;
|
||||
use crate::application::services::llm_connection_service::LlmConnectionService;
|
||||
use crate::application::services::skill_service::SkillService;
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::domain::models::agent::profile::{AgentDelegationPolicy, AgentProfileId};
|
||||
use crate::domain::models::agent::{
|
||||
AgentChatRef, AgentModelContentPart, AgentModelRequest, AgentRun, AgentRunEventLevel,
|
||||
AgentRunPresentation, AgentRunStatus, WorkspacePath,
|
||||
};
|
||||
use crate::domain::models::preset::{DefaultPreset, Preset, PresetType};
|
||||
use crate::infrastructure::persistence::png_utils::{
|
||||
read_character_data_from_png, write_character_data_to_png,
|
||||
};
|
||||
|
|
@ -56,6 +49,13 @@ use crate::infrastructure::repositories::file_world_info_repository::FileWorldIn
|
|||
use tt_adapter_storage_core::FileChatRepository;
|
||||
use tt_adapter_storage_core::FileLlmConnectionRepository;
|
||||
use tt_adapter_storage_core::chat_directory_identity::new_shared_chat_alias_store_for_user_dir;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::models::agent::profile::{AgentDelegationPolicy, AgentProfileId};
|
||||
use tt_domain::models::agent::{
|
||||
AgentChatRef, AgentModelContentPart, AgentModelRequest, AgentRun, AgentRunEventLevel,
|
||||
AgentRunPresentation, AgentRunStatus, WorkspacePath,
|
||||
};
|
||||
use tt_domain::models::preset::{DefaultPreset, Preset, PresetType};
|
||||
use tt_ports::repositories::agent_invocation_repository::AgentInvocationRepository;
|
||||
use tt_ports::repositories::agent_profile_repository::AgentProfileRepository;
|
||||
use tt_ports::repositories::agent_profile_storage_health_repository::AgentProfileStorageHealthRepository;
|
||||
|
|
@ -250,7 +250,7 @@ fn default_agent_responses() -> Vec<Value> {
|
|||
|
||||
async fn resolve_contract_profile(
|
||||
fixture: &AgentRuntimeFixture,
|
||||
) -> crate::domain::models::agent::profile::ResolvedAgentProfile {
|
||||
) -> tt_domain::models::agent::profile::ResolvedAgentProfile {
|
||||
let registry = BuiltinAgentToolRegistry::phase2c();
|
||||
fixture
|
||||
.profile_service
|
||||
|
|
@ -265,7 +265,7 @@ async fn resolve_contract_profile(
|
|||
fn contract_run(
|
||||
id: &str,
|
||||
presentation: AgentRunPresentation,
|
||||
profile: &crate::domain::models::agent::profile::ResolvedAgentProfile,
|
||||
profile: &tt_domain::models::agent::profile::ResolvedAgentProfile,
|
||||
) -> AgentRun {
|
||||
AgentRun {
|
||||
id: id.to_string(),
|
||||
|
|
@ -417,7 +417,7 @@ async fn execute_agent_loop_with_host_resolver<R>(
|
|||
run_id: String,
|
||||
prompt_snapshot: Value,
|
||||
request: ChatCompletionGenerateRequestDto,
|
||||
profile: crate::domain::models::agent::profile::ResolvedAgentProfile,
|
||||
profile: tt_domain::models::agent::profile::ResolvedAgentProfile,
|
||||
cancel_receiver: &mut watch::Receiver<bool>,
|
||||
resolver: R,
|
||||
) -> Result<(), ApplicationError>
|
||||
|
|
@ -502,7 +502,7 @@ async fn wait_for_event_field(
|
|||
async fn read_agent_events(
|
||||
repository: &FileAgentRepository,
|
||||
run_id: &str,
|
||||
) -> Vec<crate::domain::models::agent::AgentRunEvent> {
|
||||
) -> Vec<tt_domain::models::agent::AgentRunEvent> {
|
||||
repository
|
||||
.read_events(
|
||||
run_id,
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ use crate::application::dto::dev_observability_dto::{
|
|||
BackendLogEntryDto, DevBundleVersionDto, FrontendLogEntrySnapshotDto, LlmApiLogIndexEntryDto,
|
||||
LlmApiLogPreviewDto, LlmApiLogRawDto, LlmApiRawKindDto,
|
||||
};
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::infrastructure::logging::dev_bundle::{DevLogBundleInput, export_dev_log_bundle};
|
||||
use crate::infrastructure::logging::devtools::{BackendLogEntry, BackendLogStore};
|
||||
use crate::infrastructure::logging::llm_api_logs::{
|
||||
LlmApiLogEntryPreview, LlmApiLogEntryRaw, LlmApiLogIndexEntry, LlmApiLogStore, LlmApiRawKind,
|
||||
};
|
||||
use crate::infrastructure::paths::RuntimePaths;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
pub struct DevObservabilityHub {
|
||||
app_handle: AppHandle,
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::app::{BackendReadiness, StartupProfile, spawn_initialization};
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::domain::ios_policy::IosPolicyScope;
|
||||
use crate::infrastructure::logging::llm_api_logs::LlmApiLogStore;
|
||||
use tauri::Manager;
|
||||
use tt_adapter_http::HttpClientPool;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::ios_policy::IosPolicyScope;
|
||||
|
||||
pub(super) fn setup(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let app_handle = app.handle().clone();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::domain::ios_policy::{
|
||||
IosPolicyActivationReport, IosPolicyScope, resolve_ios_policy_activation_report,
|
||||
};
|
||||
use crate::domain::models::settings::TauriTavernSettings;
|
||||
use crate::infrastructure::ios_policy_cache::resolve_effective_raw_policy_sync;
|
||||
use tt_adapter_storage_core::FileSettingsRepository;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::ios_policy::{
|
||||
IosPolicyActivationReport, IosPolicyScope, resolve_ios_policy_activation_report,
|
||||
};
|
||||
use tt_domain::models::settings::TauriTavernSettings;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct StartupProfile {
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ use crate::application::services::update_service::UpdateService;
|
|||
use crate::application::services::user_directory_service::UserDirectoryService;
|
||||
use crate::application::services::user_service::UserService;
|
||||
use crate::application::services::world_info_service::WorldInfoService;
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::domain::ios_policy::IosPolicyActivationReport;
|
||||
use crate::infrastructure::paths::RuntimePaths;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::ios_policy::IosPolicyActivationReport;
|
||||
|
||||
use super::{StartupProfile, composition};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
pub(crate) use tt_domain::json_merge;
|
||||
pub use tt_domain::{errors, ios_policy, text_metrics, text_search};
|
||||
|
||||
pub mod models;
|
||||
|
|
@ -1 +0,0 @@
|
|||
pub use tt_domain::models::*;
|
||||
|
|
@ -5,11 +5,11 @@ use serde_json::Value;
|
|||
use tokio::fs;
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
|
||||
use crate::domain::json_merge::merge_json_value;
|
||||
use crate::infrastructure::persistence::png_utils::{
|
||||
process_avatar_image, read_character_data_from_png, write_character_data_to_png,
|
||||
};
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::json_merge::merge_json_value;
|
||||
use tt_domain::models::character::Character;
|
||||
use tt_domain::models::chat::parse_message_timestamp_value;
|
||||
use tt_ports::repositories::character_repository::{
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ use std::path::PathBuf;
|
|||
use super::FileSkillRepository;
|
||||
use super::package::{collect_skill_files, sha256_hex};
|
||||
use super::paths::{normalize_skill_path, validate_skill_name};
|
||||
use crate::domain::text_metrics::TextMetrics;
|
||||
use crate::domain::text_search::PreparedTextSearch;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::models::skill::{
|
||||
DEFAULT_SKILL_READ_FALLBACK_MAX_CHARS, SkillFileKind, SkillFileRef, SkillReadRequest,
|
||||
SkillReadResult, SkillScope, SkillSearchHit, SkillSearchRequest, SkillSearchResult,
|
||||
};
|
||||
use tt_domain::text_metrics::TextMetrics;
|
||||
use tt_domain::text_search::PreparedTextSearch;
|
||||
|
||||
struct SkillTextFile {
|
||||
scope: SkillScope,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
mod app;
|
||||
mod application;
|
||||
mod domain;
|
||||
mod infrastructure;
|
||||
mod observability_targets;
|
||||
mod platform;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use objc2_uniform_type_identifiers::UTType;
|
|||
use tauri::WebviewWindow;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::platform::ios_ui::resolve_presenting_view_controller;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
const DATA_ARCHIVE_CONTENT_TYPES: &[&str] = &[
|
||||
"public.zip-archive",
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ use objc2_ui_kit::{UIActivityType, UIActivityViewController};
|
|||
use tauri::WebviewWindow;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::platform::ios_ui::resolve_presenting_view_controller;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ShareResult {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use objc2::rc::Retained;
|
|||
use objc2::runtime::{AnyClass, AnyObject};
|
||||
use objc2_foundation::NSArray;
|
||||
|
||||
use crate::domain::errors::DomainError;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
use objc2_ui_kit::{UIViewController, UIWindow};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ use crate::application::dto::agent_dto::{
|
|||
};
|
||||
use crate::application::errors::ApplicationError;
|
||||
use crate::application::services::agent_workspace_lifecycle_service::AgentChatWorkspaceTarget;
|
||||
use crate::domain::models::agent::AgentChatRef;
|
||||
use crate::domain::models::agent::profile_diagnostic::AgentProfileHealth;
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::agent::AgentChatRef;
|
||||
use tt_domain::models::agent::profile_diagnostic::AgentProfileHealth;
|
||||
use tt_ports::repositories::agent_workspace_lifecycle_repository::AgentPersistentStatePruneRequest;
|
||||
|
||||
#[tauri::command]
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ use tauri::State;
|
|||
|
||||
use crate::app::AppState;
|
||||
use crate::application::services::asset_service::AssetDownloadResult;
|
||||
use crate::domain::models::asset::AssetCatalog;
|
||||
use crate::presentation::commands::helpers::{
|
||||
ensure_ios_policy_allows, log_command, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::asset::AssetCatalog;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_assets_library(
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ use tauri::State;
|
|||
use tokio::fs;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::models::avatar::{AvatarUploadResult, CropInfo};
|
||||
use crate::presentation::commands::helpers::{
|
||||
log_command, log_user_visible_error, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::avatar::{AvatarUploadResult, CropInfo};
|
||||
|
||||
const MAX_MOBILE_INLINE_AVATAR_BYTES: u64 = 8 * 1024 * 1024;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ use tauri::State;
|
|||
use crate::app::AppState;
|
||||
use crate::application::dto::background_dto::{DeleteBackgroundDto, RenameBackgroundDto};
|
||||
use crate::application::services::host_resource_service::HostResourceService;
|
||||
use crate::domain::models::background::BackgroundListEntry;
|
||||
use crate::domain::models::image_metadata::ImageMetadataIndex;
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::background::BackgroundListEntry;
|
||||
use tt_domain::models::image_metadata::ImageMetadataIndex;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct ThumbnailAssetPayload {
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ use crate::application::dto::character_dto::{
|
|||
ResolveCharacterLorebookConflictResultDto, UpdateAvatarDto, UpdateCharacterCardDataDto,
|
||||
UpdateCharacterDto,
|
||||
};
|
||||
use crate::domain::models::skill::{SkillScope, SkillScopeRetargetRequest};
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::skill::{SkillScope, SkillScopeRetargetRequest};
|
||||
|
||||
const SKILL_SOURCE_KIND_CHARACTER: &str = "character";
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use crate::application::dto::chat_completion_dto::{
|
|||
ChatCompletionGenerateRequestDto, ChatCompletionStatusRequestDto,
|
||||
};
|
||||
use crate::application::services::chat_completion_service::ChatCompletionService;
|
||||
use crate::domain::models::upstream_failure::UpstreamFailure;
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::upstream_failure::UpstreamFailure;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_chat_completions_status(
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ use std::sync::Arc;
|
|||
use tauri::State;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::ios_policy::IosPolicyScope;
|
||||
use crate::domain::models::extension::{
|
||||
Extension, ExtensionInstallResult, ExtensionUpdateResult, ExtensionVersion,
|
||||
};
|
||||
use crate::presentation::commands::helpers::{
|
||||
ensure_ios_policy_allows, log_command, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::ios_policy::IosPolicyScope;
|
||||
use tt_domain::models::extension::{
|
||||
Extension, ExtensionInstallResult, ExtensionUpdateResult, ExtensionVersion,
|
||||
};
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_extensions(
|
||||
|
|
@ -39,11 +39,11 @@ pub async fn get_extensions(
|
|||
|
||||
let before = extensions.len();
|
||||
extensions.retain(|extension| match extension.extension_type {
|
||||
crate::domain::models::extension::ExtensionType::System => {
|
||||
tt_domain::models::extension::ExtensionType::System => {
|
||||
system_allowlist.allows(&extension.name)
|
||||
}
|
||||
crate::domain::models::extension::ExtensionType::Local
|
||||
| crate::domain::models::extension::ExtensionType::Global => allow_third_party,
|
||||
tt_domain::models::extension::ExtensionType::Local
|
||||
| tt_domain::models::extension::ExtensionType::Global => allow_third_party,
|
||||
});
|
||||
|
||||
let filtered = before.saturating_sub(extensions.len());
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ use tokio::fs;
|
|||
use url::Url;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::models::filename::sanitize_filename as sanitize_filename_contract;
|
||||
use crate::presentation::commands::helpers::log_command;
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::filename::sanitize_filename as sanitize_filename_contract;
|
||||
|
||||
const UNSAFE_EXTENSIONS: &[&str] = &[
|
||||
".php",
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ use std::fmt::Display;
|
|||
use crate::presentation::errors::CommandError;
|
||||
|
||||
pub fn ensure_ios_policy_allows(
|
||||
ios_policy: &crate::domain::ios_policy::IosPolicyActivationReport,
|
||||
ios_policy: &tt_domain::ios_policy::IosPolicyActivationReport,
|
||||
allowed: bool,
|
||||
capability: &'static str,
|
||||
) -> Result<(), CommandError> {
|
||||
if ios_policy.scope == crate::domain::ios_policy::IosPolicyScope::Ios && !allowed {
|
||||
if ios_policy.scope == tt_domain::ios_policy::IosPolicyScope::Ios && !allowed {
|
||||
return Err(CommandError::Unauthorized(format!(
|
||||
"iOS policy disabled capability: {capability}"
|
||||
)));
|
||||
|
|
@ -67,7 +67,7 @@ pub fn log_user_visible_error(message: impl AsRef<str>) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::domain::errors::GENERATION_CANCELLED_BY_USER_MESSAGE;
|
||||
use tt_domain::errors::GENERATION_CANCELLED_BY_USER_MESSAGE;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ use crate::application::dto::image_metadata_dto::{
|
|||
CreateImageMetadataFolderDto, DeleteImageMetadataFolderDto, ImageMetadataFolderAssignmentDto,
|
||||
SetImageMetadataFolderThumbnailsDto, UpdateImageMetadataFolderDto,
|
||||
};
|
||||
use crate::domain::models::image_metadata::{BackgroundFoldersPayload, ImageMetadataFolder};
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::image_metadata::{BackgroundFoldersPayload, ImageMetadataFolder};
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_background_folders(
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ use tauri::{AppHandle, Manager, State, WebviewWindow};
|
|||
|
||||
use crate::app::AppState;
|
||||
use crate::application::host_contract::IOS_EXPORT_STAGING_ROOT_NAME;
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::platform::ios_document_picker::{
|
||||
PickDocumentResult, copy_picked_url_to_path, pick_data_archive, pick_skill_import_archive,
|
||||
};
|
||||
use crate::platform::ios_share_sheet::share_file;
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::errors::DomainError;
|
||||
|
||||
const IOS_SKILL_IMPORT_STAGING_ROOT_NAME: &str = "tauritavern-skill-import-staging";
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ use tauri::State;
|
|||
use ttsync_contract::sync::SyncMode;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::models::lan_sync::{LanSyncPairedDeviceSummary, LanSyncStatus};
|
||||
use crate::presentation::commands::helpers::{
|
||||
ensure_ios_policy_allows, log_command, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_contracts::sync::{SyncJobReport, SyncOperationOptions};
|
||||
use tt_domain::models::lan_sync::{LanSyncPairedDeviceSummary, LanSyncStatus};
|
||||
|
||||
fn ensure_lan_sync_allowed(app_state: &AppState) -> Result<(), CommandError> {
|
||||
ensure_ios_policy_allows(
|
||||
|
|
@ -280,9 +280,9 @@ pub async fn lan_sync_clear_sync_mode_override(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_qr_svg(text: &str) -> Result<String, crate::domain::errors::DomainError> {
|
||||
fn generate_qr_svg(text: &str) -> Result<String, tt_domain::errors::DomainError> {
|
||||
let code = QrCode::new(text.as_bytes())
|
||||
.map_err(|error| crate::domain::errors::DomainError::InternalError(error.to_string()))?;
|
||||
.map_err(|error| tt_domain::errors::DomainError::InternalError(error.to_string()))?;
|
||||
Ok(code
|
||||
.render::<qrcode::render::svg::Color>()
|
||||
.min_dimensions(200, 200)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ use crate::application::dto::preset_dto::{
|
|||
DeleteOpenAIPresetDto, DeleteOpenAIPresetResponseDto, DeletePresetDto, RestorePresetDto,
|
||||
RestorePresetResponseDto, SaveOpenAIPresetDto, SavePresetDto, SavePresetResponseDto,
|
||||
};
|
||||
use crate::domain::models::preset::PresetType;
|
||||
use crate::presentation::commands::helpers::{
|
||||
log_command, log_user_visible_error, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::preset::PresetType;
|
||||
|
||||
const SKILL_SOURCE_KIND_PRESET: &str = "preset";
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ fn runtime_paths_dto(info: RuntimePathsInfo) -> RuntimePathsDto {
|
|||
}
|
||||
}
|
||||
|
||||
fn map_set_data_root_error(error: crate::domain::errors::DomainError) -> CommandError {
|
||||
fn map_set_data_root_error(error: tt_domain::errors::DomainError) -> CommandError {
|
||||
let command_error = CommandError::from(error);
|
||||
if matches!(&command_error, CommandError::InternalServerError(_)) {
|
||||
map_command_error("Failed to set data root")(command_error)
|
||||
|
|
|
|||
|
|
@ -6,16 +6,16 @@ use serde::Serialize;
|
|||
use tauri::State;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::models::skill::{
|
||||
use crate::presentation::commands::helpers::{
|
||||
ensure_ios_policy_allows, log_command, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::skill::{
|
||||
DEFAULT_SKILL_READ_FALLBACK_MAX_CHARS, SkillFileRef, SkillImportInput, SkillImportPreview,
|
||||
SkillIndexEntry, SkillInstallRequest, SkillInstallResult, SkillMoveRequest, SkillReadRequest,
|
||||
SkillReadResult, SkillScope, SkillScopeFilter, SkillScopeRetargetRequest,
|
||||
SkillScopeRetargetResult, SkillWriteRequest,
|
||||
};
|
||||
use crate::presentation::commands::helpers::{
|
||||
ensure_ios_policy_allows, log_command, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ use tauri::State;
|
|||
use ttsync_contract::sync::SyncMode;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::models::tt_sync::TtSyncPairedServer;
|
||||
use crate::presentation::commands::helpers::{log_command, map_command_error};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_contracts::sync::{SyncJobReport, SyncOperationOptions};
|
||||
use tt_domain::models::tt_sync::TtSyncPairedServer;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct TtSyncPermissionsDto {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ use std::sync::Arc;
|
|||
use tauri::State;
|
||||
|
||||
use crate::app::AppState;
|
||||
use crate::domain::models::update::UpdateCheckResult;
|
||||
use crate::presentation::commands::helpers::{
|
||||
ensure_ios_policy_allows, log_command, map_command_error,
|
||||
};
|
||||
use crate::presentation::errors::CommandError;
|
||||
use tt_domain::models::update::UpdateCheckResult;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn check_for_update(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::application::errors::ApplicationError;
|
||||
use crate::domain::errors::DomainError;
|
||||
use crate::domain::models::upstream_failure::UpstreamFailure;
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
use tt_domain::errors::DomainError;
|
||||
use tt_domain::models::upstream_failure::UpstreamFailure;
|
||||
|
||||
#[derive(Error, Debug, Serialize)]
|
||||
pub enum CommandError {
|
||||
|
|
@ -82,7 +82,7 @@ impl CommandError {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::domain::errors::GENERATION_CANCELLED_BY_USER_MESSAGE;
|
||||
use tt_domain::errors::GENERATION_CANCELLED_BY_USER_MESSAGE;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ test('chat rename events use backend-committed normalized file names', async ()
|
|||
readFile(path.join(REPO_ROOT, 'src/tauri/main/routes/chat-routes.js'), 'utf8'),
|
||||
readFile(path.join(REPO_ROOT, 'src-tauri/src/presentation/commands/chat_commands.rs'), 'utf8'),
|
||||
readFile(path.join(REPO_ROOT, 'src-tauri/src/presentation/commands/group_chat_commands.rs'), 'utf8'),
|
||||
readFile(path.join(REPO_ROOT, 'src-tauri/src/application/services/chat_service.rs'), 'utf8'),
|
||||
readFile(path.join(REPO_ROOT, 'src-tauri/src/application/services/group_chat_service.rs'), 'utf8'),
|
||||
readFile(path.join(REPO_ROOT, 'src-tauri/crates/tt-application/src/services/chat_service.rs'), 'utf8'),
|
||||
readFile(path.join(REPO_ROOT, 'src-tauri/crates/tt-application/src/services/group_chat_service.rs'), 'utf8'),
|
||||
]);
|
||||
|
||||
assert.match(route, /const sanitizedFileName = await context\.safeInvoke\('rename_group_chat'/);
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ const openaiSource = await readFile(new URL('../src/scripts/openai.js', import.m
|
|||
const secretsSource = await readFile(new URL('../src/scripts/secrets.js', import.meta.url), 'utf8');
|
||||
const aiRoutesSource = await readFile(new URL('../src/tauri/main/routes/ai-routes.js', import.meta.url), 'utf8');
|
||||
const rustSource = await readFile(new URL('../src-tauri/crates/tt-domain/src/models/chat_completion_source.rs', import.meta.url), 'utf8');
|
||||
const rustConfigSource = await readFile(new URL('../src-tauri/src/application/services/chat_completion_service/config.rs', import.meta.url), 'utf8');
|
||||
const rustPayloadSource = await readFile(new URL('../src-tauri/src/application/services/chat_completion_service/payload/minimax.rs', import.meta.url), 'utf8');
|
||||
const rustConfigSource = await readFile(new URL('../src-tauri/crates/tt-application/src/services/chat_completion_service/config.rs', import.meta.url), 'utf8');
|
||||
const rustPayloadSource = await readFile(new URL('../src-tauri/crates/tt-application/src/services/chat_completion_service/payload/minimax.rs', import.meta.url), 'utf8');
|
||||
const rustRepositorySource = await readRustSources(new URL('../src-tauri/crates/tt-adapter-provider-http/src/http_chat_completion_repository/', import.meta.url));
|
||||
const rossAscendsSource = await readFile(new URL('../src/scripts/RossAscends-mods.js', import.meta.url), 'utf8');
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ function readProjectFile(relativePath) {
|
|||
}
|
||||
|
||||
test('connectionRef prompt assembly overlays model binding instead of validating preset source', async () => {
|
||||
const source = await readProjectFile('src-tauri/src/application/services/prompt_assembly_service.rs');
|
||||
const source = await readProjectFile('src-tauri/crates/tt-application/src/services/prompt_assembly_service.rs');
|
||||
|
||||
assert.match(source, /apply_model_binding_to_prompt_settings/);
|
||||
assert.match(source, /"deepseek"\s*=>\s*Ok\("deepseek_model"\)/);
|
||||
|
|
@ -20,7 +20,7 @@ test('connectionRef prompt assembly overlays model binding instead of validating
|
|||
});
|
||||
|
||||
test('currentPromptSnapshot prompt assembly overlays frozen current model connection', async () => {
|
||||
const source = await readProjectFile('src-tauri/src/application/services/prompt_assembly_service.rs');
|
||||
const source = await readProjectFile('src-tauri/crates/tt-application/src/services/prompt_assembly_service.rs');
|
||||
const frontendSource = await readProjectFile('src/scripts/tauritavern/agent/frozen-run-input-snapshot.js');
|
||||
const agentApiSource = await readProjectFile('src/tauri/main/api/agent-prompt-assembly-run.js');
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ test('currentPromptSnapshot prompt assembly overlays frozen current model connec
|
|||
});
|
||||
|
||||
test('requiresConfiguration prompt assembly fails fast before frontend broker handoff', async () => {
|
||||
const source = await readProjectFile('src-tauri/src/application/services/prompt_assembly_service.rs');
|
||||
const source = await readProjectFile('src-tauri/crates/tt-application/src/services/prompt_assembly_service.rs');
|
||||
const guardIndex = source.indexOf('ensure_profile_model_configured(&profile)?;');
|
||||
const brokerIndex = source.indexOf('AgentPromptAssemblyModeDto::FrontendPromptAssembly');
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ test('native regex batching shares the same runnable-script gate as sync regex e
|
|||
});
|
||||
|
||||
test('native regex DTO remains an execution payload, not SillyTavern extension state', async () => {
|
||||
const source = await readFile(path.join(REPO_ROOT, 'src-tauri', 'src', 'application', 'dto', 'native_regex_dto.rs'), 'utf8');
|
||||
const source = await readFile(path.join(REPO_ROOT, 'src-tauri', 'crates', 'tt-application', 'src', 'dto', 'native_regex_dto.rs'), 'utf8');
|
||||
|
||||
assert.doesNotMatch(source, /\bpub\s+disabled\b/);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ test('Stable Diffusion backend request uses explicit credentials instead of prov
|
|||
'utf8',
|
||||
);
|
||||
const serviceSource = await readFile(
|
||||
path.join(REPO_ROOT, 'src-tauri', 'src', 'application', 'services', 'stable_diffusion_service.rs'),
|
||||
path.join(REPO_ROOT, 'src-tauri', 'crates', 'tt-application', 'src', 'services', 'stable_diffusion_service.rs'),
|
||||
'utf8',
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ test('TauriTavern Sync automation status events refresh status only while toasts
|
|||
|
||||
test('TauriTavern Sync automation success toasts include next run time', async () => {
|
||||
const listeners = await readRepoFile('src/scripts/tauri/setting/setting-panel/sync-listeners.js');
|
||||
const service = await readRepoFile('src-tauri/src/application/services/sync_automation_service.rs');
|
||||
const service = await readRepoFile('src-tauri/crates/tt-application/src/services/sync_automation_service.rs');
|
||||
const model = await readRepoFile('src-tauri/crates/tt-contracts/src/sync_automation.rs');
|
||||
const zhCn = await readRepoFile('src/locales/zh-cn.json');
|
||||
const zhTw = await readRepoFile('src/locales/zh-tw.json');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue