mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-08 08:04:25 -10:00
fix(tools): offer retrieve_tool_result whenever a result names a saved copy
Since #6508 (v0.10.1), one budget decides how much of a tool result the model
sees inline: 3% of the route's context window. A larger result is cut to a
head and tail around a footer that names the saved artifact and says to call
retrieve_tool_result with its art_ ref. Two paths left that instruction
pointing at a tool the model did not have:
- activate_result_dependencies admitted retrieve_tool_result only for results
marked evidence_available. A result cut by the inline budget gets an
artifact ref from spillover or preserve_full_output_for_model_context, but
never that flag.
- `exec --allowed-tools` dropped retrieve_tool_result from the catalog.
On a 16,384-token route the budget is about 1,966 characters, so nearly any
real tool output is cut. The CodewhaleOS session reproduced this on 0.10.2
(93061349b3): a custom 16K openai-compatible route ran `exec --auto
--allowed-tools <one MCP tool>` against a tool returning about 4 KB. The
model received about 1,928 characters plus the retrieval hint, answered with
whitespace, and exec failed as "model tool response is malformed, truncated
or violates the declared tools".
Now the dependency is admitted whenever the result's metadata carries an art_
ref (context::offers_retrieval, on the same recovery_ref the view uses for
its footer). The allow-list always passes retrieve_tool_result: it is
read-only and resolves only the session's own artifacts, and an explicit
deny still removes it.
Not changed, follow-ups: the 3% budget has no floor for small windows, and an
empty or whitespace-only reply is still reported as a malformed tool
response.
Verification: k90 nextest (crates/tui lib) includes core::engine:: and tools::truncate:: filters: 4838 tests run, 4835 passed; the 3 failures were a coordination-lock collision and a frozen-painter parity test, neither in this change. cargo check -p codewhale-tui --lib --tests: exit 0.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
59bbd679f2
commit
9d3ef3ce40
2 files changed
+7
-2
No files matched your search
@@ -54,6 +54,10 @@ struct RecoveryRef<'a> {
|
||||
artifact_id: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub(super) fn offers_retrieval(metadata: Option<&Value>) -> bool {
|
||||
recovery_ref(metadata).is_some_and(|recovery| recovery.artifact_id.is_some())
|
||||
}
|
||||
|
||||
fn recovery_ref(metadata: Option<&Value>) -> Option<RecoveryRef<'_>> {
|
||||
let obj = metadata?.as_object()?;
|
||||
let text = |key: &str| {
|
||||
|
||||
@@ -461,7 +461,8 @@ pub(crate) fn activate_result_dependencies(
|
||||
.as_ref()
|
||||
.and_then(|metadata| metadata.get("evidence_available"))
|
||||
.and_then(Value::as_bool)
|
||||
== Some(true);
|
||||
== Some(true)
|
||||
|| super::context::offers_retrieval(result.metadata.as_ref());
|
||||
if !needs_retrieval {
|
||||
return false;
|
||||
}
|
||||
@@ -626,7 +627,7 @@ pub(super) fn tool_allowed(allowed_tools: Option<&[String]>, tool_name: &str) ->
|
||||
let Some(allowed_tools) = allowed_tools else {
|
||||
return true;
|
||||
};
|
||||
tool_matches_any_rule(allowed_tools, tool_name)
|
||||
tool_name == TOOL_RESULT_RETRIEVAL_NAME || tool_matches_any_rule(allowed_tools, tool_name)
|
||||
}
|
||||
|
||||
pub(crate) fn tool_denied(disallowed_tools: Option<&[String]>, tool_name: &str) -> bool {
|
||||
|
||||
Reference in new issue
Block a user