From c5fb75a3d92be139230af958568e04e02ff367f4 Mon Sep 17 00:00:00 2001 From: Oleg Klimov Date: Fri, 20 Dec 2024 09:23:23 +0100 Subject: [PATCH] fix all schemas, restore schema test --- src/http/routers/v1/links.rs | 24 ++++++++------- src/integrations/docker/integr_docker.rs | 13 +++++---- src/integrations/integr_chrome.rs | 20 +++++-------- src/integrations/integr_cmdline.rs | 7 +++-- src/integrations/integr_github.rs | 28 +++++++++++------- src/integrations/integr_gitlab.rs | 29 +++++++++++-------- src/integrations/integr_mysql.rs | 21 +++++++------- src/integrations/integr_pdb.rs | 13 +++++---- src/integrations/integr_postgres.rs | 15 +++++----- src/integrations/project_summary_chat.rs | 1 - src/integrations/setting_up_integrations.rs | 1 - src/integrations/yaml_schema.rs | 13 ++++++++- src/yaml_configs/customization_compiled_in.rs | 2 +- 13 files changed, 106 insertions(+), 81 deletions(-) diff --git a/src/http/routers/v1/links.rs b/src/http/routers/v1/links.rs index 99dbd82ff..35d0fe914 100644 --- a/src/http/routers/v1/links.rs +++ b/src/http/routers/v1/links.rs @@ -71,15 +71,6 @@ pub async fn handle_v1_links( let (integrations_map, integration_yaml_errors) = crate::integrations::running_integrations::load_integrations(gcx.clone(), "".to_string(), experimental).await; if post.meta.chat_mode == ChatMode::CONFIGURE { - // links.push(Link { - // link_action: LinkAction::Goto, - // link_text: "Return".to_string(), - // link_goto: Some("SETTINGS:DEFAULT".to_string()), - // link_summary_path: None, - // link_tooltip: format!(""), - // link_payload: None, - // }); - if !get_tickets_from_messages(gcx.clone(), &post.messages).await.is_empty() { links.push(Link { link_action: LinkAction::PatchAll, @@ -92,6 +83,19 @@ pub async fn handle_v1_links( } } + if post.meta.chat_mode == ChatMode::PROJECT_SUMMARY { + if !get_tickets_from_messages(gcx.clone(), &post.messages).await.is_empty() { + links.push(Link { + link_action: LinkAction::PatchAll, + link_text: "Save and return".to_string(), + link_goto: Some("NEWCHAT".to_string()), + link_summary_path: None, + link_tooltip: format!(""), + link_payload: None, + }); + } + } + // GIT uncommitted if post.meta.chat_mode == ChatMode::AGENT { let commits = get_commit_information_from_current_changes(gcx.clone()).await; @@ -110,7 +114,7 @@ pub async fn handle_v1_links( project_changes.truncate(4); project_changes.push("...".to_string()); } - uncommited_changes_warning = format!("You have uncommitted changes:\n```\n{}\n```\nāš ļø You might have a problem rolling back agent's changes.", project_changes.join("\n")); + uncommited_changes_warning = format!("You have uncommitted changes:\n```\n{}\n```\nIt's fine, but you might have a problem rolling back agent's changes.", project_changes.join("\n")); } if false { diff --git a/src/integrations/docker/integr_docker.rs b/src/integrations/docker/integr_docker.rs index 6f35ebeaf..fe77f9574 100644 --- a/src/integrations/docker/integr_docker.rs +++ b/src/integrations/docker/integr_docker.rs @@ -312,6 +312,12 @@ fields: f_desc: "Path to the SSH identity file to connect to remote Docker." f_label: "SSH Identity File" f_extra: true +available: + on_your_laptop_possible: true + when_isolated_possible: false +confirmation: + ask_user_default: [] + deny_default: ["docker* rm *", "docker* rmi *", "docker* pause *", "docker* stop *", "docker* kill *"] smartlinks: - sl_label: "Test" sl_chat: @@ -319,10 +325,5 @@ smartlinks: content: | šŸ”§ The docker tool should be visible now. To test the tool, list the running containers, briefly describe the containers and express satisfaction and relief if it works, and change nothing. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. -available: - on_your_laptop_possible: true - when_isolated_possible: false -confirmation: - ask_user_default: [] - deny_default: ["docker* rm *", "docker* rmi *", "docker* pause *", "docker* stop *", "docker* kill *"] + sl_enable_only_with_tool: true "#; diff --git a/src/integrations/integr_chrome.rs b/src/integrations/integr_chrome.rs index 45f131f4c..48ceaf3b8 100644 --- a/src/integrations/integr_chrome.rs +++ b/src/integrations/integr_chrome.rs @@ -1281,22 +1281,24 @@ fields: f_type: string_short f_desc: "Scale factor of the browser window in tablet mode." f_extra: true +available: + on_your_laptop_possible: true + when_isolated_possible: true +confirmation: + ask_user_default: [] + deny_default: [] smartlinks: - sl_label: "Test" sl_chat: - role: "user" content: | šŸ”§ The chrome tool should be visible now. To test the tool, navigate to a website like https://example.com/ take a screenshot, and express happiness if it works. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. + sl_enable_only_with_tool: true - sl_label: "Help me install Chrome for Testing" sl_chat: - role: "user" content: | - šŸ”§ Help user to install Chrome for Testing using npm, once that done rewrite the current config file %CURRENT_CONFIG% to use it. - - sl_label: "Help me connect regular Chrome via ws:// protocol" - sl_chat: - - role: "user" - content: | - šŸ”§ Help user to connect regular Chrome via ws:// protocol, rewrite the current config file %CURRENT_CONFIG% to use it. The `chrome_path` accepts the "ws://..." notation. + šŸ”§ Help the user to install Chrome for Testing using npm, once that is done rewrite the current config file %CURRENT_CONFIG% to use chrome_path to use it. docker: filter_label: "" filter_image: "standalone-chrome" @@ -1315,10 +1317,4 @@ docker: - role: "user" content: | šŸ”§ Your job is to modify chrome config in the current file to connect through websockets to the container, use docker tool to inspect the container if needed. Current config file: %CURRENT_CONFIG%. -available: - on_your_laptop_possible: true - when_isolated_possible: true -confirmation: - ask_user_default: [] - deny_default: [] "#; diff --git a/src/integrations/integr_cmdline.rs b/src/integrations/integr_cmdline.rs index dbf0b75c6..849194d89 100644 --- a/src/integrations/integr_cmdline.rs +++ b/src/integrations/integr_cmdline.rs @@ -321,13 +321,14 @@ description: | available: on_your_laptop_possible: true when_isolated_possible: true +confirmation: + ask_user_default: ["*"] + deny_default: ["sudo*"] smartlinks: - sl_label: "Auto Configure" sl_chat: - role: "user" content: | šŸ”§ Test the tool that corresponds to the current config file. If it works express happiness, and change nothing. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. -confirmation: - ask_user_default: ["*"] - deny_default: ["sudo*"] + sl_enable_only_with_tool: true "#; diff --git a/src/integrations/integr_github.rs b/src/integrations/integr_github.rs index 4dd2006b9..2e10c456b 100644 --- a/src/integrations/integr_github.rs +++ b/src/integrations/integr_github.rs @@ -179,18 +179,29 @@ fn parse_command_args(args: &HashMap) -> Result, Stri const GITHUB_INTEGRATION_SCHEMA: &str = r#" fields: + gh_token: + f_type: string_long + f_desc: "GitHub Personal Access Token, you can create one at https://github.com/settings/tokens. If you don't want to send your key to the AI model that helps you to configure the agent, put it into secrets.yaml and write $MY_SECRET_VARIABLE in this field." + f_placeholder: "ghp_xxxxxxxxxxxxxxxx" + f_label: "Token" + smartlinks: + - sl_label: "Open secrets.yaml" + sl_goto: "EDITOR:secrets.yaml" gh_binary_path: f_type: string_long - f_desc: "Path to the GitHub CLI binary. Leave empty to use the default 'gh' command." + f_desc: "Path to the GitHub CLI binary. Leave empty if you have it in PATH." f_placeholder: "/usr/local/bin/gh" f_label: "GH Binary Path" - gh_token: - f_type: string_long - f_desc: "GitHub Personal Access Token for authentication." - f_placeholder: "ghp_xxxxxxxxxxxxxxxx" + f_extra: true description: | The GitHub integration allows interaction with GitHub repositories using the GitHub CLI. It provides functionality for various GitHub operations such as creating issues, pull requests, and more. +available: + on_your_laptop_possible: true + when_isolated_possible: true +confirmation: + ask_user_default: ["gh * delete *", "gh * close *"] + deny_default: ["gh auth token *"] smartlinks: - sl_label: "Test" sl_chat: @@ -198,10 +209,5 @@ smartlinks: content: | šŸ”§ The `github` (`gh`) tool should be visible now. To test the tool, list opened pull requests for `smallcloudai/refact-lsp`, and briefly describe them and express happiness, and change nothing. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. -available: - on_your_laptop_possible: true - when_isolated_possible: true -confirmation: - ask_user_default: ["gh * delete *", "gh * close *"] - deny_default: ["gh auth token *"] + sl_enable_only_with_tool: true "#; diff --git a/src/integrations/integr_gitlab.rs b/src/integrations/integr_gitlab.rs index 0b4c720f9..5c2e0ead7 100644 --- a/src/integrations/integr_gitlab.rs +++ b/src/integrations/integr_gitlab.rs @@ -56,7 +56,7 @@ impl IntegrationTrait for ToolGitlab { fn integr_common(&self) -> IntegrationCommon { self.common.clone() } - + fn integr_upgrade_to_tool(&self, _integr_name: &str) -> Box { Box::new(ToolGitlab { common: self.common.clone(), @@ -176,18 +176,28 @@ fn parse_command_args(args: &HashMap) -> Result, Stri const GITLAB_INTEGRATION_SCHEMA: &str = r#" fields: + glab_token: + f_type: string_long + f_desc: "GitLab Personal Access Token, you can get one at https://gitlab.com/-/user_settings/personal_access_tokens. If you don't want to send your key to the AI model that helps you to configure the agent, put it into secrets.yaml and write $MY_SECRET_VARIABLE in this field." + f_placeholder: "glpat_xxxxxxxxxxxxxxxx" + smartlinks: + - sl_label: "Open secrets.yaml" + sl_goto: "EDITOR:secrets.yaml" glab_binary_path: f_type: string_long f_desc: "Path to the GitLab CLI binary. Leave empty to use the default 'glab' command." f_placeholder: "/usr/local/bin/glab" - f_label: "GLAB Binary Path" - glab_token: - f_type: string_long - f_desc: "GitLab Personal Access Token for authentication." - f_placeholder: "glpat_xxxxxxxxxxxxxxxx" + f_label: "glab binary path" + f_extra: true description: | The GitLab integration allows interaction with GitLab repositories using the GitLab CLI. It provides functionality for various GitLab operations such as creating issues, merge requests, and more. +available: + on_your_laptop_possible: true + when_isolated_possible: true +confirmation: + ask_user_default: ["glab * delete *"] + deny_default: ["glab auth token *"] smartlinks: - sl_label: "Test" sl_chat: @@ -195,10 +205,5 @@ smartlinks: content: | šŸ”§ The `gitlab` (`glab`) tool should be visible now. To test the tool, list opened merge requests for your GitLab project, and briefly describe them and express happiness, and change nothing. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. -available: - on_your_laptop_possible: true - when_isolated_possible: true -confirmation: - ask_user_default: ["glab * delete *"] - deny_default: ["glab auth token *"] + sl_enable_only_with_tool: true "#; diff --git a/src/integrations/integr_mysql.rs b/src/integrations/integr_mysql.rs index 9b87875cc..e6bd35d90 100644 --- a/src/integrations/integr_mysql.rs +++ b/src/integrations/integr_mysql.rs @@ -188,8 +188,8 @@ fields: f_type: string_short f_default: "$MYSQL_PASSWORD" smartlinks: - - sl_label: "Open passwords.yaml" - sl_goto: "EDITOR:passwords.yaml" + - sl_label: "Open secrets.yaml" + sl_goto: "EDITOR:secrets.yaml" database: f_type: string_short f_placeholder: "mysql" @@ -204,6 +204,12 @@ description: | On this page you can also see Docker containers with Mysql servers. You can ask model to create a new container with a new database for you, or ask model to configure the tool to use an existing container with existing database. +available: + on_your_laptop_possible: true + when_isolated_possible: true +confirmation: + ask_user_default: [] + deny_default: [] smartlinks: - sl_label: "Test" sl_chat: @@ -212,13 +218,14 @@ smartlinks: šŸ”§ The mysql tool should be visible now. To test the tool, list the tables available, briefly describe the tables and express happiness, and change nothing. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. The current config file is %CURRENT_CONFIG%. - - sl_label: "Look at the project, fill in automatically" + sl_enable_only_with_tool: true + - sl_label: "Look at the project, help me set it up" sl_chat: - role: "user" content: | šŸ”§ Your goal is to set up mysql client. Look at the project, especially files like "docker-compose.yaml" or ".env". Call tree() to see what files the project has. After that is completed, go through the usual plan in the system prompt. - The current config file is %CURRENT_CONFIG%. + Keep MYSQL_HOST MYSQL_PORT MYSQL_USER MYSQL_PASSWORD MYSQL_DATABASE in variables.yaml so they can be reused by command line tools later. docker: filter_label: "" filter_image: "mysql" @@ -242,10 +249,4 @@ docker: - role: "user" content: | šŸ”§ Your job is to modify mysql connection config in the current file to match the variables from the container, use docker tool to inspect the container if needed. Current config file: %CURRENT_CONFIG%. -available: - on_your_laptop_possible: true - when_isolated_possible: true -confirmation: - ask_user_default: [] - deny_default: [] "#; diff --git a/src/integrations/integr_pdb.rs b/src/integrations/integr_pdb.rs index f3fef15a8..b6b7ac577 100644 --- a/src/integrations/integr_pdb.rs +++ b/src/integrations/integr_pdb.rs @@ -377,6 +377,12 @@ fields: description: | The PDB integration allows interaction with the Python debugger for inspecting variables and exploring program execution. It provides functionality for debugging Python scripts and applications. +available: + on_your_laptop_possible: true + when_isolated_possible: true +confirmation: + ask_user_default: [] + deny_default: [] smartlinks: - sl_label: "Test" sl_chat: @@ -384,10 +390,5 @@ smartlinks: content: | šŸ”§ The pdb tool should be visible now. To test the tool, start a debugging session for a simple Python script, set a breakpoint, and inspect some variables. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. -available: - on_your_laptop_possible: true - when_isolated_possible: true -confirmation: - ask_user_default: [] - deny_default: [] + sl_enable_only_with_tool: true "#; diff --git a/src/integrations/integr_postgres.rs b/src/integrations/integr_postgres.rs index 1680a0bce..6d60af615 100644 --- a/src/integrations/integr_postgres.rs +++ b/src/integrations/integr_postgres.rs @@ -191,7 +191,7 @@ fields: sl_goto: "EDITOR:variables.yaml" database: f_type: string_short - f_placeholder: "postgres" + f_placeholder: "my_marketing_db" psql_binary_path: f_type: string_long f_desc: "If it can't find a path to `psql` you can provide it here, leave blank if not sure." @@ -203,6 +203,12 @@ description: | On this page you can also see Docker containers with Postgres servers. You can ask model to create a new container with a new database for you, or ask model to configure the tool to use an existing container with existing database. +available: + on_your_laptop_possible: true + when_isolated_possible: true +confirmation: + ask_user_default: ["psql*[!SELECT]*"] + deny_default: [] smartlinks: - sl_label: "Test" sl_chat: @@ -210,6 +216,7 @@ smartlinks: content: | šŸ”§ The postgres tool should be visible now. To test the tool, list the tables available, briefly describe the tables and express happiness, and change nothing. If it doesn't work or the tool isn't available, go through the usual plan in the system prompt. + sl_enable_only_with_tool: true - sl_label: "Look at the project, fill in automatically" sl_chat: - role: "user" @@ -240,12 +247,6 @@ docker: - role: "user" content: | šŸ”§ Your job is to modify postgres connection config in the current file to match the variables from the container, use docker tool to inspect the container if needed. Current config file: %CURRENT_CONFIG%. -available: - on_your_laptop_possible: true - when_isolated_possible: true -confirmation: - ask_user_default: ["psql*[!SELECT]*"] - deny_default: [] "#; // To think about: PGPASSWORD PGHOST PGUSER PGPORT PGDATABASE maybe tell the model to set that in variables.yaml as well diff --git a/src/integrations/project_summary_chat.rs b/src/integrations/project_summary_chat.rs index b9392712f..4fdedfdc4 100644 --- a/src/integrations/project_summary_chat.rs +++ b/src/integrations/project_summary_chat.rs @@ -15,7 +15,6 @@ pub async fn mix_project_summary_messages( ) { assert!(messages[0].role != "system"); // we are here to add this, can't already exist - // XXX should be a better way to load the prompt let custom: crate::yaml_configs::customization_loader::CustomizationYaml = match crate::yaml_configs::customization_loader::load_customization(gcx.clone(), true).await { Ok(x) => x, diff --git a/src/integrations/setting_up_integrations.rs b/src/integrations/setting_up_integrations.rs index 939993e7d..0daa88011 100644 --- a/src/integrations/setting_up_integrations.rs +++ b/src/integrations/setting_up_integrations.rs @@ -474,7 +474,6 @@ mod tests { use std::io::Write; #[tokio::test] - #[ignore] async fn test_integration_schemas() { let integrations = crate::integrations::integrations_list(true); for name in integrations { diff --git a/src/integrations/yaml_schema.rs b/src/integrations/yaml_schema.rs index 1ab72905a..315472531 100644 --- a/src/integrations/yaml_schema.rs +++ b/src/integrations/yaml_schema.rs @@ -8,7 +8,7 @@ pub struct DockerService { pub image: String, #[serde(default)] pub environment: IndexMap, - #[serde(default)] + #[serde(default, skip_serializing_if="is_empty")] pub ports: Vec, } @@ -36,6 +36,8 @@ pub struct ISmartLink { pub sl_chat: Vec, #[serde(default, skip_serializing_if="is_default")] pub sl_goto: String, + #[serde(default, skip_serializing_if="is_default")] + pub sl_enable_only_with_tool: bool, } #[derive(Serialize, Deserialize, Debug, Default)] @@ -55,12 +57,21 @@ pub struct ISchemaDocker { pub smartlinks_for_each_container: Vec, } +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct ISchemaConfirmation { + #[serde(default)] + pub ask_user_default: Vec, + #[serde(default)] + pub deny_default: Vec, +} + #[derive(Serialize, Deserialize, Debug, Default)] pub struct ISchema { pub fields: IndexMap, #[serde(default, skip_serializing_if="is_default")] pub description: String, pub available: ISchemaAvailable, + pub confirmation: ISchemaConfirmation, #[serde(default, skip_serializing_if="is_empty")] pub smartlinks: Vec, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/src/yaml_configs/customization_compiled_in.rs b/src/yaml_configs/customization_compiled_in.rs index b61fd2203..7cca1e382 100644 --- a/src/yaml_configs/customization_compiled_in.rs +++ b/src/yaml_configs/customization_compiled_in.rs @@ -162,7 +162,7 @@ PROMPT_PROJECT_SUMMARY: | Most of those integrations are easy, you can just repeat the name. But two of those are special: cmdline_TEMPLATE and service_TEMPLATE. Those can integrate a blocking command line utility (such as cmake) and a blocking background command (such as hypercorn server that runs forever until you hit Ctrl+C), respectively. - Think of typical command line things that might be required to work on the project, how do you run the webserver, how do you compile it? + Think of typical command line things that might be required to work on the project, how do you run the webserver, how do you compile the project? For webserver to work you most likely need a service_* so it runs in the background and you can open and navigate web pages at the same time. Turn those things into recommendations, replace _TEMPLATE with lowercase name with underscores, don't overthink it, "cargo build" should become "cmdline_cargo_build", etc. If there's no web server detectable, skip it.