1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
//! Skill(技能)trait 定义
//!
//! # 概述
//!
//! [`Skill`] trait 定义了技能的标准接口。
//! 技能是对 Tool/Provider/Memory 的组合封装,提供更高层次的抽象。
//!
//! # 设计要求
//!
//! - **自描述**: 提供名称、描述和输入 schema
//! - **统一输入输出**: 使用 JSON Value 作为输入输出类型
//! - **异步执行**: 支持 IO 密集型操作
//! - **线程安全**: 实现 `Send + Sync`
//!
//! # 示例
//!
//! ## 简单技能
//!
//! ```rust
//! use rucora_core::skill::{Skill, SkillContext, SkillOutput};
//! use rucora_core::error::SkillError;
//! use async_trait::async_trait;
//! use serde_json::{Value, json};
//!
//! struct EchoSkill;
//!
//! #[async_trait]
//! impl Skill for EchoSkill {
//! fn name(&self) -> &str {
//! "echo"
//! }
//!
//! fn description(&self) -> Option<&str> {
//! Some("回显输入内容")
//! }
//!
//! fn input_schema(&self) -> Value {
//! json!({
//! "type": "object",
//! "properties": {
//! "text": {"type": "string", "description": "要回显的文本"}
//! },
//! "required": ["text"]
//! })
//! }
//!
//! async fn run_value(&self, input: Value) -> Result<Value, SkillError> {
//! Ok(input)
//! }
//! }
//! ```
//!
//! ## 复杂技能(组合多个 Tool)
//!
//! ```rust,no_run
//! use rucora_core::skill::Skill;
//! use rucora_core::error::SkillError;
//! use async_trait::async_trait;
//! use serde_json::{Value, json};
//!
//! struct WeatherSummarySkill {
//! // http_tool: Arc<HttpRequestTool>,
//! // llm_provider: Arc<dyn LlmProvider>,
//! };
//!
//! #[async_trait]
//! impl Skill for WeatherSummarySkill {
//! fn name(&self) -> &str {
//! "weather_summary"
//! }
//!
//! fn description(&self) -> Option<&str> {
//! Some("查询天气并生成摘要")
//! }
//!
//! fn input_schema(&self) -> Value {
//! json!({
//! "type": "object",
//! "properties": {
//! "location": {"type": "string", "description": "城市名称"},
//! "days": {"type": "integer", "description": "预报天数", "default": 1}
//! },
//! "required": ["location"]
//! })
//! }
//!
//! async fn run_value(&self, input: Value) -> Result<Value, SkillError> {
//! // 1. 调用 HTTP 工具获取天气数据
//! // 2. 调用 LLM 生成摘要
//! // 3. 返回结果
//! unimplemented!()
//! }
//! }
//! ```
use async_trait;
use Value;
use crate::;
/// Skill(技能)trait
///
/// 定义技能的标准接口。
///
/// # 说明
///
/// - core 层只定义抽象接口(Skill 是什么)
/// - 具体 skill 的实现与注册/编排应放在上层 crate(例如 rucora / runtime)
///
/// # 设计要求
///
/// - **自描述**: 提供名称、描述和输入 schema
/// - **统一输入输出**: 使用 JSON Value 作为输入输出类型
/// - **异步执行**: 支持 IO 密集型操作
/// - **线程安全**: 实现 `Send + Sync`
///
/// # 字段说明
///
/// - `name()`: 技能名称(必须唯一)
/// - `description()`: 技能描述(帮助理解用途)
/// - `categories()`: 技能分类(支持多标签)
/// - `input_schema()`: 输入参数的 JSON Schema
/// - `run_value()`: 执行技能的异步方法
///
/// # 示例
///
/// ```rust,no_run
/// use rucora_core::skill::Skill;
/// use rucora_core::error::SkillError;
/// use async_trait::async_trait;
/// use serde_json::{Value, json};
///
/// struct MySkill;
///
/// #[async_trait]
/// impl Skill for MySkill {
/// fn name(&self) -> &str {
/// "my_skill"
/// }
///
/// fn description(&self) -> Option<&str> {
/// Some("我的自定义技能")
/// }
///
/// fn categories(&self) -> &'static [ToolCategory] {
/// &[ToolCategory::Basic]
/// }
///
/// fn input_schema(&self) -> Value {
/// json!({"type": "object"})
/// }
///
/// async fn run_value(&self, input: Value) -> Result<Value, SkillError> {
/// // 实现技能逻辑
/// Ok(json!({"result": "success"}))
/// }
/// }
/// ```