Move tool definitions into ContextState as system entries
Tool definitions are now pushed as a ContextEntry in the system section at Agent construction time, formatted in the Qwen chat template style. They're tokenized, scored, and treated like any other context entry. assemble_prompt_tokens() no longer takes a tools parameter — tools are already in the context. This prepares for the switch to /v1/completions where tools aren't a separate API field. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
67e3228c32
commit
e9765799c4
3 changed files with 220 additions and 3 deletions
|
|
@ -192,6 +192,24 @@ impl Agent {
|
|||
let mut system = ContextSection::new("System prompt");
|
||||
system.push(ContextEntry::new(
|
||||
ConversationEntry::System(Message::system(&system_prompt)), None));
|
||||
|
||||
// Tool definitions — part of the context, tokenized and scored
|
||||
let tool_defs: Vec<String> = tools::tools().iter()
|
||||
.map(|t| t.to_json()).collect();
|
||||
if !tool_defs.is_empty() {
|
||||
let tools_text = format!(
|
||||
"# Tools\n\nYou have access to the following functions:\n\n<tools>\n{}\n</tools>\n\n\
|
||||
If you choose to call a function ONLY reply in the following format with NO suffix:\n\n\
|
||||
<tool_call>\n<function=example_function_name>\n\
|
||||
<parameter=example_parameter_1>\nvalue_1\n</parameter>\n\
|
||||
</function>\n</tool_call>\n\n\
|
||||
IMPORTANT: Function calls MUST follow the specified format.",
|
||||
tool_defs.join("\n"),
|
||||
);
|
||||
system.push(ContextEntry::new(
|
||||
ConversationEntry::System(Message::system(&tools_text)), None));
|
||||
}
|
||||
|
||||
let mut identity = ContextSection::new("Identity");
|
||||
for (_name, content) in &personality {
|
||||
identity.push(ContextEntry::new(
|
||||
|
|
@ -293,6 +311,42 @@ impl Agent {
|
|||
msgs
|
||||
}
|
||||
|
||||
/// Assemble the full prompt as token IDs for the completions API.
|
||||
/// System section (includes tools), identity, journal, conversation,
|
||||
/// then the assistant prompt suffix.
|
||||
pub fn assemble_prompt_tokens(&self) -> Vec<u32> {
|
||||
let mut tokens = Vec::new();
|
||||
|
||||
// System section — includes system prompt + tool definitions
|
||||
for e in self.context.system.entries() {
|
||||
tokens.extend(&e.token_ids);
|
||||
}
|
||||
|
||||
// Identity — rendered as one user message
|
||||
let ctx = self.context.render_context_message();
|
||||
if !ctx.is_empty() {
|
||||
tokens.extend(tokenizer::tokenize_entry("user", &ctx));
|
||||
}
|
||||
|
||||
// Journal — rendered as one user message
|
||||
let jnl = self.context.render_journal();
|
||||
if !jnl.is_empty() {
|
||||
tokens.extend(tokenizer::tokenize_entry("user", &jnl));
|
||||
}
|
||||
|
||||
// Conversation entries — use cached token_ids
|
||||
for e in self.context.conversation.entries() {
|
||||
if e.entry.is_log() || e.entry.is_thinking() { continue; }
|
||||
tokens.extend(&e.token_ids);
|
||||
}
|
||||
|
||||
// Prompt the assistant to respond
|
||||
tokens.push(tokenizer::IM_START);
|
||||
tokens.extend(tokenizer::encode("assistant\n"));
|
||||
|
||||
tokens
|
||||
}
|
||||
|
||||
/// Run agent orchestration cycle, returning structured output.
|
||||
/// Push a conversation message — stamped and logged.
|
||||
pub fn push_message(&mut self, mut msg: Message) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue