Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def generate_code(app, prompt, templates, parsed_common_files, urls_content, tri
docs_meta = {} # XXX - temporarily disable supabase docs
results = []

auth_details = "## Auth details\n\nThese details come directly from the app configuration in Pipedream. Prioritize this information over any other information you find in the app's docs, since this section is specific to Pipedream."
auth_details = "<AuthDetails>\n\nThese details come directly from the app configuration in Pipedream. Prioritize this information over any other information you find in the app's docs, since this section is specific to Pipedream."
auth_meta = db.get_app_auth_meta(app)
auth_type = auth_meta.get('auth_type')
if auth_type == "keys":
Expand All @@ -48,7 +48,9 @@ def generate_code(app, prompt, templates, parsed_common_files, urls_content, tri
elif auth_type == "oauth":
auth_details += f"{app} is an OAuth app. The `this` object exposes the OAuth access token in the variable `this.#{app.name_slug}.$auth.oauth_access_token`. When you make an API request, use the format from the \"Auth example\" section below."
if auth_meta.get('component_code_scaffold_raw'):
auth_details = f"\n\n## Auth example\n\nHere's example Node.js code to show how authentication is done in {app}:\n\n{auth_meta['component_code_scaffold_raw']}\n\n"
auth_details += f"\n\n## Auth example\n\nHere's example Node.js code to show how authentication is done in {app}:\n\n{auth_meta['component_code_scaffold_raw']}\n\n"

auth_details += "</AuthDetails>"

normal_order = False
for i in range(tries):
Expand Down
34 changes: 28 additions & 6 deletions packages/component_code_gen/templates/actions/additional_rules.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,58 @@
additional_rules = """## Additional rules for actions
additional_rules = """<AdditionalRules>

1. Always import the app file like this:

```javascript
import appName from "../../appName.app.mjs";
```

and pass the app file as a prop to the component:

```javascript
export default {
props: {
appName,
},
// rest of the component ...
}
```

2. `return` the final value from the step. The data returned from steps must be JSON-serializable. The returned data is displayed in Pipedream. Think about it: if you don't return the data, the user won't see it.

3. Always use this signature for the run method:

```javascript
async run({ $ }) {
// your code here
// you must fill in the actual code here
}
```

Always pass { $ }, even if you don't use them in the code.
Always pass `{ $ }` in the arguments to the `run` method, even if you don't use it in the code.

4. Remember that `@pipedream/platform` axios returns a Promise that resolves to the HTTP response data. There is NO `data` property in the response that contains the data. The data from the HTTP response is returned directly in the response, not in the `data` property. Think about it: if you try to extract a data property that doesn't exist, the variable will hold the value `undefined`. You must return the data from the response directly and extract the proper data in the format provided by the API docs.
4. `@pipedream/platform` axios returns a Promise that resolves to the HTTP response data. There is NO `data` property in the response that contains the data. The data from the HTTP response is returned directly in the response, not in the `data` property. Think about it: if you try to extract a data property that doesn't exist, the variable will hold the value `undefined`. You must return the data from the response directly and extract the proper data in the format provided by the API docs.

For example, do this:

```javascript
const response = await axios(this, {
url: `https://api.stability.ai/v1/engines/list`,
headers: {
Authorization: `Bearer ${this.dreamstudio.$auth.api_key}`,
},
});
// process the response data. response.data is undefined
// process the `response` as the return data. `response.data` is undefined, data is directly in `response`
```

not this:

```javascript
// this is incorrect — there is no `data` property in the response
const { data } = await axios(this, {
url: `https://api.stability.ai/v1/engines/list`,
headers: {
Authorization: `Bearer ${this.dreamstudio.$auth.api_key}`,
},
});"""
});
```

</AdditionalRules>"""
15 changes: 9 additions & 6 deletions packages/component_code_gen/templates/actions/export_summary.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
export_summary = """## Export summary
export_summary = """<ExportSummary>

A short summary should be exported before the end so that the user can quickly read what has happened. This is done by calling `$.export("$summary", "Your summary here")`. This is not optional.
You must call `$.export` to export a short text summary near the end of the `run` method so the user knows the call was successful. This is done by calling `$.export("$summary", "Your summary here")`.

The summary should contain relevant metadata about the object that was created, updated, or deleted. For example, if you are creating a new issue, you should include the issue name or ID in the summary.
The summary should contain relevant metadata about the object that was created, updated, or deleted. For example, if you are creating a new issue, you should include the issue name or ID in the summary. Include information here that you think will be most relevant for the user reading the summary.

