Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
from CLI, TUI, and ACP. Instruction re-discovery is skipped in a `--safe-mode` session so `/cd`
cannot silently re-load project instructions and defeat the flag. Conversation history, active
goals, and skill state are preserved across the switch (#6032).
- **zeph-tools/zeph-llm**: foundational type plumbing for multimodal MCP `ContentBlock::Image`
passthrough (spec-072, #6229 P0 of 4). Added `ToolOutput.media: Vec<zeph_llm::ImageData>`
(empty by default, `#[derive(Default)]` on `ToolOutput`), a new `zeph-tools → zeph-llm`
dependency edge, and a redacting `impl Debug for ImageData` (`[image: {mime}, {n} bytes]`,
never the raw bytes), hardening a latent/reachable-by-construction Debug-derive leak on
`ImageData` as defense-in-depth for the existing user-upload image path (no production call
site currently Debug-formats `ImageData`/`Message`; debug-dump output uses `Serialize`, not
`Debug`). Purely additive — `media` is never populated yet, so this PR changes no runtime
behavior. Decode/validate/attach logic, the ephemeral persistence strip, vision-tier routing,
and the config/CLI/TUI surface are deferred to P1–P3 follow-up issues.

### Changed

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions crates/zeph-acp/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ impl zeph_tools::ToolExecutor for AcpFileExecutor {
locations: Some(vec![resolved_str]),
raw_response,
claim_source: Some(zeph_tools::ClaimSource::FileSystem),
..Default::default()
}))
}
"write_file" if self.can_write => {
Expand Down Expand Up @@ -491,6 +492,7 @@ impl AcpFileExecutor {
locations: Some(vec![params.path]),
raw_response: None,
claim_source: Some(zeph_tools::ClaimSource::FileSystem),
..Default::default()
}))
}

Expand Down Expand Up @@ -562,6 +564,7 @@ impl AcpFileExecutor {
locations: Some(vec![params.path]),
raw_response: None,
claim_source: Some(zeph_tools::ClaimSource::FileSystem),
..Default::default()
}))
}

Expand Down Expand Up @@ -632,6 +635,7 @@ impl AcpFileExecutor {
locations: None,
raw_response: None,
claim_source: Some(zeph_tools::ClaimSource::FileSystem),
..Default::default()
}))
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/zeph-acp/src/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ impl AcpShellExecutor {
locations: None,
raw_response: None,
claim_source: Some(zeph_tools::ClaimSource::Shell),
..Default::default()
}))
}

Expand Down Expand Up @@ -449,6 +450,7 @@ impl zeph_tools::ToolExecutor for AcpShellExecutor {
locations: None,
raw_response,
claim_source: Some(zeph_tools::ClaimSource::Shell),
..Default::default()
}))
}

Expand Down
1 change: 1 addition & 0 deletions crates/zeph-bench/src/loaders/tau2_bench/envs/airline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ impl ToolExecutor for AirlineEnv {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down
1 change: 1 addition & 0 deletions crates/zeph-bench/src/loaders/tau2_bench/envs/retail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ impl ToolExecutor for RetailEnv {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down
1 change: 1 addition & 0 deletions crates/zeph-core/src/agent/speculative/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ mod tests {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down
1 change: 1 addition & 0 deletions crates/zeph-core/src/agent/tests/agent_tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ impl MockToolExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
Self::new(vec![Ok(Some(output))])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ async fn agent_handles_tool_execution_success() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))]);

let agent_channel = MockChannel::new(vec!["execute tool".to_string()]);
Expand Down Expand Up @@ -604,6 +605,7 @@ async fn agent_handles_tool_output_with_error_marker() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
})),
Ok(None),
]);
Expand All @@ -630,6 +632,7 @@ async fn agent_handles_empty_tool_output() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))]);

let mut agent = Agent::new(provider, channel, registry, None, 5, executor);
Expand Down Expand Up @@ -759,6 +762,7 @@ async fn agent_processes_multi_turn_tool_execution() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))]);

let mut agent = Agent::new(
Expand Down Expand Up @@ -799,6 +803,7 @@ async fn agent_respects_max_shell_iterations() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
})));
}
let executor = MockToolExecutor::new(outputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl DagAwareToolExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions crates/zeph-core/src/agent/tests/inline_tool_loop_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl CallableToolExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))])
}

