-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Prototype AI Searcher #7146
Conversation
# Conflicts: # app/gui/src/controller/searcher.rs # app/gui/view/src/project.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the FRP API of Project View is a bit confusing ATM.
app/gui/src/controller/graph.rs
Outdated
#[allow(missing_docs)] | ||
#[derive(Clone, Copy, Debug, Fail)] | ||
#[fail(display = "AST node is missing ID.")] | ||
pub struct UnsupportedPattern; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message is copy-pasted
app/gui/src/controller/graph.rs
Outdated
/// Description of the nodes variable name. | ||
#[derive(Clone, Debug)] | ||
pub enum VariableName { | ||
/// The node has a variable name. | ||
Some(String), | ||
/// The node has no variable name. | ||
None, | ||
/// The node has a variable name, that is not currently supported. For example, it is a | ||
/// pattern subpart. See notes on [Node::variable_name]. | ||
NotSupported, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it needed? It looks like was meant to be used as variable_name
return type, but then replaced with Result<Option<&str>, UnsupportedPattern>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, this is no longer used. Removed.
app/gui/src/controller/searcher.rs
Outdated
|
||
use crate::controller::ide::plain::ProjectOperationsNotSupported; | ||
use crate::executor::test_utils::TestWithLocalPoolExecutor; | ||
use crate::test::mock::data::project_qualified_name; | ||
use crate::test::mock::data::MAIN_FINISH; | ||
use crate::test::mock::data::MODULE_NAME; | ||
use std::assert_matches::assert_matches; | ||
|
||
use crate::controller::graph::RequiredImport; | ||
use engine_protocol::language_server::types::test::value_update_with_type; | ||
use engine_protocol::language_server::SuggestionId; | ||
use enso_suggestion_database::entry::Argument; | ||
use enso_suggestion_database::mock_suggestion_database; | ||
use enso_suggestion_database::SuggestionDatabase; | ||
use json_rpc::expect_call; | ||
use parser::Parser; | ||
use std::assert_matches::assert_matches; | ||
|
||
use crate::controller::graph::RequiredImport; | ||
use crate::controller::ide::plain::ProjectOperationsNotSupported; | ||
use crate::executor::test_utils::TestWithLocalPoolExecutor; | ||
use crate::searcher::apply_this_argument; | ||
use crate::test::mock::data::project_qualified_name; | ||
use crate::test::mock::data::MAIN_FINISH; | ||
use crate::test::mock::data::MODULE_NAME; | ||
|
||
use super::*; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These imports look reversed.
app/gui/src/presenter/project.rs
Outdated
self.ide_controller.clone_ref(), | ||
self.controller.clone_ref(), | ||
self.graph_controller.clone_ref(), | ||
&self.graph, | ||
self.view.clone_ref(), | ||
self.view.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we clone view instead of clone-refing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spurious change. Reverted.
app/gui/src/presenter/searcher.rs
Outdated
// fn view(app: &Application) -> Option<Instance> | ||
// where Self: Sized { | ||
// Some(component_browser::View::new(app).display_object().clone_ref()) | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented code.
@@ -3022,7 +3022,6 @@ fn init_remaining_graph_editor_frp( | |||
); | |||
out.node_added <+ new_node; | |||
node_to_edit_after_adding <- new_node.filter_map(|&(id,_,do_edit)| do_edit.as_some(id)); | |||
eval node_to_edit_after_adding((id) model.with_node(*id, |node| node.show_preview())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the AI Searcher does not want to show a preview. So, this has been moved to the init_input_node
where we enable this conditionally based on the searcher.
// TODO[MM]: this should not contain the group entry id as that is component browser | ||
// specific. It should be refactored to be an implementation detail of the component | ||
// browser. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, in the new design we plan so far to have just a single view component for both searching entries and asking AI, so there will be only one view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment refers more to the fact that each new searcher (i.e., Component Browser Searcher and the planned combined AI searcher) might have its own separate view with different APIs. Each, which will need to be handled in a generic way on the project level, and interactions between the View and Presenter should be an internal implementation detail.
app/gui/view/src/project.rs
Outdated
@@ -472,7 +504,7 @@ impl View { | |||
eval position ((pos) model.searcher.set_xy(*pos)); | |||
|
|||
// Showing searcher. | |||
searcher.show <+ frp.searcher.is_some().on_true().constant(()); | |||
searcher.show <+ frp.searcher.unwrap().map(|params| matches!(params.searcher_type, SearcherType::ComponentBrowser)).on_true(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Over 100 characters.
app/gui/view/src/project.rs
Outdated
|
||
|
||
// === Handling Inputs to the AI Searcher and Committing Edit === | ||
|
||
ai_searcher_active <- frp.searcher_type.map(|t| *t == SearcherType::AiCompletion); | ||
committed_in_ai_searcher <- frp.accept_searcher_input.gate(&ai_searcher_active); | ||
committed_in_ai_searcher <- committed_in_ai_searcher.map2(&last_searcher, |_, &s| (s.input, None)); | ||
frp.source.editing_committed <+ committed_in_ai_searcher; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's strange thataccept_searcher_input
FRP input seemingly is used only to accept AI input. The more strange is, that we accept AI input with Tab.
Is the accept_searcher_input
relevant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, it does work without this code. The fact that it uses tab
was an oversight, but otherwise this was meant to compensate for the fact that there is no view associated with the AI searcher. But it appears that the Component Browser searcher is receiving the enter event anyway and starting the chain of events that is committing the current open searchers content.
build-config.yaml
Outdated
@@ -1,6 +1,6 @@ | |||
# Options intended to be common for all developers. | |||
|
|||
wasm-size-limit: 15.97 MiB | |||
wasm-size-limit: 16.05 MiB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit odd. Why such a big change from 600-lines of PR?
I don't know, however, what could we do with it. Certainly, it's not like we add a big dependency or make an extensive usage of macros.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. My initial guess would be that some code optimizations are no longer being applied because the searcher is no longer a fixed struct within the project, but a trait. Do we have a good way to debug Wasm size changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to have a look with twiggy
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _searcher suffix in module's name is redundant. Similarly, in ai_searcher
.
app/gui/view/src/project.rs
Outdated
/// Accept the current input of the searcher. | ||
accept_searcher_input(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still have this input, just not assigned to any shortcut.
And my original comment was mostly about name, as the name did not say about accepting AI searcher only. But if the shortcut from the original searcher works, we can go with it (just remove this input then).
app/gui/src/controller/graph.rs
Outdated
@@ -127,6 +132,22 @@ impl Node { | |||
pub fn has_position(&self) -> bool { | |||
self.metadata.as_ref().map_or(false, |m| m.position.is_some()) | |||
} | |||
|
|||
/// Get the nodes variable name, if it has one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Get the nodes variable name, if it has one. | |
/// Get the node's variable name, if it has one. |
app/gui/src/presenter/searcher.rs
Outdated
let target_node = mode.as_ref().map(|mode| mode.node_id()); | ||
if let Ok(target_node) = target_node { | ||
graph.allow_expression_auto_updates(target_node, false); | ||
let mode = mode?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will always succeed. mode
does not need to be a Result
.
app/gui/src/presenter/searcher.rs
Outdated
if let Some(target_node_view) = graph_presenter.view_id_of_ast_node(target_node) { | ||
// We only want to show the preview of the node if it is a component browser searcher. | ||
if matches!(parameters.searcher_type, SearcherType::ComponentBrowser) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this would be clearer with this if
around the whole if let
.
app/gui/src/presenter/searcher.rs
Outdated
/// Create a new AST that combines a `this` argument with the given AS. For example, to add a | ||
/// method call `sort` a this argument `table`. That would result in an AST that represents |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typos in first two sentences here.
/// Create a new AST that combines a `this` argument with the given AS. For example, to add a | ||
/// method call `sort` a this argument `table`. That would result in an AST that represents | ||
/// `table.sort`. | ||
pub fn apply_this_argument(this_var: &str, ast: &Ast) -> Ast { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see that this is searcher-specific; should it go in the ast
module?
app/gui/src/presenter/searcher.rs
Outdated
} | ||
} | ||
|
||
/// Initialise the expression in case there is a source node for the new node. This allows us to to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Initialise the expression in case there is a source node for the new node. This allows us to to | |
/// Initialise the expression in case there is a source node for the new node. This allows us to |
app/gui/src/presenter/searcher/ai.rs
Outdated
graph_controller, | ||
graph_presenter: graph_presenter.clone_ref(), | ||
this_arg, | ||
input_expression: RefCell::new("".to_string()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
input_expression: RefCell::new("".to_string()), | |
input_expression: default(), |
|
||
/// The Searcher presenter, synchronizing state between searcher view and searcher controller. | ||
/// | ||
/// The presenter should be created for one instantiated searcher controller (when node starts to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// The presenter should be created for one instantiated searcher controller (when node starts to | |
/// The presenter should be created for one instantiated searcher controller (when node starts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the user did not set OpenAI key? How the error is reported?
currently we get a pretty misleading method_not_found RPC error from the language server. Given we want to get rid of the endpoint completely we did not spend time on proper error handling. |
QA Report 1: 🔴Playing a little without API key, found two issues:
Both are blocking if we don't want to use any feature flag for disabling cmd+tab shortcut. |
Both of these points should now be addressed. @farmaazon |
# Conflicts: # app/gui/view/src/project.rs
Thanks for the thorough testing. @farmaazon It appears that the accepting AI prompts with "enter" worked fine only as long as the CB was not opened. Then its view would interfere with the event processing. This is now fixed. Newly created nodes from dragging will now also use the “default” searcher (CB searcher at the moment). |
QA report 3: 🍏No more issues found! |
Pull Request Description
Adds a new bare-bones AI searcher that can be triggered with
cmd+tab
. It will interpret the searcher input as a prompt to an AI model and replace the created node with the suggestion that was computed.Peek.2023-06-28.15-51.mp4
Implements the first step of #7099.
Important Notes
Contains some refactoring that allows us to have multiple controllers side by side. So QA testing should make sure that the Component Browser Searcher is still working as before.
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,
and
Rust
style guides. In case you are using a language not listed above, follow the Rust style guide.
./run ide build
.