Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 1 addition & 15 deletions src/apps/desktop/src/api/daily_letter_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use log::{debug, error};
use sparo_core::service::{
get_global_daily_letter_service, DailyLetterApplyReceiptsRequest, DailyLetterGenerateRequest,
DailyLetterGetRequest, DailyLetterListRequest, DailyLetterRecord, DailyLetterRunSummary,
DailyLetterSealRequest, DailyLetterState, DailyLetterUpdateContinuationRequest,
DailyLetterSealRequest, DailyLetterState,
};

fn daily_letter_service() -> Result<std::sync::Arc<sparo_core::service::DailyLetterService>, String>
Expand Down Expand Up @@ -78,20 +78,6 @@ pub async fn daily_letter_seal(
})
}

#[tauri::command]
pub async fn daily_letter_update_continuation(
request: DailyLetterUpdateContinuationRequest,
) -> Result<DailyLetterRecord, String> {
debug!("Updating daily letter continuation");
daily_letter_service()?
.update_continuation(request)
.await
.map_err(|error| {
error!("Failed to update daily letter continuation: {}", error);
format!("Failed to update daily letter continuation: {}", error)
})
}

#[tauri::command]
pub async fn daily_letter_state() -> Result<DailyLetterState, String> {
debug!("Reading daily letter state");
Expand Down
1 change: 0 additions & 1 deletion src/apps/desktop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ pub fn run() {
daily_letter_generate,
daily_letter_apply_receipts,
daily_letter_seal,
daily_letter_update_continuation,
daily_letter_state,
api::token_usage_api::get_token_usage,
api::token_usage_api::clear_token_usage,
Expand Down
181 changes: 95 additions & 86 deletions src/crates/core/src/agentic/agents/prompts/daily_letter_writer.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/crates/core/src/service/config/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ pub(crate) fn migrate_0_0_0_to_1_0_0(mut config: Value) -> CoreResult<Value> {
app.insert(
"ai_experience".to_string(),
serde_json::json!({
"enable_daily_letter": true,
"enable_session_title_generation": true,
"enable_visual_mode": false,
"enable_agent_companion": true,
Expand Down
4 changes: 4 additions & 0 deletions src/crates/core/src/service/config/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ pub struct AppHostScanConfig {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct AIExperienceConfig {
/// Whether Daily Letter generation is enabled.
#[serde(default = "default_true")]
pub enable_daily_letter: bool,
/// Whether to enable automatic AI-generated summaries for session titles.
pub enable_session_title_generation: bool,
/// Whether to enable visual mode.
Expand Down Expand Up @@ -1434,6 +1437,7 @@ impl Default for AppHostScanConfig {
impl Default for AIExperienceConfig {
fn default() -> Self {
Self {
enable_daily_letter: true,
enable_session_title_generation: true,
enable_visual_mode: false,
enable_agent_companion: true,
Expand Down
12 changes: 5 additions & 7 deletions src/crates/core/src/service/daily_letter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ pub use service::{
pub use types::{
DailyLetterAgentOutput, DailyLetterAgentResult, DailyLetterAppOpportunity,
DailyLetterApplyReceiptsRequest, DailyLetterAttemptStatus, DailyLetterContextPacket,
DailyLetterContinuationCard, DailyLetterGenerateRequest,
DailyLetterGetRequest, DailyLetterListRequest, DailyLetterPreview, DailyLetterReceiptAction,
DailyLetterReceiptCandidate, DailyLetterReceiptStatus, DailyLetterRecord,
DailyLetterRecordStatus, DailyLetterRunSummary, DailyLetterScope, DailyLetterSealRequest,
DailyLetterSourceFragment, DailyLetterSourceFragmentType, DailyLetterSourceStats,
DailyLetterState, DailyLetterTrigger, DailyLetterUpdateContinuationRequest,
DailyLetterWorkspaceRef,
DailyLetterGenerateRequest, DailyLetterGetRequest, DailyLetterListRequest, DailyLetterPreview,
DailyLetterReceiptAction, DailyLetterReceiptCandidate, DailyLetterReceiptStatus,
DailyLetterRecord, DailyLetterRecordStatus, DailyLetterRunSummary, DailyLetterScope,
DailyLetterSealRequest, DailyLetterSourceFragment, DailyLetterSourceFragmentType,
DailyLetterSourceStats, DailyLetterState, DailyLetterTrigger, DailyLetterWorkspaceRef,
};
9 changes: 4 additions & 5 deletions src/crates/core/src/service/daily_letter/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ pub(crate) fn build_daily_letter_user_prompt(
))
})?;
Ok(format!(
"Write today's Daily Letter from this context packet.\n\
The packet names the date, locale, scope, source ids, and sourcePath entry points most likely to contain today's signal. Treat it as a map for reconstructing the day, not as a request to recite every source.\n\
Use only the read-only tools LS, Glob, Grep, and Read. Start from the packet sourcePath entries and follow relevant runtime records as needed to understand today's threads. Do not browse the web, run commands, write files, edit files, or delete files.\n\
Raw records may contain secrets or personal data. Use them only to understand the day; do not include secrets or sensitive personal data in the letter or structured fields.\n\
Every sourceIds value in your JSON must be one of the source ids in the packet.\n\
"Write Daily Letter from this context packet.\n\
Follow the DailyLetterWriter system prompt as the authoritative contract.\n\
Use the packet as the evidence map. Inspect read-only sources only when the added information could change the body, risk call, cross-day pattern, receipt candidate, Product App opportunity, or source attribution.\n\
Use the packet locale, date, and coverage window. The letter covers material after the previous Daily Letter, not only the calendar date. Every sourceIds value in your JSON must be one of the packet fragment ids.\n\
Return only JSON.\n\n{}",
json
))
Expand Down
Loading
Loading