kcode-k1-chat-thread-actions 0.1.1

Tool scheduling and update delivery for K1 chat threads
Documentation
# Public API

The crate publicly reexports `ActionId`, `ChatError`, `Runtime`, `ToolMode`, `ToolOutput`, `ToolRequest`, `ToolStart`, and `Updates` from `kcode_k1_chat_core`.

```rust
pub trait ActionSink: Send + Sync + 'static {
    fn submit(&self, event: ActionEvent) -> Result<(), ChatError>;
}

pub enum ActionEvent {
    Update { action: ActionId, identity: u64, update: SubmittedUpdate },
    ToolReplies { entries: Vec<Immediate>, finished: bool },
    ToolDone { action: ActionId, output: ToolOutput, started: Option<Instant> },
}

pub struct ToolCall {
    pub index: usize,
    pub action: ActionId,
    pub request: ToolRequest,
}

pub struct Immediate {
    pub index: usize,
    pub action: ActionId,
    pub kind: ImmediateKind,
    pub complete: bool,
}

pub enum ImmediateKind {
    Plain(String),
    Tool { output: ToolOutput, started: Option<Instant> },
    Worker(String),
}
```

`ActionSink` receives action events through the caller's queue. Prepared semantic and activity updates become `ActionEvent::Update`; the receiver owns lookup and deduplication.

```rust
impl ImmediateKind {
    pub fn text(&self) -> &str;
}
```

`text` returns the plain or worker text, or the tool output text. Performance: Not yet benchmarked; it performs constant work and allocates nothing.

```rust
impl Immediate {
    pub fn plain(index: usize, action: ActionId, text: String, complete: bool) -> Self;
    pub fn worker(index: usize, action: ActionId, text: String, complete: bool) -> Self;
}
```

`plain` and `worker` construct ordered immediate replies. Performance: Not yet benchmarked; each performs constant work and allocation while moving the supplied text.

```rust
pub fn start_tool_batch(
    runtime: Arc<dyn Runtime>,
    calls: Vec<ToolCall>,
    immediate: Vec<Immediate>,
    sink: Arc<dyn ActionSink>,
);

pub fn redrive_tool(
    runtime: Arc<dyn Runtime>,
    action: ActionId,
    request: ToolRequest,
    sink: Arc<dyn ActionSink>,
);
```

`start_tool_batch` starts every supplied tool without awaiting another call, combines supplied replies and tool replies in ascending call-index order, and applies one shared deadline two seconds after the batch begins. Results ready by that boundary are immediate; unresolved or queued tools emit queued text and continue without cancellation, with later terminal results retaining the same action ID and original start instant. Each tool is attempted once and receives `Updates` bound to its action ID; sink failure stops remaining delivery. Performance: Not yet benchmarked; package-owned admission work and peak allocation are linear in calls and immediate entries, all starts occur synchronously before return, immediate arbitration completes no earlier than required tool starts and no later than the shared two-second boundary plus runtime scheduling and sink overhead, and terminal tool completion is not bounded by this package.

`redrive_tool` starts one recovered tool once with the same action ID and request, suppresses queued acknowledgement, and sends only the fresh terminal result. Performance: Not yet benchmarked; package-owned admission work and allocation are constant outside request size, it returns after the synchronous start attempt, and terminal completion is not bounded by this package.