feat: Install built-in agents
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# Coder
|
||||
|
||||
An AI agent that assists you with your coding tasks.
|
||||
|
||||
## Features
|
||||
|
||||
- 🏗️ Intelligent project structure creation and management
|
||||
- 🖼️ Convert screenshots into clean, functional code
|
||||
- 📁 Comprehensive file system operations (create folders, files, read/write files)
|
||||
- 🧐 Advanced code analysis and improvement suggestions
|
||||
- 📊 Precise diff-based file editing for controlled code modifications
|
||||
|
||||
## Similar Projects
|
||||
|
||||
- https://github.com/Doriandarko/claude-engineer
|
||||
- https://github.com/paul-gauthier/aider
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Coder
|
||||
description: An AI agent that assists you with your coding tasks
|
||||
version: 0.1.0
|
||||
global_tools:
|
||||
- fs_mkdir.sh
|
||||
- fs_ls.sh
|
||||
- fs_patch.sh
|
||||
- fs_cat.sh
|
||||
instructions: |
|
||||
You are an exceptional software developer with vast knowledge across multiple programming languages, frameworks, and best practices.
|
||||
Your capabilities include:
|
||||
|
||||
1. Creating and managing project structures
|
||||
2. Writing, debugging, and improving code across multiple languages
|
||||
3. Providing architectural insights and applying design patterns
|
||||
4. Staying current with the latest technologies and best practices
|
||||
5. Analyzing and manipulating files within the project directory
|
||||
|
||||
Available tools and their optimal use cases:
|
||||
|
||||
1. fs_mkdir: Create new directories in the project structure.
|
||||
2. fs_create: Generate new files with specified contents.
|
||||
3. fs_patch: Examine and modify existing files.
|
||||
4. fs_cat: View the contents of existing files without making changes.
|
||||
5. fs_ls: Understand the current project structure or locate specific files.
|
||||
|
||||
Tool Usage Guidelines:
|
||||
- Always use the most appropriate tool for the task at hand.
|
||||
- For file modifications, use fs_patch. Read the file first, then apply changes if needed.
|
||||
- After making changes, always review the diff output to ensure accuracy.
|
||||
|
||||
Project Creation and Management:
|
||||
1. Start by creating a root folder for new projects.
|
||||
2. Create necessary subdirectories and files within the root folder.
|
||||
3. Organize the project structure logically, following best practices for the specific project type.
|
||||
|
||||
Code Editing Best Practices:
|
||||
1. Always read the file content before making changes.
|
||||
2. Analyze the code and determine necessary modifications.
|
||||
3. Pay close attention to existing code structure to avoid unintended alterations.
|
||||
4. Review changes thoroughly after each modification.
|
||||
|
||||
Always strive for accuracy, clarity, and efficiency in your responses and actions.
|
||||
|
||||
Answer the user's request using relevant tools (if they are available). Before calling a tool, do some analysis within <thinking></thinking> tags. First, think about which of the provided tools is the relevant tool to answer the user's request. Second, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool call. BUT, if one of the values for a required parameter is missing, DO NOT invoke the function (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters. DO NOT ask for more information on optional parameters if it is not provided.
|
||||
|
||||
Do not reflect on the quality of the returned search results in your response.
|
||||
|
||||
conversation_starters:
|
||||
- 'Create a new Python project structure for a web application'
|
||||
- 'Explain the code in file.py and suggest improvements'
|
||||
- 'Search for the latest best practices in React development'
|
||||
- 'Help me debug this error: [paste your error message]'
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||
|
||||
# @cmd Create a new file at the specified path with contents.
|
||||
# @option --path! The path where the file should be created
|
||||
# @option --contents! The contents of the file
|
||||
# shellcheck disable=SC2154
|
||||
fs_create() {
|
||||
guard_path "$argc_path" "Create '$argc_path'?"
|
||||
mkdir -p "$(dirname "$argc_path")"
|
||||
printf "%s" "$argc_contents" > "$argc_path"
|
||||
echo "File created: $argc_path" >> "$LLM_OUTPUT"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Demo
|
||||
|
||||
This agent serves as a demo to guide agent development and showcase various agent capabilities.
|
||||
|
||||
To enable tools, Loki will look for the first `tools.py` or `tools.sh` file it finds in this directory.
|
||||
|
||||
The base configuration using `tools.py`. To switch to using `tools.sh`, rename or remove `tools.py`.
|
||||
@@ -0,0 +1,36 @@
|
||||
name: Demo
|
||||
description: An AI agent that demonstrates agent capabilities
|
||||
version: 0.1.0
|
||||
global_tools:
|
||||
- execute_command.sh
|
||||
instructions: |
|
||||
You are a AI agent designed to demonstrate agent capabilities.
|
||||
|
||||
<tools>
|
||||
{{__tools__}}
|
||||
</tools>
|
||||
|
||||
<system>
|
||||
os: {{__os__}}
|
||||
os_family: {{__os_family__}}
|
||||
arch: {{__arch__}}
|
||||
shell: {{__shell__}}
|
||||
locale: {{__locale__}}
|
||||
now: {{__now__}}
|
||||
cwd: {{__cwd__}}
|
||||
</system>
|
||||
|
||||
<user>
|
||||
username: {{username}}
|
||||
</user>
|
||||
variables:
|
||||
- name: username
|
||||
description: Your user name
|
||||
conversation_starters:
|
||||
- What is my username?
|
||||
- What is my current shell?
|
||||
- What is my ip?
|
||||
- How much disk space is left on my PC??
|
||||
- How to create an agent?
|
||||
documents:
|
||||
- README.md
|
||||
@@ -0,0 +1,9 @@
|
||||
import urllib.request
|
||||
|
||||
def get_ipinfo():
|
||||
"""
|
||||
Get the ip info
|
||||
"""
|
||||
with urllib.request.urlopen("https://httpbin.org/ip") as response:
|
||||
data = response.read()
|
||||
return data.decode('utf-8')
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||
|
||||
# @cmd Get the ip info
|
||||
get_ipinfo() {
|
||||
curl -fsSL https://httpbin.org/ip >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# Jira AI Agent
|
||||
|
||||
## Overview
|
||||
|
||||
The Jira AI Agent is designed to assist with managing tasks within Jira projects, providing capabilities such as creating, searching, updating, assigning, linking, and commenting on issues. Its primary purpose is to help software engineers seamlessly integrate Jira into their workflows through an AI-driven interface.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Variables
|
||||
|
||||
This agent accepts the following variables:
|
||||
|
||||
- **config**: Specifies the configuration file for the Jira CLI. This configuration should be located at `~/.config/.jira/<config_name>.yml`. Example: `work`.
|
||||
- **project**: The Jira project key where operations are executed. Example: `PAN`.
|
||||
|
||||
### Customization
|
||||
|
||||
#### For a User's Specific Jira Instance
|
||||
|
||||
1. **Config File Setup**:
|
||||
- Users must ensure there is a configuration file for their Jira instance located at `~/.config/.jira/`. The filename should match the `config` variable value provided to the agent (e.g., for `config` set to `work`, ensure a `work.yml` exists).
|
||||
|
||||
2. **State, Issue Type, and Priority Customization**:
|
||||
- Modify the functions `_issue_type_choice` and `_issue_state_choice` in `tools.sh` to reflect the specific issue types and states used in your Jira instance.
|
||||
- The `priority` for new issues can be modified directly through the `create_issue()` function in `tools.sh` with options set to the values available in your Jira instance (e.g., Medium, Highest, etc.).
|
||||
|
||||
## How the Agent Works
|
||||
|
||||
The agent works by utilizing provided variables to interact with Jira CLI commands through `tools.sh`. The `config` variable links directly to a `.yml` configuration file that contains connections settings for a Jira instance, enabling the agent to perform operations such as issue creation or status updates.
|
||||
|
||||
- **Configuration Linkage**: The `config` parameters specified during the execution must have a corresponding `.yml` configuration file at `~/.config/.jira/`, which contains the required Jira server details like login credentials and server URL.
|
||||
- **Jira Command Execution**: The agent uses predefined functions within `tools.sh` to execute Jira operations. These functions rely on the configuration and project variable inputs to construct and execute the appropriate Jira CLI commands.
|
||||
@@ -0,0 +1,22 @@
|
||||
name: Jira Agent
|
||||
description: An AI agent that can assist with Jira tasks such as creating issues, searching for issues, and updating issues.
|
||||
version: 0.1.0
|
||||
instructions: |
|
||||
You are a AI agent designed to assist with managing Jira tasks and helping software engineers
|
||||
utilize and integrate Jira into their workflows. You can create, search, update, assign, link, and comment on issues in Jira.
|
||||
|
||||
When you create issues, the general format of the issues is broken into two sections: Description, and User Acceptance Criteria. The Description section gives context and details about the issue, and the User Acceptance Criteria section provides bullet points that function like a checklist of all the things that must be completed in order for the issue to be considered done.
|
||||
|
||||
|
||||
Available tools:
|
||||
{{__tools__}}
|
||||
variables:
|
||||
- name: config
|
||||
description: The configuration to use for the Jira CLI; e.g. work
|
||||
- name: project
|
||||
description: The Jira project to operate on; e.g. PAN
|
||||
conversation_starters:
|
||||
- What are the latest issues in my Jira project?
|
||||
- Can you create a new Jira issue for me?
|
||||
- What are my open Jira issues?
|
||||
- Can you search for issues with the label "bug" in my Jira project?
|
||||
Executable
+259
@@ -0,0 +1,259 @@
|
||||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC2154
|
||||
# shellcheck disable=SC2046
|
||||
set -e
|
||||
|
||||
# @meta require-tools jira
|
||||
# @env LLM_OUTPUT=/dev/stdout The output path
|
||||
# @env LLM_AGENT_VAR_CONFIG! The configuration to use for the Jira CLI; e.g. work
|
||||
# @env LLM_AGENT_VAR_PROJECT! The Jira project to operate on; e.g. PAN
|
||||
|
||||
# @cmd Fetch my Jira username
|
||||
get_jira_username() {
|
||||
declare config_file="$HOME/.config/.jira/${LLM_AGENT_VAR_CONFIG}.yml"
|
||||
|
||||
jira me -c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Query for jira issues using a Jira Query Language (JQL) query
|
||||
# @option --jql-query! The Jira Query Language query to execute
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
query_jira_issues() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
|
||||
jira issue ls \
|
||||
--project "$argc_project" \
|
||||
-q "$argc_jql_query" \
|
||||
--plain \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Assign a Jira issue to the specified user
|
||||
# @option --issue-key! The Jira issue key, e.g. ISSUE-1
|
||||
# @option --assignee! The email or display name of the user to assign the issue to
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
assign_jira_issue() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
|
||||
jira issue assign \
|
||||
--project "$argc_project" \
|
||||
"$argc_issue_key" "$argc_assignee" \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd View a Jira issue
|
||||
# @option --issue-key! The Jira issue key, e.g. ISSUE-1
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
view_issue() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
|
||||
jira issue view \
|
||||
"$argc_issue_key" \
|
||||
--project "$argc_project" \
|
||||
--comments 20 \
|
||||
--plain \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Transition a Jira issue to a different state
|
||||
# @option --issue-key! The Jira issue key, e.g. ISSUE-1
|
||||
# @option --state![`_issue_state_choice`] The Jira state of the issue
|
||||
# @option --comment Add a comment to the issue
|
||||
# @option --resolution Set resolution
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
transition_issue() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
declare -a flags=()
|
||||
|
||||
if [[ -n $argc_comment ]]; then
|
||||
flags+=("--comment '${argc_comment}'")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_resolution ]]; then
|
||||
flags+=("--resolution ${argc_resolution}")
|
||||
fi
|
||||
|
||||
jira issue move \
|
||||
--project "$argc_project" \
|
||||
"$argc_issue_key" "$argc_state" "$(echo "${flags[*]}" | xargs)" \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Create a new Jira issue
|
||||
# @option --type![`_issue_type_choice`]
|
||||
# @option --summary! Issue summary or title
|
||||
# @option --description! Issue description
|
||||
# @option --parent-issue-key Parent issue key can be used to attach epic to an issue. And, this field is mandatory when creating a sub-task
|
||||
# @option --assignee Issue assignee (username, email or display name)
|
||||
# @option --fix-version* String array of Release info (fixVersions); for example: `--fix-version 'some fix version 1' --fix-version 'version 2'`
|
||||
# @option --affects-version* String array of Release info (affectsVersions); for example: `--affects-version 'the first affected version' --affects-version 'v1.2.3'`
|
||||
# @option --label* String array of issue labels; for example: `--label backend --label custom`
|
||||
# @option --component* String array of issue components; for example: `--component backend --component core`
|
||||
# @option --original-estimate The original estimate of the issue
|
||||
# @option --priority[=Medium|Highest|High|Low|Lowest] The priority of the issue
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
create_issue() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
declare -a flags=()
|
||||
|
||||
if [[ -n $argc_assignee ]]; then
|
||||
flags+=("--assignee $argc_assignee")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_original_estimate ]]; then
|
||||
flags+=("--original-estimate $argc_original_estimate")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_priority ]]; then
|
||||
flags+=("--priority $argc_priority")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_fix_version ]]; then
|
||||
for version in "${argc_fix_version[@]}"; do
|
||||
flags+=("--fix-version '$version'")
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ -n $argc_affects_version ]]; then
|
||||
for version in "${argc_affects_version[@]}"; do
|
||||
flags+=("--affects-version '$version'")
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ -n $argc_components ]]; then
|
||||
for component in "${argc_components[@]}"; do
|
||||
flags+=("--affects-version '$component'")
|
||||
done
|
||||
fi
|
||||
|
||||
jira issue create \
|
||||
--project "$argc_project" \
|
||||
--type "$argc_type" \
|
||||
--summary "$argc_summary" \
|
||||
--body "$argc_description" \
|
||||
--parent "$argc_parent_issue_key" \
|
||||
-c "$config_file" \
|
||||
--no-input $(echo "${flags[*]}" | xargs) >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Link two issues together
|
||||
# @option --inward-issue-key! Issue key of the source issue, eg: ISSUE-1
|
||||
# @option --outward-issue-key! Issue key of the target issue, eg: ISSUE-2
|
||||
# @option --issue-link-type! Relationship between two issues, eg: Duplicates, Blocks etc.
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
link_issues() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
|
||||
jira issue link \
|
||||
--project "$argc_project" \
|
||||
"${argc_inward_issue_key}" "${argc_outward_issue_key}" "${argc_issue_link_type}" \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Unlink or disconnect two issues from each other, if already connected.
|
||||
# @option --inward-issue-key! Issue key of the source issue, eg: ISSUE-1
|
||||
# @option --outward-issue-key! Issue key of the target issue, eg: ISSUE-2.
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
unlink_issues() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
|
||||
jira issue unlink \
|
||||
--project "$argc_project" \
|
||||
"${argc_inward_issue_key}" "${argc_outward_issue_key}" \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Add a comment to an issue
|
||||
# @option --issue-key! Issue key of the source issue, eg: ISSUE-1
|
||||
# @option --comment-body! Body of the comment you want to add
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
add_comment_to_issue() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
|
||||
jira issue comment add \
|
||||
--project "$argc_project" \
|
||||
"${argc_issue_key}" "${argc_comment_body}" \
|
||||
--no-input \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
# @cmd Edit an existing Jira issue
|
||||
# @option --issue-key! The Jira issue key, e.g. ISSUE-1
|
||||
# @option --parent Link to a parent key
|
||||
# @option --summary Edit summary or title
|
||||
# @option --description Edit description
|
||||
# @option --priority Edit priority
|
||||
# @option --assignee Edit assignee (email or display name)
|
||||
# @option --label Append labels
|
||||
# @option --project! $LLM_AGENT_VAR_PROJECT <PROJECT> Jira project to operate on; e.g. PAN
|
||||
edit_issue() {
|
||||
declare config_file="$HOME"/.config/.jira/"${LLM_AGENT_VAR_CONFIG}".yml
|
||||
declare -a flags=()
|
||||
|
||||
if [[ -n $argc_parent ]]; then
|
||||
flags+=("--parent $argc_parent")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_summary ]]; then
|
||||
flags+=("--summary $argc_summary")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_description ]]; then
|
||||
flags+=("--body $argc_description")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_priority ]]; then
|
||||
flags+=("--priority $argc_priority")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_assignee ]]; then
|
||||
flags+=("--assignee $argc_assignee")
|
||||
fi
|
||||
|
||||
if [[ -n $argc_label ]]; then
|
||||
flags+=("--label $argc_label")
|
||||
fi
|
||||
|
||||
jira issue edit \
|
||||
--project "$argc_project" \
|
||||
"$argc_issue_key" $(echo "${flags[*]}" | xargs) \
|
||||
--no-input \
|
||||
-c "$config_file" >> "$LLM_OUTPUT"
|
||||
}
|
||||
|
||||
_issue_type_choice() {
|
||||
if [[ $LLM_AGENT_VAR_CONFIG == "work" ]]; then
|
||||
echo "Story"
|
||||
echo "Task"
|
||||
echo "Bug"
|
||||
echo "Technical Debt"
|
||||
echo "Sub-task"
|
||||
elif [[ $LLM_AGENT_VAR_CONFIG == "sideproject" ]]; then
|
||||
echo "Task"
|
||||
echo "Story"
|
||||
echo "Bug"
|
||||
echo "Epic"
|
||||
fi
|
||||
}
|
||||
|
||||
_issue_state_choice() {
|
||||
if [[ $LLM_AGENT_VAR_CONFIG == "work" ]]; then
|
||||
echo "Ready for Dev"
|
||||
echo "CODE REVIEW"
|
||||
echo "IN PROGRESS"
|
||||
echo "Backlog"
|
||||
echo "Done"
|
||||
echo "TESTING"
|
||||
elif [[ $LLM_AGENT_VAR_CONFIG == "sideproject" ]]; then
|
||||
echo "IN CLARIFICATION"
|
||||
echo "NEED TO CLARIFY"
|
||||
echo "READY TO WORK"
|
||||
echo "RELEASE BACKLOG"
|
||||
echo "REOPEN"
|
||||
echo "CODE REVIEW"
|
||||
echo "IN PROGRESS"
|
||||
echo "IN TESTING"
|
||||
echo "TO TEST"
|
||||
echo "DONE"
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
use_mcp_servers: lucem-slack
|
||||
temperature: 0.2
|
||||
---
|
||||
You are an expert Slack assistant designed to assist with lucemhealth Slack workspaces via the lucem-slack MCP server.
|
||||
You can perform various tasks related to Slack, such as sending messages to channels, searching for messages, and
|
||||
providing information about users. You can also interact with other tools to enhance your capabilities.
|
||||
|
||||
When sending messages to Slack channels, ensure that the messages are clear, concise, and relevant to the channel's
|
||||
purpose. Use appropriate formatting and emojis to enhance the message's readability and engagement.
|
||||
|
||||
If ever a user references communicating with a specific person, you should always try to find that person's Slack
|
||||
username and use that to send the message. If you cannot find that person's Slack username, you should ask the user to
|
||||
provide it.
|
||||
+50
-16
@@ -8,13 +8,17 @@ use crate::{
|
||||
use anyhow::{Context, Result};
|
||||
use inquire::{validator::Validation, Text};
|
||||
use std::{fs::read_to_string, path::Path};
|
||||
|
||||
use rust_embed::Embed;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const DEFAULT_AGENT_NAME: &str = "rag";
|
||||
|
||||
pub type AgentVariables = IndexMap<String, String>;
|
||||
|
||||
#[derive(Embed)]
|
||||
#[folder = "assets/agents/"]
|
||||
struct AgentAssets;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Agent {
|
||||
name: String,
|
||||
@@ -29,6 +33,35 @@ pub struct Agent {
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
pub fn install_builtin_agents() -> Result<()> {
|
||||
info!("Installing built-in agents in {}", Config::agents_data_dir().display());
|
||||
|
||||
for file in AgentAssets::iter() {
|
||||
debug!("Processing agent file: {}", file.as_ref());
|
||||
|
||||
let embedded_file = AgentAssets::get(&file).ok_or_else(|| {
|
||||
anyhow!(
|
||||
"Failed to load embedded agent file: {}",
|
||||
file.as_ref()
|
||||
)
|
||||
})?;
|
||||
let content = unsafe { std::str::from_utf8_unchecked(&embedded_file.data) };
|
||||
let file_path = Config::agents_data_dir().join(file.as_ref());
|
||||
|
||||
if file_path.exists() {
|
||||
debug!("Agent file already exists, skipping: {}", file_path.display());
|
||||
continue;
|
||||
}
|
||||
|
||||
ensure_parent_exists(&file_path)?;
|
||||
info!("Creating agent file: {}", file_path.display());
|
||||
let mut agent_file = File::create(&file_path)?;
|
||||
agent_file.write_all(content.as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn init(
|
||||
config: &GlobalConfig,
|
||||
name: &str,
|
||||
@@ -530,22 +563,23 @@ pub struct AgentVariable {
|
||||
}
|
||||
|
||||
pub fn list_agents() -> Vec<String> {
|
||||
let agents_file = Config::config_dir().join("agents.txt");
|
||||
let contents = match read_to_string(agents_file) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return vec![],
|
||||
};
|
||||
contents
|
||||
.split('\n')
|
||||
.filter_map(|line| {
|
||||
let line = line.trim();
|
||||
if line.is_empty() || line.starts_with('#') {
|
||||
None
|
||||
} else {
|
||||
Some(line.to_string())
|
||||
let agents_data_dir = Config::agents_data_dir();
|
||||
if !agents_data_dir.exists() {
|
||||
return vec![];
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
|
||||
let mut agents = Vec::new();
|
||||
if let Ok(entries) = read_dir(agents_data_dir) {
|
||||
for entry in entries.flatten() {
|
||||
if entry.path().is_dir() {
|
||||
if let Some(name) = entry.file_name().to_str() {
|
||||
agents.push(name.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
agents
|
||||
}
|
||||
|
||||
pub fn complete_agent_variables(agent_name: &str) -> Vec<(String, Option<String>)> {
|
||||
|
||||
@@ -300,6 +300,8 @@ impl Config {
|
||||
Self::load_from_file(&config_path)?
|
||||
};
|
||||
|
||||
Agent::install_builtin_agents()?;
|
||||
|
||||
config.working_mode = working_mode;
|
||||
config.info_flag = info_flag;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user