Skip to main content

skilllite_core/
protocol.rs

1//! Standard Node I/O types for protocol handlers and P2P routing.
2//!
3//! These types are the shared "currency" across stdio_rpc, agent_chat, MCP,
4//! and the future P2P layer. They intentionally carry only what a remote peer
5//! (or routing layer) needs — not full agent internals.
6
7use serde::{Deserialize, Serialize};
8
9// ─── Input types (NodeTask, NodeContext) ─────────────────────────────────────
10
11/// Execution context attached to every [`NodeTask`].
12///
13/// Provides the agent with workspace identity, session continuity, and the
14/// capability tags the caller intends to use. Remote P2P peers use
15/// `required_capabilities` to decide whether to accept the task.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct NodeContext {
18    /// Workspace path (local execution) or originating node ID (P2P).
19    pub workspace: String,
20    /// Session key for memory/transcript continuity (matches `ChatSession` key).
21    pub session_key: String,
22    /// Capability tags the caller expects to exercise (e.g. `["python", "web"]`).
23    #[serde(default)]
24    pub required_capabilities: Vec<String>,
25}
26
27/// Standard task unit — the universal input for local execution and P2P routing.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct NodeTask {
30    /// Unique task identifier (UUIDv4 or monotonic counter string).
31    pub id: String,
32    /// Natural-language description of what the agent should accomplish.
33    pub description: String,
34    /// Execution context (workspace, session, capabilities).
35    pub context: NodeContext,
36    /// Optional hint for which skill or tool to prefer.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub tool_hint: Option<String>,
39}
40
41// ─── Output types (NodeResult, NewSkill) ─────────────────────────────────────
42
43/// An evolved skill produced during task execution.
44///
45/// Emitted in [`NodeResult::new_skill`] when the Evolution Engine synthesises
46/// or refines a skill as a side-effect of completing a task.
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct NewSkill {
49    /// Skill name — matches the `name` field in `SKILL.md`.
50    pub name: String,
51    /// Human-readable description of what the skill does.
52    pub description: String,
53    /// Local filesystem path where the skill was installed.
54    pub path: String,
55    /// Evolution transaction ID — used for rollback via `skilllite evolution reset`.
56    pub txn_id: String,
57}
58
59/// Standard result unit — the universal output for local execution and P2P routing.
60///
61/// Maps from `AgentResult` internally; fields are intentionally minimal so
62/// that routing layers and remote peers can parse results without knowing agent internals.
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct NodeResult {
65    /// Echoed task ID (matches caller's task id when available; otherwise a generated UUID).
66    pub task_id: String,
67    /// Agent's final response text.
68    pub response: String,
69    /// Whether the agent marked the task as completed.
70    pub task_completed: bool,
71    /// Total tool calls made during execution.
72    pub tool_calls: usize,
73    /// Newly synthesised skill, if the Evolution Engine produced one.
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub new_skill: Option<NewSkill>,
76}