agent_workspace_contract/environment/
skills.rs1use super::*;
2
3pub const SANDBOX_SKILLS_PATH: &str = "/internal/v1/workspace/sandboxes/{sandboxId}/skills";
5
6pub const SKILLS_SEARCH_PATH: &str = "/internal/v1/workspace/skills:search";
8
9pub const SANDBOX_SKILL_INSTALL_ROOT: &str = "skills";
11
12pub const SANDBOX_SKILL_DEFAULT_VERSION: &str = "latest";
14
15pub const SANDBOX_SKILL_DEFAULT_PROVIDER: &str = "local";
17
18fn default_sandbox_skill_provider() -> String {
19 SANDBOX_SKILL_DEFAULT_PROVIDER.to_string()
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
23#[serde(deny_unknown_fields, rename_all = "camelCase")]
24pub struct InstallSandboxSkillRequest {
25 pub group: String,
26 pub name: String,
27 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub version: Option<String>,
29 #[serde(default = "default_sandbox_skill_provider")]
31 pub provider: String,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(deny_unknown_fields, rename_all = "camelCase")]
36pub struct InstallSandboxSkillResource {
37 pub sandbox_id: String,
38 pub provider: String,
39 pub group: String,
40 pub name: String,
41 pub version: String,
42 pub install_path: String,
43 pub files: Vec<String>,
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
47pub struct SkillPackageFile {
48 pub path: String,
49 pub content: Vec<u8>,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct SkillPackage {
54 pub group: String,
55 pub name: String,
56 pub version: String,
57 pub files: Vec<SkillPackageFile>,
58}
59
60#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
61#[serde(rename_all = "camelCase")]
62pub struct SkillSearchQuery {
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub q: Option<String>,
65 #[serde(default, skip_serializing_if = "Option::is_none")]
66 pub page: Option<u32>,
67 #[serde(default, skip_serializing_if = "Option::is_none")]
68 pub limit: Option<u32>,
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub struct SkillSearchItem {
74 pub group: String,
75 pub name: String,
76 pub full_name: String,
77 #[serde(default)]
78 pub description: String,
79 #[serde(default)]
80 pub latest_version: String,
81 #[serde(default, skip_serializing_if = "Option::is_none")]
82 pub skill_type: Option<String>,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(rename_all = "camelCase")]
87pub struct SkillSearchPage {
88 pub items: Vec<SkillSearchItem>,
89 #[serde(default)]
90 pub page: u32,
91 #[serde(default)]
92 pub limit: u32,
93 #[serde(default, skip_serializing_if = "Option::is_none")]
94 pub total: Option<u64>,
95 #[serde(default, skip_serializing_if = "Option::is_none")]
96 pub has_more: Option<bool>,
97}
98
99#[async_trait]
101pub trait SkillHubClient: Send + Sync + Debug {
102 async fn download_skill(
103 &self,
104 group: &str,
105 name: &str,
106 version: &str,
107 user_authorization: &str,
108 ) -> Result<SkillPackage>;
109
110 async fn search_skills(
111 &self,
112 query: &SkillSearchQuery,
113 user_authorization: &str,
114 ) -> Result<SkillSearchPage>;
115}