diff options
7 files changed, 108 insertions, 24 deletions
| diff --git a/continuedev/src/continuedev/core/policy.py b/continuedev/src/continuedev/core/policy.py index 4287bb6e..e65b6c9d 100644 --- a/continuedev/src/continuedev/core/policy.py +++ b/continuedev/src/continuedev/core/policy.py @@ -17,7 +17,10 @@ class DemoPolicy(Policy):      def next(self, history: History) -> Step:          # At the very start, run initial Steps spcecified in the config          if history.get_current() is None: -            return MessageStep(message="Welcome to Continue!") >> SetupContinueWorkspaceStep() >> CreateCodebaseIndexChroma() >> StepsOnStartupStep() +            return (MessageStep(message="Welcome to Continue!") >> +                    SetupContinueWorkspaceStep() >> +                    CreateCodebaseIndexChroma() >> +                    StepsOnStartupStep())          observation = history.get_current().observation          if observation is not None and isinstance(observation, UserInputObservation): diff --git a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py index 4a4604d6..55c25da4 100644 --- a/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py +++ b/continuedev/src/continuedev/recipes/CreatePipelineRecipe/main.py @@ -11,7 +11,7 @@ class CreatePipelineRecipe(Step):      hide: bool = True      async def run(self, sdk: ContinueSDK): -        await sdk.run_step( +        text_observation = await sdk.run_step(              MessageStep(message=dedent("""\                  This recipe will walk you through the process of creating a dlt pipeline for your chosen data source. With the help of Continue, you will:                  - Create a Python virtual environment with dlt installed @@ -21,7 +21,10 @@ class CreatePipelineRecipe(Step):                  - Test that the API call works                  - Load the data into a local DuckDB instance                  - Write a query to view the data""")) >> -            WaitForUserInputStep(prompt="What API do you want to load data from?") >> -            SetupPipelineStep(api_description="WeatherAPI.com API") >> +            WaitForUserInputStep( +                prompt="What API do you want to load data from?") +        ) +        await sdk.run_step( +            SetupPipelineStep(api_description=text_observation.text) >>              ValidatePipelineStep()          ) diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py index fdcd9837..ad468595 100644 --- a/continuedev/src/continuedev/steps/core/core.py +++ b/continuedev/src/continuedev/steps/core/core.py @@ -191,13 +191,18 @@ class WaitForUserInputStep(Step):      name: str = "Waiting for user input"      _description: Union[str, None] = None +    _response: Union[str, None] = None      async def describe(self, models: Models) -> Coroutine[str, None, None]: -        return self.prompt +        if self._response is None: +            return self.prompt +        else: +            return self.prompt + "\n\n" + self._response      async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:          self._description = self.prompt          resp = await sdk.wait_for_user_input() +        self._response = resp          return TextObservation(text=resp) diff --git a/extension/react-app/src/components/ContinueButton.tsx b/extension/react-app/src/components/ContinueButton.tsx index 11dc7a92..c6117bf9 100644 --- a/extension/react-app/src/components/ContinueButton.tsx +++ b/extension/react-app/src/components/ContinueButton.tsx @@ -24,9 +24,13 @@ let StyledButton = styled(Button)`    }  `; -function ContinueButton(props: { onClick?: () => void }) { +function ContinueButton(props: { onClick?: () => void; hidden?: boolean }) {    return ( -    <StyledButton className="m-auto" onClick={props.onClick}> +    <StyledButton +      hidden={props.hidden} +      className="m-auto" +      onClick={props.onClick} +    >        <Play />        {/* <img src={"/continue_arrow.png"} width="16px"></img> */}        Continue diff --git a/extension/react-app/src/components/InputAndButton.tsx b/extension/react-app/src/components/InputAndButton.tsx new file mode 100644 index 00000000..0a8592f2 --- /dev/null +++ b/extension/react-app/src/components/InputAndButton.tsx @@ -0,0 +1,77 @@ +import React, { useRef } from "react"; +import styled from "styled-components"; +import { vscBackground } from "."; + +interface InputAndButtonProps { +  onUserInput: (input: string) => void; +} + +const TopDiv = styled.div` +  display: grid; +  grid-template-columns: 3fr 1fr; +  grid-gap: 0; +`; + +const Input = styled.input` +  padding: 0.5rem; +  border: 1px solid white; +  background-color: ${vscBackground}; +  color: white; +  border-radius: 4px; +  border-top-right-radius: 0; +  border-bottom-right-radius: 0; +  outline: none; +`; + +const Button = styled.button` +  padding: 0.5rem; +  border: 1px solid white; +  background-color: ${vscBackground}; +  color: white; +  border-radius: 4px; +  border-top-left-radius: 0; +  border-bottom-left-radius: 0; +  border-left: 0; +  cursor: pointer; + +  &:hover { +    background-color: white; +    color: black; +  } +`; + +function InputAndButton(props: InputAndButtonProps) { +  const userInputRef = useRef<HTMLInputElement>(null); + +  return ( +    <TopDiv className="grid grid-cols-2 space-x-0"> +      <Input +        ref={userInputRef} +        onKeyDown={(e) => { +          if (e.key === "Enter") { +            props.onUserInput(e.currentTarget.value); +          } +        }} +        type="text" +        onSubmit={(ev) => { +          props.onUserInput(ev.currentTarget.value); +        }} +        onClick={(e) => { +          e.stopPropagation(); +        }} +      /> +      <Button +        onClick={(e) => { +          if (userInputRef.current) { +            props.onUserInput(userInputRef.current.value); +          } +          e.stopPropagation(); +        }} +      > +        Enter +      </Button> +    </TopDiv> +  ); +} + +export default InputAndButton; diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx index 903f9b94..f54d4d75 100644 --- a/extension/react-app/src/components/StepContainer.tsx +++ b/extension/react-app/src/components/StepContainer.tsx @@ -23,6 +23,7 @@ import {  import { HistoryNode } from "../../../schema/HistoryNode";  import ReactMarkdown from "react-markdown";  import ContinueButton from "./ContinueButton"; +import InputAndButton from "./InputAndButton";  interface StepContainerProps {    historyNode: HistoryNode; @@ -177,22 +178,11 @@ function StepContainer(props: StepContainerProps) {            )}            {props.historyNode.step.name === "Waiting for user input" && ( -            <input -              ref={userInputRef} -              className="m-auto p-2 rounded-md border-1 border-solid text-white w-3/4 border-gray-200 bg-vsc-background" -              onKeyDown={(e) => { -                if (e.key === "Enter") { -                  props.onUserInput(e.currentTarget.value); -                } +            <InputAndButton +              onUserInput={(value) => { +                props.onUserInput(value);                }} -              type="text" -              onSubmit={(ev) => { -                props.onUserInput(ev.currentTarget.value); -              }} -              onClick={(e) => { -                e.stopPropagation(); -              }} -            /> +            ></InputAndButton>            )}            {props.historyNode.step.name === "Waiting for user confirmation" && (              <> diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx index a08698a4..7dd30acb 100644 --- a/extension/react-app/src/tabs/gui.tsx +++ b/extension/react-app/src/tabs/gui.tsx @@ -38,11 +38,11 @@ function GUI(props: GUIProps) {    const [waitingForSteps, setWaitingForSteps] = useState(false);    const [userInputQueue, setUserInputQueue] = useState<string[]>([]);    const [history, setHistory] = useState<History | undefined>(); -  // { +  //   {    //   timeline: [    //     {    //       step: { -  //         name: "RunCodeStep", +  //         name: "Waiting for user input",    //         cmd: "python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py",    //         description:    //           "Run `python3 /Users/natesesti/Desktop/continue/extension/examples/python/main.py`", @@ -189,6 +189,8 @@ function GUI(props: GUIProps) {      if (mainTextInputRef.current) {        if (!client) return;        let input = mainTextInputRef.current.value; +      if (input.trim() === "") return; +        setWaitingForSteps(true);        client.sendMainInput(input);        setUserInputQueue((queue) => { | 