```
`$.export("$summary", `Created issue ${name}`)
Generally, this should happen immediately before you return the data at the end of the component's `run` method.

```javascript
$.export("$summary", `Created issue ${name}`)
return data
```

Include information here that you think will be most relevant for the user.
</ExportSummary>
"""
32 changes: 27 additions & 5 deletions packages/component_code_gen/templates/actions/introduction.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
introduction = """## Instructions
introduction = """<Instructions>
Your goal is to create Pipedream Action Components. Your code should solve the requirements provided below.
<Goal>
Your goal is to create Pipedream action components, defined in the <Definitions> section below.
Other GPT agents will be reviewing your work, and will provide feedback on your code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules.
Your code should solve the requirements provided below.
## Pipedream components
Think step by step:
All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument."""
1. Review the requirements
2. Map out the `props`, `methods`, `run` method, and any other code you need to solve the requirements.
3. Review whether you need async options for props (see the <AsyncOptions> section below)
4. Review all of the rules carefully before producing code
5. Produce full, complete, working code. This code is going straight to production.
6. Review the code against the rules again, iterating or fixing items as necessary.
7. Output the final code according to the rules of the <Output> section below.
Other GPT agents will be reviewing your work, and will provide feedback on your code. Please review it before producing output.
</Goal>
Comment on lines +3 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix typo and consider adding a brief introduction

The section provides clear, step-by-step instructions for creating Pipedream action components. However, there's a minor typo that needs to be corrected:

  1. On line 21, "Defintions" should be "Definitions".

Additionally, consider adding a brief introductory sentence before the numbered list to set the context for the steps that follow.

Here's a suggested improvement for the beginning of the section:

 <Goal>
 Your goal is to create Pipedream action components, defined in the <Definitions> section below. 
 
 Your code should solve the requirements provided below.
 
+To achieve this goal, follow these steps:
+
 Think step by step:
 
 1. Review the requirements

And fix the typo:

-<Defintions>
+<Definitions>

Also applies to: 21-21

<Defintions>
<PipedreamActionComponents>
All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument.
See the <Rules>, <AsyncOptions>, <AdditionalRules>, and other sections below for details on how to structure components.
</PipedreamActionComponents>
</Definitions>
Comment on lines +22 to +29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance the section with more details and examples

While the section provides a basic understanding of Pipedream components, it could be more comprehensive. Consider the following improvements:

  1. Provide a more detailed explanation of the component structure.
  2. Include a simple example of a basic Pipedream component.
  3. Explain key properties or methods that are commonly used in components.

Here's a suggested expansion of the section:

 <PipedreamActionComponents>
 
 All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument.
 
+A typical Pipedream component structure includes:
+- `props`: Define the input parameters for the component.
+- `run`: The main method that executes when the component is triggered.
+- Other optional methods like `deploy`, `dedupe`, etc.
+
+Example of a basic component structure:
+
+```javascript
+export default {
+  key: "my-component",
+  name: "My Component",
+  version: "0.0.1",
+  props: {
+    myProp: "string",
+  },
+  async run({ steps, $ }) {
+    // Component logic here
+  },
+};
+```
+
 See the <Rules>, <AsyncOptions>, <AdditionalRules>, and other sections below for details on how to structure components.
 
 </PipedreamActionComponents>

This expansion provides more context and a concrete example, which should help users better understand Pipedream components.

</Instructions>"""
Comment on lines +1 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Address missing sections referenced in the introduction

The introduction refers to several sections that are not present in this file, such as , , , and . This could lead to confusion for users expecting to find this information here. Consider the following options:

  1. Include these sections within this file to provide a complete set of instructions.
  2. If these sections are defined elsewhere, add references or links to where users can find this information.
  3. Add a note explaining that these sections will be provided separately or in a different context.

Would you like assistance in drafting placeholder content for these missing sections or in creating a note explaining their absence?

12 changes: 8 additions & 4 deletions packages/component_code_gen/templates/actions/main_example.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
main_example = """## OpenAI example component
main_example = """<Example>
<OpenAI>

Here's an example component:
Here's an example Pipedream action for OpenAI that lists all models available to the user:

```
```javascript
import openai from "../../openai.app.mjs"
import { axios } from "@pipedream/platform"

Expand All @@ -26,4 +27,7 @@
return response
},
};
```"""
```
</OpenAI>
</Example>
"""
17 changes: 13 additions & 4 deletions packages/component_code_gen/templates/actions/other_example.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
other_example = """## Slack API example component
other_example = """<AdditionalExample>
<Slack>

Here's an example Pipedream component that makes a test request against the Slack API:

```
```javascript
import slack from "../../slack.app.mjs"
import { axios } from "@pipedream/platform"

Expand Down Expand Up @@ -41,18 +42,22 @@
return response
},
};
```

