291 lines
8.9 KiB
Rust
291 lines
8.9 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use serde_json::Value;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct ActionDefinition {
|
|
pub action_id: String,
|
|
pub aliases: Vec<String>,
|
|
pub description: String,
|
|
pub intent_examples: Vec<String>,
|
|
pub payload_schema: Value,
|
|
pub executable: ExecutableDefinition,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
pub struct ExecutableDefinition {
|
|
pub kind: String,
|
|
pub script: String,
|
|
}
|
|
|
|
pub fn registered_actions() -> Vec<ActionDefinition> {
|
|
vec![
|
|
action(
|
|
"append_to_file",
|
|
&["append", "append_file", "add_to_file"],
|
|
"Append content to a project-local notes file.",
|
|
&[
|
|
"append this line to notes.txt",
|
|
"add content to a file",
|
|
"append to a project note",
|
|
],
|
|
object_schema(
|
|
&[
|
|
("filename", string_schema("Relative notes/ filename.")),
|
|
("content", string_schema("Content to append.")),
|
|
],
|
|
&["filename", "content"],
|
|
),
|
|
),
|
|
action(
|
|
"calculate",
|
|
&["calc", "evaluate_expression", "math"],
|
|
"Evaluate a simple math expression.",
|
|
&[
|
|
"calculate 2 + 2 * 3",
|
|
"evaluate this expression",
|
|
"what is 10 / 2 plus 8",
|
|
],
|
|
object_schema(
|
|
&[("expression", string_schema("Math expression to evaluate."))],
|
|
&["expression"],
|
|
),
|
|
),
|
|
action(
|
|
"convert_units",
|
|
&["convert", "unit_conversion", "convert_measurement"],
|
|
"Convert a numeric distance value between supported units.",
|
|
&[
|
|
"convert 100 km to miles",
|
|
"convert meters to feet",
|
|
"unit conversion for 12 inches to cm",
|
|
],
|
|
object_schema(
|
|
&[
|
|
("value", number_schema("Numeric value to convert.")),
|
|
("from", string_schema("Source unit.")),
|
|
("to", string_schema("Target unit.")),
|
|
],
|
|
&["value", "from", "to"],
|
|
),
|
|
),
|
|
action(
|
|
"count_words",
|
|
&["word_count", "count_text_words"],
|
|
"Count whitespace-delimited words in text.",
|
|
&[
|
|
"count words in this text",
|
|
"how many words are here",
|
|
"word count this sentence",
|
|
],
|
|
object_schema(
|
|
&[("text", string_schema("Text to count words in."))],
|
|
&["text"],
|
|
),
|
|
),
|
|
action(
|
|
"delete_file",
|
|
&["delete_note", "remove_file", "remove_note"],
|
|
"Delete a project-local notes file.",
|
|
&[
|
|
"delete note.txt",
|
|
"remove this note file",
|
|
"delete a project note",
|
|
],
|
|
object_schema(
|
|
&[("filename", string_schema("Relative notes/ filename."))],
|
|
&["filename"],
|
|
),
|
|
),
|
|
action(
|
|
"generate_uuid",
|
|
&["uuid", "new_uuid", "create_uuid"],
|
|
"Generate a random UUID v4.",
|
|
&[
|
|
"generate a uuid",
|
|
"create a new uuid",
|
|
"give me a random uuid",
|
|
],
|
|
object_schema(&[], &[]),
|
|
),
|
|
action(
|
|
"hash_string",
|
|
&["hash", "digest_string", "string_hash"],
|
|
"Hash text with sha256, md5, or sha1.",
|
|
&[
|
|
"hash hello with sha256",
|
|
"md5 this string",
|
|
"sha1 digest for this text",
|
|
],
|
|
object_schema(
|
|
&[
|
|
("text", string_schema("Text to hash.")),
|
|
(
|
|
"algorithm",
|
|
enum_schema("Hash algorithm.", &["sha256", "md5", "sha1"]),
|
|
),
|
|
],
|
|
&["text", "algorithm"],
|
|
),
|
|
),
|
|
action(
|
|
"logger",
|
|
&["log", "write_log", "record_message"],
|
|
"Write a structured proof-of-concept log message.",
|
|
&[
|
|
"log hello from codex",
|
|
"record this message",
|
|
"write a logger proof of concept entry",
|
|
],
|
|
object_schema(
|
|
&[(
|
|
"message",
|
|
string_schema("Message text to write into logs/controller-actions.jsonl."),
|
|
)],
|
|
&["message"],
|
|
),
|
|
),
|
|
action(
|
|
"random_number",
|
|
&["random_int", "roll_number", "number_in_range"],
|
|
"Generate a random integer in an inclusive range.",
|
|
&[
|
|
"random number between 1 and 100",
|
|
"roll a number in this range",
|
|
"pick an integer from 5 to 10",
|
|
],
|
|
object_schema(
|
|
&[
|
|
("min", integer_schema("Inclusive minimum.")),
|
|
("max", integer_schema("Inclusive maximum.")),
|
|
],
|
|
&["min", "max"],
|
|
),
|
|
),
|
|
action(
|
|
"read_file",
|
|
&["read_note", "open_file", "show_file"],
|
|
"Read a project-local notes file.",
|
|
&[
|
|
"read note.txt",
|
|
"show the contents of this note",
|
|
"open a project note file",
|
|
],
|
|
object_schema(
|
|
&[("filename", string_schema("Relative notes/ filename."))],
|
|
&["filename"],
|
|
),
|
|
),
|
|
action(
|
|
"to_slug",
|
|
&["slugify", "make_slug", "url_slug"],
|
|
"Convert text to a URL-safe ASCII slug.",
|
|
&[
|
|
"slugify this title",
|
|
"make a url slug",
|
|
"convert text to a slug",
|
|
],
|
|
object_schema(&[("text", string_schema("Text to slugify."))], &["text"]),
|
|
),
|
|
action(
|
|
"truncate_text",
|
|
&["truncate", "shorten_text", "clip_text"],
|
|
"Truncate text to a maximum character count.",
|
|
&[
|
|
"truncate this to 100 characters",
|
|
"shorten this text",
|
|
"clip text to a max length",
|
|
],
|
|
object_schema(
|
|
&[
|
|
("text", string_schema("Text to truncate.")),
|
|
("max_chars", integer_schema("Maximum number of characters.")),
|
|
],
|
|
&["text", "max_chars"],
|
|
),
|
|
),
|
|
action(
|
|
"write_note",
|
|
&["write_file", "save_note", "create_note"],
|
|
"Create or overwrite a project-local notes file.",
|
|
&[
|
|
"write a note file",
|
|
"save this note",
|
|
"create a text file with this content",
|
|
],
|
|
object_schema(
|
|
&[
|
|
("filename", string_schema("Relative notes/ filename.")),
|
|
("content", string_schema("Content to write.")),
|
|
],
|
|
&["filename", "content"],
|
|
),
|
|
),
|
|
]
|
|
}
|
|
|
|
fn action(
|
|
action_id: &str,
|
|
aliases: &[&str],
|
|
description: &str,
|
|
intent_examples: &[&str],
|
|
payload_schema: Value,
|
|
) -> ActionDefinition {
|
|
ActionDefinition {
|
|
action_id: action_id.to_string(),
|
|
aliases: aliases.iter().map(|alias| alias.to_string()).collect(),
|
|
description: description.to_string(),
|
|
intent_examples: intent_examples
|
|
.iter()
|
|
.map(|example| example.to_string())
|
|
.collect(),
|
|
payload_schema,
|
|
executable: ExecutableDefinition {
|
|
kind: "internal-rust-script".to_string(),
|
|
script: action_id.to_string(),
|
|
},
|
|
}
|
|
}
|
|
|
|
fn object_schema(properties: &[(&str, Value)], required: &[&str]) -> Value {
|
|
let properties = properties
|
|
.iter()
|
|
.map(|(name, schema)| ((*name).to_string(), schema.clone()))
|
|
.collect::<serde_json::Map<_, _>>();
|
|
|
|
serde_json::json!({
|
|
"type": "object",
|
|
"required": required,
|
|
"properties": properties,
|
|
"additionalProperties": false
|
|
})
|
|
}
|
|
|
|
fn string_schema(description: &str) -> Value {
|
|
serde_json::json!({
|
|
"type": "string",
|
|
"description": description
|
|
})
|
|
}
|
|
|
|
fn number_schema(description: &str) -> Value {
|
|
serde_json::json!({
|
|
"type": "number",
|
|
"description": description
|
|
})
|
|
}
|
|
|
|
fn integer_schema(description: &str) -> Value {
|
|
serde_json::json!({
|
|
"type": "integer",
|
|
"description": description
|
|
})
|
|
}
|
|
|
|
fn enum_schema(description: &str, values: &[&str]) -> Value {
|
|
serde_json::json!({
|
|
"type": "string",
|
|
"description": description,
|
|
"enum": values
|
|
})
|
|
}
|