Skip to main content

everruns_capability/
lib.rs

1#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
2//! The neutral Everruns capability contract (EVE-873).
3//!
4//! One open identity/configuration contract shared by the `everruns`
5//! Framework, the hosted product composition, and integration crates:
6//!
7//! - [`CapabilityId`]: an open, string-based capability identifier with one
8//!   validation rule set (character set, length, reserved namespace).
9//! - [`CapabilityRef`]: a reference to a capability implementation plus its
10//!   per-agent JSON object configuration. This is the persisted attachment
11//!   representation and the Framework activation value — the same bytes
12//!   round-trip through application code, database rows, and worker
13//!   resolution.
14//! - [`CapabilitySpec`] and the non-sealed [`IntoCapability`]: the open
15//!   conversion seam application values use to become capability
16//!   registrations.
17//! - [`Definition`] (feature `definition`): the code-defined capability
18//!   authoring surface — typed tool handlers, schema metadata, structured
19//!   execution errors — with no engine or host dependency.
20//! - [`CapabilityIdIndex`] and [`ActivationSet`]: canonical-id/alias
21//!   bookkeeping and duplicate/collision rejection shared by registries.
22//!
23//! This crate deliberately depends on neither `everruns-core` nor
24//! `everruns-host`, and carries no Tokio, HTTP, SQLx, OpenAPI, inventory, or
25//! platform-record dependency. Third-party capability crates can depend on
26//! this crate alone; application authors normally consume the same types
27//! re-exported from `everruns`. Part of the [Everruns](https://everruns.com)
28//! ecosystem.
29//!
30//! # Example
31//!
32//! ```
33//! use everruns_capability::{CapabilityRef, CapabilitySpec, IntoCapability};
34//! use serde_json::json;
35//!
36//! struct VendorSearch {
37//!     index: String,
38//! }
39//!
40//! impl IntoCapability for VendorSearch {
41//!     fn into_capability(self) -> CapabilitySpec {
42//!         CapabilityRef::new("vendor.search")
43//!             .config(json!({ "index": self.index }))
44//!             .into()
45//!     }
46//! }
47//!
48//! let spec = VendorSearch { index: "prod".into() }.into_capability();
49//! assert_eq!(spec.capability_ref().id(), "vendor.search");
50//! ```
51
52#![deny(missing_docs)]
53
54mod error;
55mod id;
56pub mod presets;
57mod reference;
58mod registry;
59mod spec;
60
61#[cfg(feature = "definition")]
62pub mod definition;
63
64pub use error::CapabilityError;
65pub use id::{
66    CapabilityId, PLUGIN_CAPABILITY_PREFIX, RESERVED_CAPABILITY_ID_NAMESPACE, is_plugin_capability,
67    parse_plugin_capability_id, plugin_capability_id, validate_capability_id,
68};
69pub use presets::{GENERIC_HARNESS_NAME, generic_capabilities};
70pub use reference::{CapabilityRef, validate_capability_config};
71pub use registry::{ActivationSet, CapabilityIdIndex};
72pub use spec::{CapabilitySpec, CapabilitySpecParts, IntoCapability};
73
74#[cfg(feature = "definition")]
75pub use definition::{Definition, json_schema_for};
76
77// Dependency re-exports so downstream capability crates can align derive
78// macro paths (`#[serde(crate = "...")]`) without adding their own pins.
79pub use serde;
80pub use serde_json;
81
82#[cfg(feature = "definition")]
83pub use async_trait::async_trait;
84#[cfg(feature = "definition")]
85pub use schemars;