forked from 1jehuang/jcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprompting.rs
More file actions
123 lines (107 loc) · 4.07 KB
/
Copy pathprompting.rs
File metadata and controls
123 lines (107 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use super::Agent;
use crate::logging;
use crate::message::{Message, ToolDefinition};
impl Agent {
pub(super) fn log_prompt_prefix_accounting(
&self,
split: &crate::prompt::SplitSystemPrompt,
tools: &[ToolDefinition],
) {
let system_tokens = split.estimated_tokens();
let tool_tokens = ToolDefinition::aggregate_prompt_token_estimate(tools);
let prefix_tokens = system_tokens + tool_tokens;
logging::info(&format!(
"Prompt prefix estimate: total={} tokens (system={} tools={})",
prefix_tokens, system_tokens, tool_tokens
));
}
pub(super) fn build_memory_prompt_nonblocking_shared(
&self,
messages: std::sync::Arc<[Message]>,
_memory_event_tx: Option<crate::memory::MemoryEventSink>,
) -> Option<crate::memory::PendingMemory> {
if !self.memory_enabled {
return None;
}
let session_id = &self.session.id;
let pending = if crate::message::ends_with_fresh_user_turn(&messages) {
crate::memory::take_pending_memory(session_id)
} else {
None
};
// Use the persistent memory-agent pipeline as the single source of truth.
// Running both this and the legacy MemoryManager background retrieval path
// can prepare overlapping pending prompts for the same turn, which makes
// memory injection feel overly aggressive.
crate::memory_agent::update_context_sync_with_dir(
session_id,
messages,
self.session.working_dir.clone(),
);
pending
}
fn append_current_turn_system_reminder(&self, split: &mut crate::prompt::SplitSystemPrompt) {
let Some(reminder) = self
.current_turn_system_reminder
.as_ref()
.map(|value| value.trim())
.filter(|value| !value.is_empty())
else {
return;
};
if !split.dynamic_part.is_empty() {
split.dynamic_part.push_str("\n\n");
}
split.dynamic_part.push_str("# System Reminder\n\n");
split.dynamic_part.push_str(reminder);
}
/// Build split system prompt for better caching
/// Returns static (cacheable) and dynamic (not cached) parts separately
pub(super) fn build_system_prompt_split(
&self,
memory_prompt: Option<&str>,
) -> crate::prompt::SplitSystemPrompt {
if let Some(ref override_prompt) = self.system_prompt_override {
return crate::prompt::SplitSystemPrompt {
static_part: override_prompt.clone(),
dynamic_part: String::new(),
};
}
let skills = self.current_skills_snapshot();
let skill_prompt = self
.active_skill
.as_ref()
.and_then(|name| skills.get(name).map(|skill| skill.get_prompt().to_string()));
let available_skills: Vec<crate::prompt::SkillInfo> = self
.current_skills_snapshot()
.list()
.iter()
.map(|skill| crate::prompt::SkillInfo {
name: skill.name.clone(),
description: skill.description.clone(),
})
.collect();
let working_dir = self
.session
.working_dir
.as_ref()
.map(std::path::PathBuf::from);
let (mut split, _context_info) = crate::prompt::build_system_prompt_split(
skill_prompt.as_deref(),
&available_skills,
self.session.is_canary,
memory_prompt,
working_dir.as_deref(),
);
self.append_current_turn_system_reminder(&mut split);
split
}
/// Non-blocking memory prompt - takes pending result and spawns check for next turn
pub(super) fn build_memory_prompt_nonblocking(
&self,
messages: &[Message],
_memory_event_tx: Option<crate::memory::MemoryEventSink>,
) -> Option<crate::memory::PendingMemory> {
self.build_memory_prompt_nonblocking_shared(messages.to_vec().into(), _memory_event_tx)
}
}