Expand Down Expand Up @@ -174,6 +175,7 @@ async fn multiple_tool_iterations_before_text() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
})),
Ok(Some(ToolOutput {
tool_name: "test_tool".into(),
Expand All @@ -186,6 +188,7 @@ async fn multiple_tool_iterations_before_text() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
})),
]);

Expand Down Expand Up @@ -249,6 +252,7 @@ async fn network_deny_wrapped_executor_blocks_fetch_before_reaching_inner() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down Expand Up @@ -356,6 +360,7 @@ async fn elicitation_event_during_tool_execution_is_handled() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down
3 changes: 3 additions & 0 deletions crates/zeph-core/src/agent/tests/shutdown_summary_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ async fn filter_stats_metrics_increment_on_normal_native_tool_path() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down Expand Up @@ -432,6 +433,7 @@ impl zeph_tools::executor::ToolExecutor for TwoToolExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
} else {
Ok(Some(zeph_tools::executor::ToolOutput {
Expand All @@ -453,6 +455,7 @@ impl zeph_tools::executor::ToolExecutor for TwoToolExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ impl ToolExecutor for FixedOutputExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down Expand Up @@ -817,6 +818,7 @@ impl ToolExecutor for FirstFailsExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ impl ToolExecutor for AlwaysOkSpecExec {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ impl zeph_tools::executor::ToolExecutor for DelayExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down Expand Up @@ -90,6 +91,7 @@ impl zeph_tools::executor::ToolExecutor for FailingNthExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down Expand Up @@ -420,6 +422,7 @@ async fn handle_tool_result_with_output_returns_true() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
let result = agent
.handle_tool_result("response", Ok(Some(output)))
Expand Down Expand Up @@ -451,6 +454,7 @@ async fn handle_tool_result_empty_output_returns_false() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
let result = agent
.handle_tool_result("response", Ok(Some(output)))
Expand Down Expand Up @@ -482,6 +486,7 @@ async fn handle_tool_result_error_prefix_triggers_anomaly_error() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
// reflection_used = true so reflection path is skipped
agent.services.learning_engine.mark_reflection_used();
Expand Down Expand Up @@ -518,6 +523,7 @@ async fn handle_tool_result_stderr_prefix_triggers_anomaly_error() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
agent.services.learning_engine.mark_reflection_used();
let result = agent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ async fn handle_tool_result_sends_output_when_streamed_true() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
agent
.handle_tool_result("response", Ok(Some(output)))
Expand Down Expand Up @@ -212,6 +213,7 @@ async fn handle_tool_result_fenced_emits_tool_start_then_output_via_loopback() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
agent
.handle_tool_result("response", Ok(Some(output)))
Expand Down Expand Up @@ -291,6 +293,7 @@ async fn handle_tool_result_locations_propagated_to_loopback_event() {
locations: Some(vec!["/src/main.rs".to_owned()]),
raw_response: None,
claim_source: None,
..Default::default()
};
agent
.handle_tool_result("response", Ok(Some(output)))
Expand Down Expand Up @@ -344,6 +347,7 @@ async fn handle_tool_result_display_is_raw_body_not_markdown_wrapped() {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};
agent
.handle_tool_result("response", Ok(Some(output)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,7 @@ impl ToolExecutor for TransientThenOkExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ impl ToolExecutor for FixedOutputExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down Expand Up @@ -209,6 +210,7 @@ impl ToolExecutor for FirstSuccessExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down Expand Up @@ -250,6 +252,7 @@ impl ToolExecutor for DispatchingExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
})),
"tool-retryable" if idx == 1 => Err(ToolError::Execution(std::io::Error::new(
std::io::ErrorKind::TimedOut,
Expand All @@ -266,6 +269,7 @@ impl ToolExecutor for DispatchingExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
})),
_ => Err(ToolError::Execution(std::io::Error::new(
std::io::ErrorKind::TimedOut,
Expand Down Expand Up @@ -546,6 +550,7 @@ async fn skipped_output_processing_does_not_reset_cross_iteration_utility_window
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
};

// Two LLM iterations, each: note_action records a non-ToolCall (Retrieve)
Expand Down Expand Up @@ -2203,6 +2208,7 @@ impl ToolExecutor for RecordingExecutor {
locations: None,
raw_response: None,
claim_source: None,
..Default::default()
}))
}
}
Expand Down
Loading
Loading