fix(skills): a skill body stops at the 25k-token read cap
`read_file` exempted SKILL.md from every limit, and both injection paths (`/skill` expansion and the `skill` tool) pasted the whole body. A 220 KB skill put 55k tokens into the context on each call. `cap_skill_body` cuts an over-cap body at the last line boundary that fits (a char boundary when the body is one long line) and appends a note that points at offset and limit. It runs before `apply_substitutions`, so the arguments land after the cut. Both injection paths call it and log the cut. `read_file` returns a SKILL.md whole only while it fits the cap. Over the cap it reads like any other file: offset and limit apply, and a window that is still too large answers FileTooLarge. Without that the note would send the model to a read that ignores its range. `skill_file_skips_token_limit` pinned the exemption; it gives way to `skill_file_over_cap_returns_file_too_large` and `skill_file_over_cap_honors_offset_and_limit`, as upstream did. Ported from upstream (grok-build tools skills/skill.rs cap_skill_body and read_file skill_full, 1.0.33). Upstream's `max_output_bytes` read budget in the same hunk is a feature and stays out.
This commit is contained in:
6 files changed
+163
-28
No files matched your search
@@ -6,6 +6,7 @@
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::implementations::skills::body_cap::cap_skill_body;
|
||||
use crate::implementations::skills::skill::{SkillOutput, extract_skill_body, format_skill_name};
|
||||
use crate::implementations::skills::types::SkillInfo;
|
||||
use crate::types::requirements::{Expr, ToolRequirement};
|
||||
@@ -279,7 +280,7 @@ impl kigi_tool_runtime::Tool for SkillTool {
|
||||
}
|
||||
};
|
||||
|
||||
let content = match load_skill_content(&skill).await {
|
||||
let mut content = match load_skill_content(&skill).await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
return Ok(SkillOutput {
|
||||
@@ -292,6 +293,14 @@ impl kigi_tool_runtime::Tool for SkillTool {
|
||||
}
|
||||
};
|
||||
|
||||
if cap_skill_body(&mut content) {
|
||||
tracing::info!(
|
||||
skill = %skill.name,
|
||||
path = %skill.path,
|
||||
"skill body truncated at read cap"
|
||||
);
|
||||
}
|
||||
|
||||
let files = list_skill_files(&skill, 10).await;
|
||||
|
||||
let output = format_output(&skill, &content, &files);
|
||||
|
||||
Reference in new issue
Block a user