Releases: rustakka/atomr-agents
v0.21.0
Added — Claude Agent SDK harness
Anthropic's Claude Agent SDK (claude-agent-sdk /
@anthropic-ai/claude-agent-sdk) — the programmable form of Claude Code —
wrapped as a first-class atomr-agents harness. It exposes Claude Code's full
feature set (slash commands, subagents, hooks, MCP, permission modes,
sessions, custom system prompts, built-in Read/Write/Edit/Bash/Grep/WebSearch
tools) and bills against your Anthropic API credits by driving the bundled
claude CLI. Distinct from the server-side "Managed Agents" API.
atomr-agents-agent-sdk-core— the contract:AgentSdkConfigmirroring
the SDK'sClaudeAgentOptions(round-trips to a JSON dict), a normalized
message/result/event schema, and the pluggableAgentSdkBackend/
AgentSdkSessiontrait seam with a deterministic in-memoryMockBackendso
the whole surface is testable without the SDK, theclaudeCLI, or
network/credits.atomr-agents-agent-sdk-harness— orchestrator with a pluggable backend,
an event broadcast, a session registry under an atomically-reserved
concurrency quota, Anthropic-credit spend tracking via the shared
SpendLedger, a.claude/projection (skills / slash commands / MCP /
settings), and aCallableimpl. Behind theactorfeature it exposes the
bidirectional interactive session as anatomr_core::actor::Actor. The
defaultpermission_modeisbypassPermissions(max autonomy — overridable
per request/spec).atomr-agents-agent-sdk-harness-web— axum REST + SSE companion (start
runs/sessions, post messages, interrupt, change mode/model, stream events).- PyO3 bridge —
from atomr_agents.agent_sdk import harness. The Rust
PythonAgentSdkBackenddrives the realclaude-agent-sdkover a reverse
async-iterator bridge (Rust drives the Python__anext__); the interactive
session is exposed asAgentSdkSession(the actor surface). atomr@tool
guests and Rust tools are bridged into the agent as in-process SDK MCP tools
viacreate_sdk_mcp_server. - Per-session sandbox workspaces (Pattern C) — behind the harness
sandbox
feature, each interactive session (and each headless run) gets its own
isolated microVM sandbox as a disposable
workspace: the.claude/projection is staged into it (write_file), the
agent's exec/file is routed there via an in-processrun_in_sandboxtool
while the hostBash/Write/Editare disabled (true containment), and the
workspace is discarded — or snapshotted to the warm pool — on close
(spec.workspace.{enabled,profile,backend,on_close,reuse_warm}). One
SandboxClientis shared between the Rust harness and the Python tool so both
resolve the workspace from a single registry;SandboxClient.attach(id)
binds the tool. See Pattern C indocs/agent-sdk-harness.md. - Host loader —
<root>/agent-sdk/<id>/(harness.yaml+commands/+
skills/+mcp/) →AgentSdkHarnessSpec+.claudeprojection, reusing
the host's on-disk conventions. - Umbrella — new
agent-sdkfeature. - Packaging —
pip install atomr-agents[agent-sdk]pulls the SDK (which
auto-bundles theclaudeCLI); the native extension imports it lazily.
Added — MicroVM sandbox capability (local + dev tiers)
Secure, instant-boot compute environments for executing untrusted agent
code (Python / Bash / JavaScript / Rust), per the Agentic MicroVM
Sandboxes PRD. This wave lands the backend-agnostic foundation plus the
locally-runnable tiers; the Firecracker/KVM backend and the Tier-3 gRPC
cluster are the documented next milestones.
atomr-agents-sandbox-core—SandboxBackend/SandboxHandle
traits, profile / budget / request types (with the security-relevant
Rust 2 GB / 2 vCPU floor),SandboxEventstream, and a deterministic
in-memoryMockBackendso the whole surface is testable without Docker
or KVM.atomr-agents-sandbox-harness— orchestrator with a pluggable
backend, a sandbox registry under an atomically-reserved concurrency
quota, a best-fit bin-packing scheduler, a warm snapshot pool, lifecycle
event broadcast, and aCallableimpl. The Rust budget floor is enforced
structurally at the harness boundary.atomr-agents-sandbox-tool— theexecute_in_sandboxTool.atomr-agents-sandbox-backend-docker— bollard-backed "insecure dev
mode" backend (real exec, tar file I/O, commit-based snapshot/fork).
Containers share the host kernel, so this is explicitly not an isolation
boundary for untrusted code.atomr-agents-sandbox-harness-web— axum REST + SSE companion.atomr-agents-sandbox-proto— host↔guest wire protocol
(length-prefixed postcard frames over AF_VSOCK).atomr-agents-sandbox-guest-agent— the in-VM PID-1 guest daemon.- PyO3 bindings —
from atomr_agents.sandbox import SandboxClient, SandboxConfig, SandboxProfile. - Umbrella — new
sandboxfeature.
Changed — Coding-CLI vendor: Gemini CLI → Antigravity CLI (agy)
Google is transitioning the Gemini CLI into the Antigravity CLI; the
legacy gemini CLI stops serving requests on 2026-06-18. The
coding-cli-vendor-gemini crate is renamed to
atomr-agents-coding-cli-vendor-antigravity and now targets the
agy binary. Unlike the old Gemini CLI, Antigravity serves non-Gemini
models (Claude, etc.) selectable via the model flag.
GeminiVendor→AntigravityVendor;GeminiParser→
AntigravityParser;materialize_gemini_config→
materialize_antigravity_config.- New
AntigravityConfigmakes the binary name, headless flags, and the
on-disk config directory (default.antigravity/) configurable — so
operators can reconcile them withagy's real interface without a code
change. - Harness Cargo feature
vendor-gemini→vendor-antigravity. - Default Docker image
gemini.Dockerfile→antigravity.Dockerfile
(installsagyvia the officialinstall.sh). - Breaking:
CliVendorKind::Gemini→CliVendorKind::Antigravity;
the serde wire value changes from"gemini"to"antigravity", so
persistedCliRequestJSON withvendor: "gemini"no longer
deserializes.
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed from `Arc<dyn Scor...
v0.20.0
Added — Claude Agent SDK harness
Anthropic's Claude Agent SDK (claude-agent-sdk /
@anthropic-ai/claude-agent-sdk) — the programmable form of Claude Code —
wrapped as a first-class atomr-agents harness. It exposes Claude Code's full
feature set (slash commands, subagents, hooks, MCP, permission modes,
sessions, custom system prompts, built-in Read/Write/Edit/Bash/Grep/WebSearch
tools) and bills against your Anthropic API credits by driving the bundled
claude CLI. Distinct from the server-side "Managed Agents" API.
atomr-agents-agent-sdk-core— the contract:AgentSdkConfigmirroring
the SDK'sClaudeAgentOptions(round-trips to a JSON dict), a normalized
message/result/event schema, and the pluggableAgentSdkBackend/
AgentSdkSessiontrait seam with a deterministic in-memoryMockBackendso
the whole surface is testable without the SDK, theclaudeCLI, or
network/credits.atomr-agents-agent-sdk-harness— orchestrator with a pluggable backend,
an event broadcast, a session registry under an atomically-reserved
concurrency quota, Anthropic-credit spend tracking via the shared
SpendLedger, a.claude/projection (skills / slash commands / MCP /
settings), and aCallableimpl. Behind theactorfeature it exposes the
bidirectional interactive session as anatomr_core::actor::Actor. The
defaultpermission_modeisbypassPermissions(max autonomy — overridable
per request/spec).atomr-agents-agent-sdk-harness-web— axum REST + SSE companion (start
runs/sessions, post messages, interrupt, change mode/model, stream events).- PyO3 bridge —
from atomr_agents.agent_sdk import harness. The Rust
PythonAgentSdkBackenddrives the realclaude-agent-sdkover a reverse
async-iterator bridge (Rust drives the Python__anext__); the interactive
session is exposed asAgentSdkSession(the actor surface). atomr@tool
guests and Rust tools are bridged into the agent as in-process SDK MCP tools
viacreate_sdk_mcp_server. - Host loader —
<root>/agent-sdk/<id>/(harness.yaml+commands/+
skills/+mcp/) →AgentSdkHarnessSpec+.claudeprojection, reusing
the host's on-disk conventions. - Umbrella — new
agent-sdkfeature. - Packaging —
pip install atomr-agents[agent-sdk]pulls the SDK (which
auto-bundles theclaudeCLI); the native extension imports it lazily.
Added — MicroVM sandbox capability (local + dev tiers)
Secure, instant-boot compute environments for executing untrusted agent
code (Python / Bash / JavaScript / Rust), per the Agentic MicroVM
Sandboxes PRD. This wave lands the backend-agnostic foundation plus the
locally-runnable tiers; the Firecracker/KVM backend and the Tier-3 gRPC
cluster are the documented next milestones.
atomr-agents-sandbox-core—SandboxBackend/SandboxHandle
traits, profile / budget / request types (with the security-relevant
Rust 2 GB / 2 vCPU floor),SandboxEventstream, and a deterministic
in-memoryMockBackendso the whole surface is testable without Docker
or KVM.atomr-agents-sandbox-harness— orchestrator with a pluggable
backend, a sandbox registry under an atomically-reserved concurrency
quota, a best-fit bin-packing scheduler, a warm snapshot pool, lifecycle
event broadcast, and aCallableimpl. The Rust budget floor is enforced
structurally at the harness boundary.atomr-agents-sandbox-tool— theexecute_in_sandboxTool.atomr-agents-sandbox-backend-docker— bollard-backed "insecure dev
mode" backend (real exec, tar file I/O, commit-based snapshot/fork).
Containers share the host kernel, so this is explicitly not an isolation
boundary for untrusted code.atomr-agents-sandbox-harness-web— axum REST + SSE companion.atomr-agents-sandbox-proto— host↔guest wire protocol
(length-prefixed postcard frames over AF_VSOCK).atomr-agents-sandbox-guest-agent— the in-VM PID-1 guest daemon.- PyO3 bindings —
from atomr_agents.sandbox import SandboxClient, SandboxConfig, SandboxProfile. - Umbrella — new
sandboxfeature.
Changed — Coding-CLI vendor: Gemini CLI → Antigravity CLI (agy)
Google is transitioning the Gemini CLI into the Antigravity CLI; the
legacy gemini CLI stops serving requests on 2026-06-18. The
coding-cli-vendor-gemini crate is renamed to
atomr-agents-coding-cli-vendor-antigravity and now targets the
agy binary. Unlike the old Gemini CLI, Antigravity serves non-Gemini
models (Claude, etc.) selectable via the model flag.
GeminiVendor→AntigravityVendor;GeminiParser→
AntigravityParser;materialize_gemini_config→
materialize_antigravity_config.- New
AntigravityConfigmakes the binary name, headless flags, and the
on-disk config directory (default.antigravity/) configurable — so
operators can reconcile them withagy's real interface without a code
change. - Harness Cargo feature
vendor-gemini→vendor-antigravity. - Default Docker image
gemini.Dockerfile→antigravity.Dockerfile
(installsagyvia the officialinstall.sh). - Breaking:
CliVendorKind::Gemini→CliVendorKind::Antigravity;
the serde wire value changes from"gemini"to"antigravity", so
persistedCliRequestJSON withvendor: "gemini"no longer
deserializes.
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-han...
v0.19.0
Added — MicroVM sandbox capability (local + dev tiers)
Secure, instant-boot compute environments for executing untrusted agent
code (Python / Bash / JavaScript / Rust), per the Agentic MicroVM
Sandboxes PRD. This wave lands the backend-agnostic foundation plus the
locally-runnable tiers; the Firecracker/KVM backend and the Tier-3 gRPC
cluster are the documented next milestones.
atomr-agents-sandbox-core—SandboxBackend/SandboxHandle
traits, profile / budget / request types (with the security-relevant
Rust 2 GB / 2 vCPU floor),SandboxEventstream, and a deterministic
in-memoryMockBackendso the whole surface is testable without Docker
or KVM.atomr-agents-sandbox-harness— orchestrator with a pluggable
backend, a sandbox registry under an atomically-reserved concurrency
quota, a best-fit bin-packing scheduler, a warm snapshot pool, lifecycle
event broadcast, and aCallableimpl. The Rust budget floor is enforced
structurally at the harness boundary.atomr-agents-sandbox-tool— theexecute_in_sandboxTool.atomr-agents-sandbox-backend-docker— bollard-backed "insecure dev
mode" backend (real exec, tar file I/O, commit-based snapshot/fork).
Containers share the host kernel, so this is explicitly not an isolation
boundary for untrusted code.atomr-agents-sandbox-harness-web— axum REST + SSE companion.atomr-agents-sandbox-proto— host↔guest wire protocol
(length-prefixed postcard frames over AF_VSOCK).atomr-agents-sandbox-guest-agent— the in-VM PID-1 guest daemon.- PyO3 bindings —
from atomr_agents.sandbox import SandboxClient, SandboxConfig, SandboxProfile. - Umbrella — new
sandboxfeature.
Changed — Coding-CLI vendor: Gemini CLI → Antigravity CLI (agy)
Google is transitioning the Gemini CLI into the Antigravity CLI; the
legacy gemini CLI stops serving requests on 2026-06-18. The
coding-cli-vendor-gemini crate is renamed to
atomr-agents-coding-cli-vendor-antigravity and now targets the
agy binary. Unlike the old Gemini CLI, Antigravity serves non-Gemini
models (Claude, etc.) selectable via the model flag.
GeminiVendor→AntigravityVendor;GeminiParser→
AntigravityParser;materialize_gemini_config→
materialize_antigravity_config.- New
AntigravityConfigmakes the binary name, headless flags, and the
on-disk config directory (default.antigravity/) configurable — so
operators can reconcile them withagy's real interface without a code
change. - Harness Cargo feature
vendor-gemini→vendor-antigravity. - Default Docker image
gemini.Dockerfile→antigravity.Dockerfile
(installsagyvia the officialinstall.sh). - Breaking:
CliVendorKind::Gemini→CliVendorKind::Antigravity;
the serde wire value changes from"gemini"to"antigravity", so
persistedCliRequestJSON withvendor: "gemini"no longer
deserializes.
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.18.0
Changed — Coding-CLI vendor: Gemini CLI → Antigravity CLI (agy)
Google is transitioning the Gemini CLI into the Antigravity CLI; the
legacy gemini CLI stops serving requests on 2026-06-18. The
coding-cli-vendor-gemini crate is renamed to
atomr-agents-coding-cli-vendor-antigravity and now targets the
agy binary. Unlike the old Gemini CLI, Antigravity serves non-Gemini
models (Claude, etc.) selectable via the model flag.
GeminiVendor→AntigravityVendor;GeminiParser→
AntigravityParser;materialize_gemini_config→
materialize_antigravity_config.- New
AntigravityConfigmakes the binary name, headless flags, and the
on-disk config directory (default.antigravity/) configurable — so
operators can reconcile them withagy's real interface without a code
change. - Harness Cargo feature
vendor-gemini→vendor-antigravity. - Default Docker image
gemini.Dockerfile→antigravity.Dockerfile
(installsagyvia the officialinstall.sh). - Breaking:
CliVendorKind::Gemini→CliVendorKind::Antigravity;
the serde wire value changes from"gemini"to"antigravity", so
persistedCliRequestJSON withvendor: "gemini"no longer
deserializes.
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.17.0
Changed — Coding-CLI vendor: Gemini CLI → Antigravity CLI (agy)
Google is transitioning the Gemini CLI into the Antigravity CLI; the
legacy gemini CLI stops serving requests on 2026-06-18. The
coding-cli-vendor-gemini crate is renamed to
atomr-agents-coding-cli-vendor-antigravity and now targets the
agy binary. Unlike the old Gemini CLI, Antigravity serves non-Gemini
models (Claude, etc.) selectable via the model flag.
GeminiVendor→AntigravityVendor;GeminiParser→
AntigravityParser;materialize_gemini_config→
materialize_antigravity_config.- New
AntigravityConfigmakes the binary name, headless flags, and the
on-disk config directory (default.antigravity/) configurable — so
operators can reconcile them withagy's real interface without a code
change. - Harness Cargo feature
vendor-gemini→vendor-antigravity. - Default Docker image
gemini.Dockerfile→antigravity.Dockerfile
(installsagyvia the officialinstall.sh). - Breaking:
CliVendorKind::Gemini→CliVendorKind::Antigravity;
the serde wire value changes from"gemini"to"antigravity", so
persistedCliRequestJSON withvendor: "gemini"no longer
deserializes.
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.16.3
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.16.2
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.13.0
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.12.0
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.
v0.11.0
Added — Meetings harness: structured extraction from diarized transcripts
A downstream harness that turns a diarized SttConversation into a
structured MeetingAnalysis — attendee roster, linear append-only
notes/actions ledgers, and a tiered dynamic summary stack. See
docs/meetings-harness.md.
crates/meetings-harness— the harness core: typed +
Boxed*split mirroringstt-harness;RuleBasedExtractor
default that is deterministic and LLM-free; pluggable
MeetingExtractortrait for LLM-driven implementations;
MeetingsToolSetofToolimpls (list_turns,upsert_attendee,
append_note,append_action,update_action,revise_tail_segment,
finalize_segment,regenerate_running,set_title,finalize).
BatchExtractionLoopandStreamingExtractionLoop— the latter
subscribes to an STT harness's broadcast and maintains an append-only
ledger with a revisable in-flight tail segment summary. Persistence
viaMeetingsStoreand (featurestate)CheckpointerMeetingsStore,
filed under the sameconversation_idas the source transcript.crates/meetings-harness-web— an optional axum backend plus an
embedded React + Vite SPA (port 7100) for reviewing and editing
analyses: REST CRUD, attendee rename, action patch, run trigger / stop,
WebSocket live feed ofMeetingsHarnessEvents, SPA fallback.atomr-agents meetings— new CLI subcommand.meetings analyze --conversation-id <id> --model <model_id>runs the harness against
an existing transcript;meetings serveboots the web UI. Gated by
--features meetings/--features meetings-web.
Added — STT harness: agentic streaming speech-to-text pipeline
A new capability layer that diarizes, transcribes, and accumulates a
conversation record aligned to agentic structures. See
docs/stt-harness.md.
crates/stt-harness— the harness core: audio sources (mic /
file / bytes), a streaming session actor, diarization + voice-mode
coalescing, the loop/termination strategies, and aConversationStore
with aCheckpointer-backed implementation (statefeature).
BoxedSttHarnessmirrors the Agent/Harness boxed-handle pattern.crates/stt-harness-web— an optional axum backend plus an
embedded React SPA (embed-uifeature, viarust-embed) for
reviewing and editing diarized conversations: REST routes, a
WebSocket live feed, and the SPA fallback handler.atomr-agents servenow runs the real review UI when the CLI is
built with--features stt-web, persisting conversations through the
configuredcrates/statecheckpointer.xtask stt-web-build— builds the React SPA intoui/distso
stt-harness-webcan be compiled with--features embed-ui.- Python bindings —
atomr_agents.stt_harnesswraps the harness;
the top-level facade now resolves native names defensively so a name
not yet bound on the Rust side degrades toNoneinstead of failing
the whole package import.
Added — Phase C: async scorers, guest adapters, boxed Agent/Harness, Python workflow runner
Closes the "Phase B" deferral comments scattered across crates/agent,
crates/harness, crates/eval, and crates/py-bindings/src/{agent, harness,workflow,eval}.rs. The five blocks:
AsyncScorertrait (crates/eval/src/scorer.rs). Parallel to
the existing syncScorer; blanketimpl<S: Scorer> AsyncScorer for Skeeps existing sync impls compatible.LlmJudgeScorer,
RubricScorer, andPairwiseScorernow implementAsyncScorer
directly — dropping thetokio::task::block_in_placeworkaround
the syncScorerimpl required.EvalSuite::scorerfield type
changed fromArc<dyn Scorer>toArc<dyn AsyncScorer>.- 6 Python→Rust guest adapters (
crates/py-bindings/src/guest/).
The single-fileguest.rs(331 LOC) is split into aguest/
directory (10 files, ~1400 LOC). New adapters:PyInstructionAdapter,
PyMemoryStrategyAdapter,PySkillStrategyAdapter,PyPersonaAdapter,
PyMemoryStoreAdapter,PyEmbedderAdapter. Each ships a
build_guest_*factory mirroring the existingbuild_guest_toolset
pattern. BoxedAgent+AgentSpec::into_agent(crates/agent/src/boxed.rs).
Object-erasedBoxedAgentfor config-driven instantiation. The typed
Agent<I,T,Ms,Sk>keeps hot-path monomorphization; both share a
pub(crate) async fn run_turn_implhelper.HarnessDispatch+HarnessRef+BoxedHarness(crates/harness/).
Mirror of the Agent boxed-handle pattern.Harness::into_boxed,
HarnessSpec::into_harness, andimpl HarnessDispatch for Harness<L,T>
added.PyAgent,PyHarness,PyWorkflowRunnerPython wrappers with
from_spec/from_dictconstructors and asyncrun_turn/run
exposed as Python coroutines via
pyo3_async_runtimes::tokio::future_into_py.WorkflowRunner::new
was added as a public constructor.
Changed
EvalSuite::scorerfield type:Arc<dyn Scorer>→
Arc<dyn AsyncScorer>. The blanketimpl<S: Scorer> AsyncScorer for Smeans callers holding a syncArc::new(SomeSyncScorer)
continue to compile via auto-unsizing into the new field type.
Direct&dyn Scorercallers ofLlmJudgeScorer/RubricScorer
must migrate to&dyn AsyncScorer— Rust coherence forbids both
the blanketAsyncScorerimpl and a directScorerimpl on the
same judge (ContainsScoreris unaffected).- Sibling deps (
atomr,atomr-infer,atomr-accel) consume
crates.io artifacts only — nopath = "../sibling/..."links.
Pinned to atomr 0.9.2 / atomr-infer 0.8.0 / atomr-accel 0.10.0.