Notice this section:

```javascript
data: {
channel: this.channel,
text: this.text,
},
```

This shows you how to pass the values of props (e.g. this.channel and this.text) as params to the API. This is one of the most important things to know: you MUST generate code that adds inputs as props so that users can enter their own values when making the API request. You MUST NOT pass static values. See rule #2 below for more detail.
This shows you how to pass the values of props (e.g. `this.channel` and `this.text`) as params to the API. This is one of the most important things to know: you MUST generate code that adds inputs as props so that users can enter their own values when making the API request. You MUST NOT pass static values. See the <Rules> for more information.

The code you generate should be placed within the `run` method of the Pipedream component:

```javascript
import { axios } from "@pipedream/platform";

export default {
Expand All @@ -69,4 +74,8 @@
$.export("$summary", "Your summary here")
return response
},
};"""
};
```

</Slack>
</AdditionalExample>"""
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
additional_rules = """## Additional rules
additional_rules = """<AdditionalRules>

### Generate propDefinitions and methods for ALL requirements
1. Generate `propDefinitions` and `methods` for ALL requirements

The instructions should note the actions and source components that are required for the app. The code generator should generate the propDefinitions and methods for ALL requirements. Think about it: this way other agents will be able to use the shared props + methods in the action and source components. Double-check your output to make sure that the propDefinitions and methods are generated for ALL requirements.
The instructions should note the actions and source components that are required for the app. The code generator should generate the `propDefinitions` and `methods` for ALL requirements. Think about it: this way other agents will be able to use the shared props + methods in the action and source components. Double-check your output to make sure that the propDefinitions and methods are generated for ALL requirements.
</AdditionalRules>
"""
38 changes: 30 additions & 8 deletions packages/component_code_gen/templates/apps/introduction.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
introduction = """## Instructions
introduction = """<Instructions>

Your goal is to create Pipedream app files. Your code should solve the requirements provided below.
<Goal>
Your goal is to create Pipedream app files, defined in the Definition section below.

DO NOT remove any propDefinitions or methods that already exist. You can only write more, if required.
Your code should solve the requirements provided below.

Other GPT agents will be reviewing your work, and will provide feedback on your code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules.
Think step by step:

## Pipedream App files
1. Review the requirements
2. Map out the props and methods you need to solve the requirements
3. Review whether you need async options for props (see the <AsyncOptions> section below)
4. Review all of the rules carefully before producing code
5. Produce full, complete, working code. This code is going straight to production.
6. Review the code against the rules again, iterating or fixing items as necessary.
7. Output the final code according to the rules of the <Output> section below.

Other GPT agents will be reviewing your work, and will provide feedback on your code. Please review it before producing output.
</Goal>

<Definition>
<PipedreamAppFiles>

All Pipedream app files are Node.js modules that have a default export: a javascript object - a Pipedream app - as its single argument.

All app objects have four properties: type, app, propDefinitions, and methods:
All app objects have four properties: `type`, `app`, `propDefinitions`, and `methods`:

- The `type` property is always set to "app".
- The `app` property is the name of the app, e.g. "google_sheets".
- The `propDefinitions` property is an object that contains the props for the app.
- The methods property is an object that contains the methods for the app.
- The `methods` property is an object that contains the methods for the app.

These props and methods are shared across components for this app file. You'll need to generate props and methods for ALL requirements for all components that you're passed below.
</PipedreamAppFiles>
</Definition>
<Output>
Output Node.js code.

DO NOT remove any `propDefinitions` or `methods` that already exist. You can only write more, if required.
</Output>

These props and methods are shared across components for this app file. You'll need to generate props and methods for ALL requirements for all components that you're passed below."""
</Instructions>"""
16 changes: 11 additions & 5 deletions packages/component_code_gen/templates/apps/main_example.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
main_example = """## Example app file for Raindrop
main_example = """<Examples>
<Raindrop>

Here's an example Pipedream app for Raindrop:

