1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//! Loop-facing completion signal for background Bash shells (issue #84 Phase 2b
//! follow-up: push completion into the loop instead of only polling at turn end).
//!
//! A `run_in_background` shell (or an auto-promoted long command) runs detached
//! from the agent loop. When it finishes, the loop should learn the result the
//! same way it learns a sub-agent finished — pushed in, not polled.
//! [`BashCompletionSink`] is that push: the background completion-poll task
//! invokes it once per shell on exit, and the engine's implementation delivers
//! the result into the owning session's loop (injected at the next round
//! boundary when the loop is actively iterating; via a resume when it is idle).
//!
//! The trait lives in `bamboo-agent-core` — NOT `bamboo-engine` — because the
//! producer (`bamboo_tools::tools::bash_runtime::spawn_completion_poll`) is in
//! the tools crate, which depends on this crate but not on the engine. This is
//! the one deliberate wiring divergence from the sibling `ChildCompletionHandler`
//! (which can live in the engine because its own producer does too).
/// Data delivered to a [`BashCompletionSink`] when a background shell exits.
/// Loop-facing sink invoked exactly once when a background Bash shell completes.
///
/// Implementations MUST be cheap and non-blocking on the calling task: the
/// producer invokes this from the shell's completion-poll task, so the
/// implementation should hand the delivery to a detached task (mirroring the
/// sibling `BashResumeHook`) rather than doing I/O inline.
///
/// Delivery MUST stay idempotent with the durable end-of-turn suspend/poll
/// backstop: the same completion can also be observed by that poll, so an
/// implementation must not double-deliver (e.g. guard on the persisted bash
/// wait) and must treat the push purely as a latency optimization over the poll.