#[non_exhaustive]pub struct SkillCard {Show 13 fields
pub id: String,
pub name: String,
pub description: String,
pub tags: Vec<String>,
pub examples: Vec<String>,
pub input_modes: Vec<String>,
pub output_modes: Vec<String>,
pub security_requirements: Vec<String>,
pub input_schema: Option<Value>,
pub output_schema: Option<Value>,
pub execution_hints: Option<ExecutionHints>,
pub provider_config: Option<Value>,
pub body: String,
}Expand description
The A2A view of an Agent Skills SKILL.md.
The skill’s spec name is its catalog identity; metadata.a2a-id, when
present, is the wire id (AgentSkill.id) and otherwise the name is.
The other A2A fields come from a2a-* metadata keys, and the schemas and
provider config from JSON files under the skill directory. LLM-backed
skills supply execution hints and provider config; non-LLM skills omit
them. The Markdown body is the prompt template (used only by LLM-backed
skills); template grammar is {{ name }} with dotted paths.
SkillCard::from_embedded, SkillCard::from_skill and
TryFrom<&Skill> are the only constructors: the struct is #[non_exhaustive] and deliberately
implements neither Deserialize nor Default, so every card has passed
the metadata, strict-keyword and schema-compilation checks.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.id: String§name: String§description: String§examples: Vec<String>§input_modes: Vec<String>§output_modes: Vec<String>§security_requirements: Vec<String>§input_schema: Option<Value>§output_schema: Option<Value>§execution_hints: Option<ExecutionHints>§provider_config: Option<Value>§body: StringMarkdown body (prompt template for LLM-backed skills).
Implementations§
Source§impl SkillCard
impl SkillCard
Sourcepub fn from_skill(
skill: &Skill,
assets: impl Fn(&str) -> Option<String>,
) -> Result<Self, ManifestError>
pub fn from_skill( skill: &Skill, assets: impl Fn(&str) -> Option<String>, ) -> Result<Self, ManifestError>
Project a loaded skill onto a SkillCard, reading asset files
through assets.
assets is called with the path a metadata key names, relative to
the skill directory (assets/input.schema.json), and returns the
file’s text or None when it is absent. Use it for a skill embedded
in the binary; SkillCard::try_from(&skill) reads the files from the
directory the skill was loaded from.
List keys hold a JSON array of strings, the execution hints a
decimal string, and the schema and provider-config keys a relative
path to a JSON file. An unknown a2a-* key, a path that leaves the
skill directory, a missing asset, or a value that does not parse is
a ManifestError::Parse at that key. Declared schemas must be
usable: unknown JSON Schema keywords and schemas the 2020-12
validator cannot compile are a ManifestError::Schema, never
deferred to the first validate call.
Sourcepub fn from_embedded(
dir_name: &str,
skill_md: &str,
assets: &[(&str, &str)],
) -> Result<Self, ManifestError>
pub fn from_embedded( dir_name: &str, skill_md: &str, assets: &[(&str, &str)], ) -> Result<Self, ManifestError>
Load a skill embedded in the binary and project it.
dir_name is the skill’s directory name, skill_md the text of its
SKILL.md and assets its asset files as (relative path, text)
pairs, typically all from include_str!. Embedded content is fixed at
build time, so any problem the loader reports — an unknown field, a
name that differs from dir_name — is an error here rather than a
diagnostic. Errors from loading are ManifestError::Parse at
SKILL.md; the rest are as for SkillCard::from_skill.
Sourcepub fn to_agent_skill(&self) -> AgentSkill
pub fn to_agent_skill(&self) -> AgentSkill
Project the eight A2A discovery fields onto an AgentSkill.
Schemas, execution hints, and provider config are intentionally NOT
projected — they are Turul-local planning metadata, not wire fields.
For manifest-backed skills, params_schema is derived from the
manifest’s input schema, ensuring there is exactly one schema per
skill.
Sourcepub fn render_prompt(&self, params: &Value) -> Result<String, RenderError>
pub fn render_prompt(&self, params: &Value) -> Result<String, RenderError>
Render the Markdown body against the given input parameters.
Grammar: {{ path }} with dotted access ({{ user.name }}).
Literal {{ escaped as \{{. Missing variable -> structured
RenderError::MissingVariable (no silent empty substitution).
Sourcepub fn validate_input(&self, input: &Value) -> Result<(), ValidationError>
pub fn validate_input(&self, input: &Value) -> Result<(), ValidationError>
Validate input against the manifest’s input schema. A card
without an input schema accepts any input. Error locations are
JSON pointers into the instance rooted at #, as in
validate_json.
Sourcepub fn validate_output(&self, output: &Value) -> Result<(), ValidationError>
pub fn validate_output(&self, output: &Value) -> Result<(), ValidationError>
Validate output against the manifest’s output schema. A card
without an output schema accepts any output. Error locations are
JSON pointers into the instance rooted at #, as in
validate_json.
Trait Implementations§
Source§impl TryFrom<&Skill> for SkillCard
Reads asset files from the directory the skill was loaded from. The
resolved file must lie inside that directory, so a symlink pointing out
of it is refused. A file that is absent, refused or unreadable fails as
not found; so does every asset of a skill with no location (one that was
built, or loaded from text).
impl TryFrom<&Skill> for SkillCard
Reads asset files from the directory the skill was loaded from. The resolved file must lie inside that directory, so a symlink pointing out of it is refused. A file that is absent, refused or unreadable fails as not found; so does every asset of a skill with no location (one that was built, or loaded from text).