Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
db921fc
add generate webhook sample
andrewjschuang Jul 28, 2023
f910c8d
add generate webhook source
andrewjschuang Aug 1, 2023
6fda90f
modify logic for main
andrewjschuang Aug 1, 2023
1a722e8
add tests
andrewjschuang Aug 1, 2023
858e168
add component metadata rules (sources)
andrewjschuang Aug 1, 2023
53ed46e
add component metadata rules (actions)
andrewjschuang Aug 1, 2023
81e89fa
make only one request to create actions
andrewjschuang Aug 1, 2023
2e230e3
make gpt model a config
andrewjschuang Aug 2, 2023
0577758
try and go to next if failed
andrewjschuang Aug 2, 2023
08d3eb3
add component metadata to examples
andrewjschuang Aug 7, 2023
0dbd8cd
modify source key/name to past tense
andrewjschuang Aug 7, 2023
bd0d279
remove generate webhook sample
andrewjschuang Aug 7, 2023
b840518
add webhook signature validation
andrewjschuang Aug 7, 2023
56972fa
add webhook activate and deactivate hooks
andrewjschuang Aug 7, 2023
5580553
add brex test webhook source
andrewjschuang Aug 7, 2023
a4cbf92
redirect all test output to file
andrewjschuang Aug 7, 2023
4b6355a
add deploy hook
andrewjschuang Aug 7, 2023
12e7adc
fix typo
andrewjschuang Aug 7, 2023
1456fc3
add env example
andrewjschuang Aug 7, 2023
17a1f8d
change order in readme
andrewjschuang Aug 7, 2023
52d6c9b
change main function name
andrewjschuang Aug 7, 2023
f7a668b
add code example with auth to templates
andrewjschuang Aug 8, 2023
b65e6ac
change instructions for running
andrewjschuang Aug 8, 2023
2ab355f
disable docs by default
andrewjschuang Aug 8, 2023
8ec3e2d
add tests to readme
andrewjschuang Aug 8, 2023
7518ec9
add tests for actions
andrewjschuang Aug 8, 2023
31ed789
read instructions file outside of main
andrewjschuang Aug 8, 2023
85a895b
change tests to python
andrewjschuang Aug 8, 2023
ce6d5ab
return copy of template instead of overwriting
andrewjschuang Aug 8, 2023
57fabfb
use only one script for running tests
andrewjschuang Aug 8, 2023
98e4439
change component_type arg to type
andrewjschuang Aug 8, 2023
7cfb73c
add $summary export
andrewjschuang Aug 10, 2023
789b200
add azure openai option and adjust configs
andrewjschuang Aug 14, 2023
7adb7bf
add polling source template
andrewjschuang Aug 15, 2023
a963fe0
add tests for polling components
andrewjschuang Aug 16, 2023
088076e
alphabetical reorder tests
andrewjschuang Aug 16, 2023
a8cc5ca
add apps template
andrewjschuang Aug 21, 2023
80e81aa
Testing Stable Diffusion image to text
dylburger Aug 27, 2023
e60deeb
Adding pnpm.lock
dylburger Aug 27, 2023
ada8a35
Merge remote-tracking branch 'origin/master' into ai-components/pr-re…
dylburger Aug 27, 2023
7140f69
pnpm.lock
dylburger Aug 27, 2023
311a192
Multi agent debate (#7787)
dylburger Aug 28, 2023
48eefab
Improving readme, updating tool-versions
dannyroosevelt Aug 29, 2023
09cbbfa
Update generate_component_code.py
dannyroosevelt Aug 29, 2023
355352a
Templates restructure (#7816)
andrewjschuang Aug 30, 2023
cf2551e
Merge branch 'master' into ai-components/pr-review
andrewjschuang Aug 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
nodejs 14.19.0
pnpm 7.13.4
python 3.11.5
poetry 1.6.1
17 changes: 17 additions & 0 deletions packages/component_code_gen/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
BROWSERLESS_API_KEY=your-browserless-api-key

SUPABASE_URL=https://your-supabase-url.supabase.co
SUPABASE_API_KEY=your-supabase-service-role-key

OPENAI_API_TYPE=openai
OPENAI_API_KEY=your-openai-api-key
OPENAI_MODEL=gpt-4

# comment or remove these below if using openai api
OPENAI_API_TYPE=azure
OPENAI_DEPLOYMENT_NAME=deployment-name
OPENAI_API_VERSION=2023-05-15
OPENAI_API_BASE=https://resource-name.openai.azure.com
OPENAI_API_KEY=azure-api-key
OPENAI_MODEL=gpt-4-32k
OPENAI_TEMPERATURE=0.5
3 changes: 3 additions & 0 deletions packages/component_code_gen/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.env
instructions.md
.vscode
ve/
node_modules/
__pycache__/
tests/**/output
*.mjs
76 changes: 58 additions & 18 deletions packages/component_code_gen/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,76 @@
# AI Code Gen for Pipedream Components

Generate components using OpenAI GPT-4.
Generate components using OpenAI GPT.


### Run
### Installation

```
SCRIPT=generate_action.py
APP=slack
PROMPT="how to send myself a direct message?"
poetry run python3 "$SCRIPT" --app "$APP" "$PROMPT"
poetry run python3 "$SCRIPT" --app "$APP" "$PROMPT" --verbose # print debug logs
asdf plugin-add poetry
asdf install
cd packages/component_code_gen
poetry install
```

### Setup

### Installation
#### Create a `.env` file

```
cd packages/component_code_gen
cp .env.example .env
```

#### Modify the `.env` file to use your own keys:

1. Add these API Keys to your new `.env` file:

- BROWSERLESS_API_KEY=api_key # not required
- SUPABASE_URL=https://your-project-url.supabase.co # get this from Supabase Project Settings -> API
- SUPABASE_API_KEY=service_role_key # get this from Supabase Project Settings -> API

2. Add OpenAI keys

- OPENAI_API_TYPE=openai
- OPENAI_API_KEY=your-openai-api-key
- OPENAI_MODEL=gpt-4

3. Or use a Azure OpenAI deployment (gpt-4-32k)

1. Install poetry: follow instructions at https://python-poetry.org/docs/#installation
- OPENAI_API_TYPE=azure
- OPENAI_DEPLOYMENT_NAME=deployment-name
- OPENAI_API_VERSION=2023-05-15
- OPENAI_API_BASE=https://resource-name.openai.azure.com
- OPENAI_API_KEY=azure-api-key
- OPENAI_MODEL=gpt-4-32k

5. Create a file named `instructions.md` with the same structure as the `instructions.md.example` file:

2. Run install:
```
poetry install
## Prompt

... your prompt here ...

## API docs

... copy and paste relevant parts of the api docs here ...
```


### Setup
### Run

Create a `.env` file
```
poetry run python main.py --type action --app slack --instructions instructions.md --verbose
```


### Tests

Add these API Keys:
To run a suite of tests (e.g. webhook_sources):

```
poetry run python -m tests.test --type webhook_sources
```

- BROWSERLESS_API_KEY=api_key
- OPENAI_API_KEY=API_KEY
- SUPABASE_URL=https://url.supabase.co
- SUPABASE_API_KEY=service_role_key
This script will generate code for some selected apps/components for comparison with registry components
Compare `./tests/webhook_sources/output/*` with `./tests/webhook_sources/reference/*`
107 changes: 74 additions & 33 deletions packages/component_code_gen/code_gen/generate_component_code.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,87 @@
import config.logging_config as logging_config
from config.config import config
import helpers.supabase_helpers as supabase_helpers
import helpers.langchain_helpers as langchain_helpers
from dotenv import load_dotenv
load_dotenv()

import helpers.langchain_helpers as langchain_helpers
import helpers.supabase_helpers as supabase_helpers

import config.logging_config as logging_config
logger = logging_config.getLogger(__name__)


def main(app, prompt, templates):
def generate_code(app, prompt, templates, tries):
validate_inputs(app, prompt, templates, tries)
db = supabase_helpers.SupabaseConnector()

docs_meta = db.get_app_docs_meta(app)

if 'docs_url' in docs_meta:
contents = db.get_docs_contents(app)
if contents:
docs = { row['url']: row['content'] for row in contents }
return with_docs(app, prompt, docs, 'api reference', templates)

if 'openapi_url' in docs_meta:
contents = db.get_openapi_contents(app)
if contents:
docs = { row['path']: row['content'] for row in contents }
return with_docs(app, prompt, docs, 'openapi', templates)

return no_docs(app, prompt, templates)


def no_docs(app, prompt, templates):
logger.debug('no docs, calling openai directly')

return langchain_helpers.no_docs(app, prompt, templates)


def with_docs(app, prompt, docs, docs_type, templates):
logger.debug(f"using {docs_type} docs")

result = langchain_helpers.ask_agent(prompt, docs, templates)
results = []

auth_example = None
auth_meta = db.get_app_auth_meta(app)
if auth_meta.get('component_code_scaffold_raw'):
auth_example = f"Here's how authentication is done in {app}:\n\n{auth_meta['component_code_scaffold_raw']}\n\n"

for i in range(tries):
logger.debug(f'Attempt {i+1} of {tries}')

# Initialize a flag to track if we obtained any results with docs
has_docs_result = False

if 'docs_url' in docs_meta:
contents = db.get_docs_contents(app)
if contents:
docs = {row['url']: row['content'] for row in contents}
results.append(call_langchain(
app, prompt, templates, auth_example, docs, 'api reference'))
has_docs_result = True

if 'openapi_url' in docs_meta:
contents = db.get_openapi_contents(app)
if contents:
docs = {row['path']: row['content'] for row in contents}
results.append(call_langchain(
app, prompt, templates, auth_example, docs, 'openapi'))
has_docs_result = True

# If we haven't obtained any results using docs
if not has_docs_result:
results.append(call_langchain(app, prompt, templates, auth_example))

# Create a new prompt string
new_prompt = "I've asked other GPT agents to generate the following code based on the prompt and the instructions below. One set of code (or all) may not follow the rules laid out in the prompt or in the instructions below, so you'll need to review it for accuracy. Try to evaluate the examples according to the rules, combine the best parts of each example, and generate a final set of code that solves the problem posed by the prompt and follows all of the rules below. Here are the attempts + code:\n\n---\n\n"
for idx, result in enumerate(results, 1):
new_prompt += f"Try {idx}:\n\n${result}\n\n---\n\n"
new_prompt += "---\n\n" + prompt

# Call the model again with the new prompt to get the final result
logger.debug(f"Calling the model a final time to summarize the attempts")
return call_langchain(app, new_prompt, templates, auth_example)


def call_langchain(app, prompt, templates, auth_example, docs=None, docs_type=None, attempts=0, max_attempts=3):
logger.debug(f"Calling langchain")
# If we don't have docs, or if we can't reach OpenAI to get the parsed docs
if not docs:
logger.debug('No docs available, calling the model directly')
return langchain_helpers.no_docs(app, prompt, templates, auth_example)

if attempts >= max_attempts:
logger.debug('Max attempts reached, calling the model directly')
return langchain_helpers.no_docs(app, prompt, templates, auth_example)

# else if we have docs, call the model with docs
logger.debug(f"Using {docs_type} docs")

result = langchain_helpers.ask_agent(prompt, docs, templates, auth_example)

if result != "I don't know":
return result

logger.debug("trying again without docs")
return no_docs(app, prompt, templates)
logger.debug("Trying again without docs")
return call_langchain(app, prompt, templates, auth_example, attempts=attempts+1)


def validate_inputs(app, prompt, templates, tries):
assert app and type(app) == str
assert prompt and type(prompt) == str
assert tries and type(tries) == int
assert templates.system_instructions
19 changes: 0 additions & 19 deletions packages/component_code_gen/code_gen/transform_code.py

This file was deleted.

30 changes: 24 additions & 6 deletions packages/component_code_gen/config/config.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,39 @@
import os
from dotenv import load_dotenv
load_dotenv()

import os

def get_env_var(var_name, required=False, default=None):
if os.environ.get(var_name):
return os.environ.get(var_name)
if default is not None:
return default
if required:
raise Exception(f"Environment variable {var_name} is required")


config = {
"temperature": get_env_var("OPENAI_TEMPERATURE", default=0.5),
"openai_api_type": get_env_var("OPENAI_API_TYPE", default="azure"),
"openai": {
"api_key": os.environ.get('OPENAI_API_KEY'),
"api_key": get_env_var("OPENAI_API_KEY", required=True),
"model": get_env_var("OPENAI_MODEL", default="gpt-4"),
},
"azure": {
"deployment_name": get_env_var("OPENAI_DEPLOYMENT_NAME", required=True),
"api_version": get_env_var("OPENAI_API_VERSION", default="2023-05-15"),
"api_base": get_env_var("OPENAI_API_BASE", required=True),
"api_key": get_env_var("OPENAI_API_KEY", required=True),
"model": get_env_var("OPENAI_MODEL", default="gpt-4-32k"),
},
"browserless": {
"api_key": os.environ.get('BROWSERLESS_API_KEY'),
"api_key": get_env_var("BROWSERLESS_API_KEY"),
},
"supabase": {
"url": os.environ.get('SUPABASE_URL'),
"api_key": os.environ.get('SUPABASE_API_KEY'),
"url": get_env_var("SUPABASE_URL", required=True),
"api_key": get_env_var("SUPABASE_API_KEY", required=True),
},
"logging": {
"level": "DEBUG" if os.environ.get('DEBUG') == "1" else "WARN",
"level": get_env_var("LOGGING_LEVEL", default="WARN"),
},
}
Loading