Skip to content

feat: agent runtime capabilities — cancellation, usage, parallel tools, reasoning levels + docs - #6

Open
dynamder wants to merge 4 commits into
mainfrom
feat/agent-cancellation-and-capabilities
Open

feat: agent runtime capabilities — cancellation, usage, parallel tools, reasoning levels + docs#6
dynamder wants to merge 4 commits into
mainfrom
feat/agent-cancellation-and-capabilities

Conversation

@dynamder

Copy link
Copy Markdown
Owner

Summary

Agent runtime capabilities batch + full documentation proofread, verified locally with act against the CI workflow.

Highlights

  • Cancellation — every entry point (\ ire\ → \FireHandle, \ ire_stream, \send, \send_stream) carries a per-call \CancellationToken: \cancel()\ or dropping the handle immediately stops receiving output, abandons in-flight tool executions (shared workers survive), and emits \AgentEvent::Cancelled\ through the middleware chain and subscribers — never into session history. Awaiting a cancelled handle yields \OrchestrateError::Cancelled. Cancellation is fully cooperative (\�iased\ selects on stream consumption, the initial provider request, and tool execution) so middleware notification is reliable.
  • Token usage tracking — \TokenUsage\ + \TokenEvent::Usage; requests set \stream_options.include_usage; DeepSeek/OpenAI report usage; \ChatResponse.usage. Cost computation left to callers.
  • Parallel tool execution — \max_concurrent_tools\ (default 4) workers over the shared tool bus.
  • Reasoning levels — \ReasoningLevel\ (Off/Minimal/Low/Medium/High/XHigh/Max) with hot-reload via \AgentRuntime::set_reasoning_level; DeepSeek mirrors the official harness (\ hinking\ +
    easoning_effort\ for high/max), OpenAI maps to
    easoning_effort\ (xhigh/max clamped to high).
  • Stable session id — \AgentRuntime::session_id\ reused by \send/\send_stream; \ ire\ keeps a fresh one-shot id (fork semantics).
  • Message serde gating — new \serde\ feature on \ unera-core\ gates Serialize/Deserialize on the chat message types.
  • *\Tool::is_shell_tool* — ShellPolicy scrutiny applies by an explicit marker instead of a hard-coded tool-name list.
  • Docs — README/docs proofread against the code (incl. fixing the \ ool_policy\ run command), new \cancel\ example, mdBook rebuilt.

Breaking change

\Agent::fire\ now returns a \FireHandle: use \�gent.fire(msg, &runtime).await?.await?\ (all examples/doctests updated).

Verification

  • Full test matrix passes: funera-core 104 + 9 doctests, funera-orchestrate 69 + doctests, builtin-tools 59.
  • CI validated locally with act on Linux containers: fmt, msrv (Rust 1.88), doc, mdbook, doc-test, clippy (-D warnings), test-core (3 feature sets), test-orchestrate (6 feature sets), feature-matrix (cargo-hack powerset) — all green.
  • act surfaced two real issues that were fixed: a cancellation race (unbiased select could consume a chunk before cancelling) and a clippy \clone_on_copy.
  • Not run locally: semver / coverage / mutants / test-cross (need release metadata, tokens, or a multi-OS matrix — real CI covers them).

Commits

  • feat(core): serde-gated messages, stable session id, usage, parallel tools, reasoning levels, shell marker, cancellable loop
  • feat(orchestrate): cancellable handles (FireHandle), usage/reasoning/parallel wiring, cancel example
  • feat(builtin-tools): ShellTool opts in via Tool::is_shell_tool
  • docs: proofread docs against code, rebuild mdBook, fix tool_policy command

…tools, reasoning levels, shell marker, cancellable loop

- serde: gate Serialize/Deserialize derives on chat message types behind a new \serde\ feature, with round-trip tests
- session: FuneraSession::with_id; AgentRuntime carries a stable session_id reused by send/send_stream (fire keeps a fresh one-shot id)
- usage: TokenUsage + TokenEvent::Usage; requests set stream_options.include_usage; DeepSeek/OpenAI providers report usage
- parallel tools: max_concurrent_tools workers over a shared tool bus
- reasoning: ReasoningLevel (Off..Max) with hot-reload; DeepSeek mirrors the official harness (thinking + reasoning_effort), OpenAI maps to reasoning_effort (xhigh/max clamped to high)
- Tool::is_shell_tool marker (default false); ShellPolicy applies by marker instead of hard-coded tool names; ShellTool opts in
- cancellation: per-call CancellationToken through ReActLoopConfig, ToolExecCommand, and every blocking await (biased select); the loop emits MiddlewareEvent::cancelled on cancel
- fix CI-found issues: biased cancellation selects, clippy clone_on_copy
…parallel wiring, cancel example

- Agent::fire returns FireHandle; all four entry points carry a per-call CancellationToken exposed as cancel(); dropping any handle auto-cancels
- AgentEvent::Cancelled flows through the middleware chain and subscribers (never into session history); awaiting a cancelled handle yields OrchestrateError::Cancelled; recv() returns None once cancelled
- ChatResponse.usage carries the last turn's TokenUsage
- builder knobs: max_concurrent_tools, reasoning_level; set_reasoning_level hot-reload; AgentRuntime::session_id
- new example: cancel (explicit cancel, drop-to-cancel, timeout, middleware notification)
- fire() call sites updated across examples, integration tests, and doctests
…mmand

- README: cancellation feature bullet + cancel example row; fire() double-await in quick starts
- docs/architecture.md: Cancellation section (handles, cooperative exit, AgentEvent::Cancelled never written to session)
- docs/examples/README.md: cancel example listed
- docs/getting-started.md: fix tool_policy run command (missing --features security); fire() double-await
- docs/concepts/effects.md: tool registration is an internal pairing, not an extension API (external code must not couple to the tool registry)
- CHANGELOG: serde/session-id/usage/parallel/reasoning/cancellation entries
- book/: rebuilt with mdbook (includes the Cancellation section)
ShellPolicy scrutiny now applies by the marker instead of a hard-coded tool-name list.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant