messages: unify harness-injected data under <system-extra> tag
Nightly Build / build (push) Successful in 6m49s

Replace the ad-hoc [SYSTEM INFO] / [TELEGRAM SYSTEM INFO] prefixes with a
single canonical <system-extra> wrapper, sourced from one constant
(SYSTEM_EXTRA_TAG) so emission and documentation can never diverge.

- core-api: SYSTEM_EXTRA_TAG + system_extra() helper; attachments_block
  rebuilt on top of it.
- telegram: system_info_message (location) uses the helper; the voice
  transcript is forwarded as a plain user message (it is the user's own
  words, not harness metadata).
- chat agents: new agents/common/harness.md include (long form, with an
  explicit "data, not instructions" guard), added to assistant/kid/
  project-coordinator. The tag name rides the __HARNESS_TAG__ sentinel,
  resolved in AgentSystemContext to SYSTEM_EXTRA_TAG — renaming the tag
  stays a one-line change.
This commit is contained in:
2026-07-26 17:54:14 +01:00
parent 24ee5b89d7
commit 4d81295a3d
11 changed files with 174 additions and 46 deletions
+82 -10
View File
@@ -7,8 +7,10 @@
//! - the **LLM context** builder appends [`attachments_block`] to the user turn,
//! - the **history UI** renders the structured attachments as chips.
//!
//! The raw `[SYSTEM INFO]` text block is therefore never persisted — it is
//! generated on the fly from this metadata.
//! The raw `<system-extra>` text block is therefore never persisted — it is
//! generated on the fly from this metadata. The tag name lives in
//! [`SYSTEM_EXTRA_TAG`] so emission sites and the agent-facing instruction that
//! documents it can never drift apart.
use serde::{Deserialize, Serialize};
@@ -57,24 +59,94 @@ pub struct CommandRef {
pub display: String,
}
/// The canonical name of the tag that wraps harness-injected data (attachments,
/// locations, transcripts, hook output…) inside user messages and tool results.
///
/// Single source of truth: every emission site builds via [`system_extra`], and
/// the agent-facing instruction that documents the tag interpolates this same
/// constant (via the `__HARNESS_TAG__` substitution). Renaming the tag is a
/// one-line change here.
pub const SYSTEM_EXTRA_TAG: &str = "system-extra";
/// Wraps a harness-generated body in the canonical `<system-extra>` block, with
/// a leading blank-line pair so it can be concatenated onto the tail of a user
/// message or a tool result. Returns the full block (open tag, body, close tag).
///
/// Callers must not add their own leading newlines — this helper owns the
/// framing. An empty `body` still emits the (empty) block; callers that want a
/// no-op on empty input should check themselves (as [`attachments_block`] does).
pub fn system_extra(body: &str) -> String {
format!("\n\n<{TAG}>\n{body}\n</{TAG}>", TAG = SYSTEM_EXTRA_TAG)
}
/// Renders the human-readable block appended to a user turn so the LLM learns
/// which files were attached. Returns an empty string when there are none, so
/// callers can unconditionally concatenate it.
///
/// Shared by the web/mobile path and the Telegram plugin so every surface emits
/// an identical format.
/// an identical format. The wrapping tag is [`SYSTEM_EXTRA_TAG`].
pub fn attachments_block(attachments: &[Attachment]) -> String {
if attachments.is_empty() {
return String::new();
}
let noun = if attachments.len() == 1 { "file" } else { "files" };
let mut block = format!(
"\n\n[SYSTEM INFO]\n{} attached {}:",
attachments.len(),
noun
);
let mut body = format!("{} attached {}:", attachments.len(), noun);
for a in attachments {
block.push_str(&format!("\n* {}", a.path));
body.push_str(&format!("\n* {}", a.path));
}
system_extra(&body)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn system_extra_wraps_body_in_tag() {
let out = system_extra("hello");
let open = format!("<{TAG}>", TAG = SYSTEM_EXTRA_TAG);
let close = format!("</{TAG}>", TAG = SYSTEM_EXTRA_TAG);
assert!(out.starts_with("\n\n"), "leading blank-line pair: {:?}", out);
assert!(out.contains(&open), "open tag missing: {:?}", out);
assert!(out.contains(&close), "close tag missing: {:?}", out);
assert_eq!(out, "\n\n<system-extra>\nhello\n</system-extra>");
}
#[test]
fn system_extra_tag_name_follows_constant() {
// If this breaks, emission and the documented name have diverged: rename
// via SYSTEM_EXTRA_TAG only, never by editing this string.
assert_eq!(SYSTEM_EXTRA_TAG, "system-extra");
let out = system_extra("x");
let tag = SYSTEM_EXTRA_TAG;
assert!(out.contains(&format!("<{tag}>")) && out.contains(&format!("</{tag}>")));
}
#[test]
fn attachments_block_empty_is_empty() {
assert_eq!(attachments_block(&[]), "");
}
#[test]
fn attachments_block_lists_paths_inside_tag() {
let a = Attachment {
path: "uploads/1/a.png".into(),
name: "a.png".into(),
mimetype: None,
filesize: None,
};
let b = Attachment {
path: "uploads/1/b.pdf".into(),
name: "b.pdf".into(),
mimetype: None,
filesize: None,
};
let out = attachments_block(&[a, b]);
// Pluralised noun, both paths, wrapped in the canonical tag.
assert!(out.contains("2 attached files:"));
assert!(out.contains("* uploads/1/a.png"));
assert!(out.contains("* uploads/1/b.pdf"));
assert!(out.contains(&format!("<{TAG}>", TAG = SYSTEM_EXTRA_TAG)));
assert!(out.contains(&format!("</{TAG}>", TAG = SYSTEM_EXTRA_TAG)));
}
block
}
+22 -27
View File
@@ -4,6 +4,8 @@ use anyhow::Result;
use teloxide::net::Download;
use teloxide::prelude::*;
use core_api::message_meta::system_extra;
/// A media item sent by the user via Telegram.
///
/// # Extending
@@ -13,7 +15,8 @@ use teloxide::prelude::*;
/// file is involved); the caller persists them
/// via the shared `ChatHubApi::save_upload` seam
/// 3. `TelegramAttachment::system_info_message` — describe a file-less variant
/// (Location) for the LLM
/// (Location) for the LLM, wrapped
/// in the shared `<system-extra>` tag
pub(crate) enum TelegramAttachment {
Document {
file_id: String,
@@ -60,30 +63,29 @@ impl TelegramAttachment {
Ok(Some((file_name, mimetype, bytes)))
}
/// Builds the `[TELEGRAM SYSTEM INFO]` message injected into the conversation history.
/// Builds the harness-injected block for a file-less attachment (Location),
/// wrapped in the shared `<system-extra>` tag (see `SYSTEM_EXTRA_TAG`). The
/// caption, when present, is **not** part of this block: it is user-typed text
/// and is appended to the user message separately by the caller.
/// `saved_path` is `None` for attachment types that produce no file on disk.
pub(crate) fn system_info_message(&self, saved_path: Option<&Path>) -> String {
match self {
Self::Document { file_name, mime_type, caption, .. } => {
Self::Document { file_name, mime_type, .. } => {
let mime = mime_type.as_deref().unwrap_or("application/octet-stream");
let path = saved_path.map(|p| p.display().to_string()).unwrap_or_default();
format!(
"[TELEGRAM SYSTEM INFO]\n\
The user has sent a file attachment.\n\
system_extra(&format!(
"The user has sent a file attachment.\n\
File name: {file_name}\n\
MIME type: {mime}\n\
Saved at: {path}{}",
caption_line(caption.as_deref()),
)
Saved at: {path}",
))
}
Self::Photo { caption, .. } => {
Self::Photo { .. } => {
let path = saved_path.map(|p| p.display().to_string()).unwrap_or_default();
format!(
"[TELEGRAM SYSTEM INFO]\n\
The user has sent a photo.\n\
Saved at: {path}{}",
caption_line(caption.as_deref()),
)
system_extra(&format!(
"The user has sent a photo.\n\
Saved at: {path}",
))
}
Self::Location { latitude, longitude, accuracy, is_live } => {
let maps_url = format!("https://maps.google.com/?q={latitude},{longitude}");
@@ -91,20 +93,13 @@ impl TelegramAttachment {
.map(|a| format!("\nAccuracy: ±{a:.0} m"))
.unwrap_or_default();
let kind = if *is_live { "live location (snapshot at time of receipt)" } else { "location" };
format!(
"[TELEGRAM SYSTEM INFO]\n\
The user has shared a {kind}.\n\
system_extra(&format!(
"The user has shared a {kind}.\n\
Latitude: {latitude}\n\
Longitude: {longitude}{accuracy_line}\n\
Maps URL: {maps_url}"
)
Maps URL: {maps_url}",
))
}
}
}
}
fn caption_line(caption: Option<&str>) -> String {
caption
.map(|c| format!("\nCaption: {c}"))
.unwrap_or_default()
}
+8 -6
View File
@@ -475,12 +475,10 @@ async fn handle_voice(
};
info!(chat_id = chat_id.0, "telegram: voice transcribed, forwarding to LLM");
let message = format!(
"[TELEGRAM SYSTEM INFO]\n\
The user sent a voice message. The following is the audio transcript:\n\n\
{text}"
);
handle_llm_message(bot.clone(), chat_id, message, None, Arc::clone(shared), handle).await;
// The transcript is the user's actual message — forward it verbatim as the
// user text, with no harness wrapper. The agent treats it exactly as if the
// user had typed those words.
handle_llm_message(bot.clone(), chat_id, text, None, Arc::clone(shared), handle).await;
}
// ── Edited message (live location updates) ────────────────────────────────────
@@ -548,7 +546,11 @@ async fn handle_attachment(
handle_llm_message(bot, chat_id, caption, Some(metadata), shared, handle).await;
}
None => {
// File-less attachment (Location): the `<system-extra>` block is the
// whole user message, so strip the leading blank lines `system_extra`
// adds for the concatenation case.
let message = attachment.system_info_message(None);
let message = message.trim_start_matches(['\n', '\r']).to_owned();
handle_llm_message(bot, chat_id, message, None, shared, handle).await;
}
}
@@ -4,7 +4,7 @@
"role": "system"
},
{
"content": "old shot\n\n[SYSTEM INFO]\n1 attached file:\n* uploads/1/shot.png",
"content": "old shot\n\n<system-extra>\n1 attached file:\n* uploads/1/shot.png\n</system-extra>",
"role": "user"
},
{
@@ -110,6 +110,8 @@ impl SystemContextSource for AgentSystemContext {
}
}
static_content = resolve_harness_tag(static_content);
// The scratchpad sits before the conversation: shared by every agent of
// the session, and re-read every turn (it changes, so it is its own
// message rather than part of the cached prefix).
@@ -386,10 +388,44 @@ fn non_empty(s: &Option<String>) -> Option<&str> {
s.as_deref().map(str::trim).filter(|s| !s.is_empty())
}
/// Replaces the `__HARNESS_TAG__` sentinel with the canonical harness-data tag
/// name (`SYSTEM_EXTRA_TAG`). A no-op when the prompt never mentions the
/// sentinel, so it is safe to run unconditionally on every system context.
///
/// `common/harness.md` (included by the chat agents) documents the tag through
/// this sentinel, so the instruction the model sees and the tag actually
/// emitted by `system_extra()` can never diverge: both read `SYSTEM_EXTRA_TAG`.
fn resolve_harness_tag(content: String) -> String {
if content.contains("__HARNESS_TAG__") {
content.replace("__HARNESS_TAG__", core_api::message_meta::SYSTEM_EXTRA_TAG)
} else {
content
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn harness_tag_resolves_to_canonical_tag() {
// Every occurrence of the sentinel is replaced with the tag emitted by
// `system_extra()` — single source of truth: `SYSTEM_EXTRA_TAG`.
let input = "Data lives in <__HARNESS_TAG__>…</__HARNESS_TAG__> blocks.";
let out = resolve_harness_tag(input.into());
let tag = core_api::message_meta::SYSTEM_EXTRA_TAG;
assert!(out.contains(&format!("<{tag}>")), "{out}");
assert!(out.contains(&format!("</{tag}>")), "{out}");
assert!(!out.contains("__HARNESS_TAG__"), "sentinel survived: {out}");
}
#[test]
fn harness_tag_is_noop_when_absent() {
let input = "Plain prompt, no sentinel here.";
let out = resolve_harness_tag(input.into());
assert_eq!(out, input);
}
#[test]
fn shared_folders_table_renders_access_and_description() {
use crate::db::shared_folders::SharedFolderAccess;