Expand Down Expand Up @@ -87,15 +88,17 @@
},
};
```
</Raindrop>
<GeneralExample>
App files contain a `propDefinitions` property, which contains the definitions for the props of the app.

This object contains a `propDefinitions` property, which contains the definitions for the props of the app.

The propDefinitions object contains two props: collectionId and raindropId. The collectionId prop is a string prop. The raindropId prop is also a string prop. The propDefinitions object also contains an `options` method. The `options` method is an optional method that can be defined on a prop. It is used to dynamically generate the options for a prop and can return a static array of options or a Promise that resolves to an array of options.
The `propDefinitions` object contains two props: `collectionId` and `raindropId`. The `collectionId` prop is a string prop. The `raindropId` prop is also a string prop. The `propDefinitions` object also contains an `options` method. The `options` method is an optional method that can be defined on a prop. It is used to dynamically generate the options for a prop and can return a static array of options or a Promise that resolves to an array of options.

This object contains a `props` property, which defines a single prop of type "app":

```
import { axios } from "@pipedream/platform";

export default {
type: "app",
app: "the_app_name",
Expand Down Expand Up @@ -141,4 +144,7 @@
},
},
}
```"""
```
</GeneralExample>
</Examples>
"""
20 changes: 13 additions & 7 deletions packages/component_code_gen/templates/apps/methods.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
methods = """## Methods
methods = """<Methods>

The `methods` property contains helper methods. These methods can be called by other files.
The `methods` property contains helper methods that compnents can use. These methods can be called by components that include the app file.

A `_baseUrl` method is always required. It should return the base URL endpoint for the API.
### _baseUrl method

A `async _makeRequest` method is always required. It contains the code that makes the API request. It takes one argument, a single object named `opts`.
Always include a `_baseUrl` method. It should return the base URL endpoint for the API, defined by the OpenAPI spec or the API documentation.

### _makeRequest method

Always include an `async _makeRequest` method. It contains the code that makes the API request. It takes one argument, a single object named `opts`.

`opts` is an object that contains the parameters of the API request. When calling a component method with multiple parameters, you should pass them as a single object, using the Javascript spread syntax and destructuring when able to.

Expand Down Expand Up @@ -32,7 +36,7 @@

An example `_makeRequest` method is shown below. It is a simple GET request that returns the data from the response.

```
```javascript
async _makeRequest(opts = {}) {
const { $ = this, method = "GET", path = "/", headers, ...otherOpts } = opts;
return axios($, {
Expand All @@ -48,7 +52,7 @@

Auxiliary methods, usually for CRUD operations call `_makeRequest` with the appropriate parameters. Please add a few methods for common operations, e.g. get and list. You can also add other methods that you think are useful. Similar to the `_makeRequest` method, these auxiliary methods should have only one parameter, an object, `opts`. It should always destructure `...otherOpts`. Be sure to always add this parameter. `return` directly when calling the `_makeRequest` method. Here's an example:

```
```javascript
async listObjects(opts = {}) {
return this._makeRequest({
path: "/objects",
Expand All @@ -70,4 +74,6 @@

If we find more data, the method should call itself with the listing method and the parameters for fetching the next set of data.

If we don't find more data, you should return the array of results."""
If we don't find more data, you should return the array of results.

</Methods>"""
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
prop_definitions = """## Prop Definitions
prop_definitions = """<PropDefinitions>

The app code should contain a `propDefinitions` property, which are the definitions for the props.
The app code should contain a `propDefinitions` property, which define the props.

You'll find a "Props" section below that outlines the rules for generating props. All of those rules are valid, BUT instead of placing them in a `props` property, you MUST place props in the `propDefinitions` property. This is how Pipedream app files expect props to be declared.
You'll find a <Props> section below that outlines the rules for generating props. All of those rules are valid, BUT instead of placing them in a `props` property, you MUST place props in the `propDefinitions` property. This is how Pipedream app files expect props to be declared.
</PropDefinitions>
"""
8 changes: 5 additions & 3 deletions packages/component_code_gen/templates/common/app_prop.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
app_prop = """## App props
app_prop = """<AppProp>

The props object must contain a `props` property, which defines a single prop of type "app":

```
```javascript
export default {
props: {
the_app_name: {
Expand All @@ -14,4 +14,6 @@
}
```

This lets the user connect their app account to the step, authorizing requests to the app API."""
This lets the user connect their app account to the step, authorizing requests to the app API.

</AppProp>"""
Loading
Loading