Skip to content

Issue #17031 #17036

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
39 changes: 39 additions & 0 deletions .github/workflows/retrieve-commits.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Retrieve Commits


on:
workflow_dispatch:

jobs:
fetch-commits:
runs-on: ubuntu-latest
steps:

- name: Checkout repository
uses: actions/checkout@v3


- name: List commits
run: |
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/commits?per_page=30 \
> commits.json

- name: Get specific commit
run: |
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository_owner }}/${{ github.event.repository.name }}/commits/${{ github.sha }} \
> commit.json


- name: Upload commit data
uses: actions/upload-artifact@v3
with:
name: commit-data
path: |
commits.json
commit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import openai from "../../openai.app.mjs";
import common from "../common/common.mjs";
import constants from "../../common/constants.mjs";
import axios from "axios";

export default {
...common,
key: "openai-chat-using-responses-api",
name: "Chat with OpenAI Responses API",
version: "0.0.1",
description:
"Send a chat via the Responses API, mixing built-in tools and MCP servers.",
type: "action",
props: {
openai,
modelId: {
type: "string",
label: "Model",
description: "Model used to generate the response",
default: "gpt-4o",
options: [
"gpt-4o",
"gpt-4o-mini",
],
},
input: {
type: "string",
label: "Chat Input",
description: "Text input to the model used to generate a response",
},
instructions: {
type: "string",
label: "Instructions",
description:
"Inserts a system (or developer) message as the first item in the model's context",
optional: true,
},
previousResponseId: {
type: "string",
label: "Previous Response ID",
description:
"The unique ID of the previous response to the model. Use this to create multi-turn conversations",
optional: true,
},
truncation: {
type: "string",
label: "Truncation",
description:
"Specifies the truncation mode for the response if it exceeds the context window",
default: "auto",
options: [
"auto",
"disabled",
],
optional: true,
},
responseFormat: {
type: "string",
label: "Response Format",
description:
"- **text**: Returns unstructured text output.\n- **json_schema**: Enforces a specific structure using a JSON schema.",
options: [
"text",
"json_schema",
],
default: "text",
optional: true,
reloadProps: true,
},
skipThisStep: {
type: "boolean",
label: "Skip This Step",
description:
"Pass in a boolean custom expression to skip execution at runtime",
default: false,
optional: true,
},
builtInTools: {
type: "string[]",
label: "Built-In Tools",
description:
"Which of OpenAI’s first-party tools to enable (web search, file search, code interpreter).",
options: [
{
label: "Web Search",
value: "web_search_preview",
},
{
label: "File Search",
value: "file_search",
},
{
label: "Code Interpreter",
value: "code_interpreter",
},
],
default: [],
},
mcpServers: {
type: "string[]",
label: "MCP Server URLs",
description:
"Enter your MCP server base URLs. To set one up, visit https://mcp.pipedream.com/ and click “Create new server.",
optional: true,
Comment on lines +99 to +104
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

Consider adding URL validation for MCP servers.

User-provided MCP server URLs could potentially be used for SSRF attacks. Consider validating that URLs point to expected domains or implementing allowlists.

  mcpServers: {
    type: "string[]",
    label: "MCP Server URLs",
    description:
      "Enter your MCP server base URLs. To set one up, visit https://mcp.pipedream.com/ and click "Create new server.",
    optional: true,
+   validate: (urls) => {
+     if (!urls?.length) return true;
+     for (const url of urls) {
+       try {
+         const parsed = new URL(url);
+         if (!['http:', 'https:'].includes(parsed.protocol)) {
+           throw new Error(`Invalid protocol: ${parsed.protocol}`);
+         }
+       } catch (error) {
+         throw new Error(`Invalid URL "${url}": ${error.message}`);
+       }
+     }
+     return true;
+   },
  },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mcpServers: {
type: "string[]",
label: "MCP Server URLs",
description:
"Enter your MCP server base URLs. To set one up, visit https://mcp.pipedream.com/ and click “Create new server.",
optional: true,
mcpServers: {
type: "string[]",
label: "MCP Server URLs",
description:
"Enter your MCP server base URLs. To set one up, visit https://mcp.pipedream.com/ and click “Create new server.",
optional: true,
validate: (urls) => {
if (!urls?.length) return true;
for (const url of urls) {
try {
const parsed = new URL(url);
if (!['http:', 'https:'].includes(parsed.protocol)) {
throw new Error(`Invalid protocol: ${parsed.protocol}`);
}
} catch (error) {
throw new Error(`Invalid URL \"${url}\": ${error.message}`);
}
}
return true;
},
},
🤖 Prompt for AI Agents
In
components/openai/actions/chat-with-opeai-responses-api/chat-with-openai-responses-api.mjs
around lines 99 to 104, the MCP server URLs input lacks validation, which could
lead to SSRF vulnerabilities. Implement validation logic to ensure each URL is
well-formed and restrict URLs to a predefined allowlist of trusted domains or
patterns. This can be done by parsing each URL and checking its hostname against
the allowed domains before accepting them.

},
mcpTools: {
type: "string[]",
label: "MCP Tools to Enable",
description:
"Select which tools from your MCP servers to include in the chat.",
optional: true,
async options({ mcpServers }) {
if (!mcpServers?.length) return [];
const all = [];
for (let url of mcpServers) {
url = url.replace(/\/$/, "");
const { data } = await axios.get(`${url}/tools`);
for (const t of data.tools) {
all.push({
label: t.name,
value: t.id,
});
}
}
return all;
},
Comment on lines +112 to +126
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

Add comprehensive error handling for MCP server requests.

The async options method lacks error handling for HTTP requests to MCP servers. If a server is unreachable or returns an error, this will cause the component to fail during property loading.

  async options({ mcpServers }) {
    if (!mcpServers?.length) return [];
    const all = [];
    for (let url of mcpServers) {
      url = url.replace(/\/$/, "");
-     const { data } = await axios.get(`${url}/tools`);
-     for (const t of data.tools) {
-       all.push({
-         label: t.name,
-         value: t.id,
-       });
-     }
+     try {
+       const { data } = await axios.get(`${url}/tools`, {
+         timeout: 5000,
+         validateStatus: (status) => status === 200,
+       });
+       if (data?.tools && Array.isArray(data.tools)) {
+         for (const t of data.tools) {
+           if (t?.name && t?.id) {
+             all.push({
+               label: t.name,
+               value: t.id,
+             });
+           }
+         }
+       }
+     } catch (error) {
+       console.warn(`Failed to fetch tools from ${url}:`, error.message);
+       // Continue with other servers instead of failing completely
+     }
    }
    return all;
  },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async options({ mcpServers }) {
if (!mcpServers?.length) return [];
const all = [];
for (let url of mcpServers) {
url = url.replace(/\/$/, "");
const { data } = await axios.get(`${url}/tools`);
for (const t of data.tools) {
all.push({
label: t.name,
value: t.id,
});
}
}
return all;
},
async options({ mcpServers }) {
if (!mcpServers?.length) return [];
const all = [];
for (let url of mcpServers) {
url = url.replace(/\/$/, "");
try {
const { data } = await axios.get(`${url}/tools`, {
timeout: 5000,
validateStatus: (status) => status === 200,
});
if (data?.tools && Array.isArray(data.tools)) {
for (const t of data.tools) {
if (t?.name && t?.id) {
all.push({
label: t.name,
value: t.id,
});
}
}
}
} catch (error) {
console.warn(`Failed to fetch tools from ${url}:`, error.message);
// Continue with other servers instead of failing completely
}
}
return all;
},
🤖 Prompt for AI Agents
In
components/openai/actions/chat-with-opeai-responses-api/chat-with-openai-responses-api.mjs
around lines 112 to 126, the async options method does not handle errors from
axios.get calls to MCP servers, which can cause failures if a server is
unreachable or returns an error. Add try-catch blocks around the axios.get
request to catch any errors, log or handle them appropriately, and ensure the
method continues processing other servers without failing entirely. This will
make the property loading more robust against individual server issues.

},
},
additionalProps() {
const props = {};
if (
this.responseFormat ===
constants.CHAT_RESPONSE_FORMAT.JSON_SCHEMA.value
) {
props.jsonSchema = {
type: "string",
label: "JSON Schema",
description:
"Define the schema that the model's output must adhere to.",
};
}
return props;
},
methods: {
...common.methods,
},
async run({ $ }) {
if (this.skipThisStep) {
$.export("$summary", "Step execution skipped");
return;
}
const tools = [];
for (const id of this.builtInTools) {
tools.push({
type: id,
});
}
for (const id of this.mcpTools || []) {
tools.push({
type: id,
});
}
Comment on lines +158 to +162
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

Add array validation for mcpTools.

The code assumes mcpTools is an array without validation, which could cause runtime errors if the property is undefined or not an array.

- for (const id of this.mcpTools || []) {
+ for (const id of Array.isArray(this.mcpTools) ? this.mcpTools : []) {
    tools.push({
      type: id,
    });
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (const id of this.mcpTools || []) {
tools.push({
type: id,
});
}
for (const id of Array.isArray(this.mcpTools) ? this.mcpTools : []) {
tools.push({
type: id,
});
}
🤖 Prompt for AI Agents
In
components/openai/actions/chat-with-opeai-responses-api/chat-with-openai-responses-api.mjs
around lines 158 to 162, the code iterates over this.mcpTools assuming it is
always an array, which can cause runtime errors if it is undefined or not an
array. Add a validation check to confirm this.mcpTools is an array before the
loop, and only iterate if the check passes. This prevents errors by ensuring the
code handles cases where mcpTools is missing or not an array.

const data = {
model: this.modelId,
input: this.input,
instructions: this.instructions,
previous_response_id: this.previousResponseId,
truncation: this.truncation,
tools,
};
if (
this.responseFormat ===
constants.CHAT_RESPONSE_FORMAT.JSON_SCHEMA.value
) {
try {
data.text = {
format: {
type: this.responseFormat,
...JSON.parse(this.jsonSchema),
},
};
} catch {
throw new Error("Invalid JSON format in the provided JSON Schema");
}
Comment on lines +175 to +184
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

Improve JSON schema validation and error handling.

The current error handling for JSON parsing is too generic and doesn't provide helpful feedback to users.

  try {
+   if (!this.jsonSchema || typeof this.jsonSchema !== 'string') {
+     throw new Error("JSON Schema is required when using json_schema response format");
+   }
+   const parsedSchema = JSON.parse(this.jsonSchema);
+   if (typeof parsedSchema !== 'object' || parsedSchema === null) {
+     throw new Error("JSON Schema must be a valid JSON object");
+   }
    data.text = {
      format: {
        type: this.responseFormat,
-       ...JSON.parse(this.jsonSchema),
+       ...parsedSchema,
      },
    };
- } catch {
-   throw new Error("Invalid JSON format in the provided JSON Schema");
+ } catch (error) {
+   if (error instanceof SyntaxError) {
+     throw new Error(`Invalid JSON syntax in schema: ${error.message}`);
+   }
+   throw error;
  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
data.text = {
format: {
type: this.responseFormat,
...JSON.parse(this.jsonSchema),
},
};
} catch {
throw new Error("Invalid JSON format in the provided JSON Schema");
}
try {
if (!this.jsonSchema || typeof this.jsonSchema !== 'string') {
throw new Error("JSON Schema is required when using json_schema response format");
}
const parsedSchema = JSON.parse(this.jsonSchema);
if (typeof parsedSchema !== 'object' || parsedSchema === null) {
throw new Error("JSON Schema must be a valid JSON object");
}
data.text = {
format: {
type: this.responseFormat,
...parsedSchema,
},
};
} catch (error) {
if (error instanceof SyntaxError) {
throw new Error(`Invalid JSON syntax in schema: ${error.message}`);
}
throw error;
}
🤖 Prompt for AI Agents
In
components/openai/actions/chat-with-opeai-responses-api/chat-with-openai-responses-api.mjs
around lines 175 to 184, the catch block for JSON.parse is too generic and does
not provide detailed error feedback. Modify the catch block to capture the
specific error thrown by JSON.parse and include its message in the thrown Error,
so users receive more informative feedback about what went wrong with the JSON
schema parsing.

}
const response = await this.openai.responses({
$,
data,
});
Comment on lines +186 to +189
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the OpenAI responses method exists.

Ensure that the this.openai.responses() method is available in the OpenAI app module, as this appears to be a newer API endpoint.


🏁 Script executed:

#!/bin/bash
# Description: Verify if the responses method exists in the OpenAI app module
# Expected: Find the responses method implementation

# Search for the responses method in OpenAI related files
ast-grep --pattern 'responses($_) {
  $$$
}'

# Also search for any mention of responses API
rg -A 5 "responses.*api|responses.*method"

Length of output: 6777


Missing responses Method on OpenAI Client

We couldn’t locate a responses method on this.openai. The OpenAI app module does not currently expose this endpoint, so calling this.openai.responses() will fail.

Please update accordingly:

  • Confirm the correct client method name for the new Responses API (e.g., chat.completions, chat.stream, etc.).
  • If responses is intended, implement it in the OpenAI app module (components/openai), wiring through to the actual API endpoint.
  • Otherwise, replace the call in components/openai/actions/chat-with-opeai-responses-api/chat-with-openai-responses-api.mjs (around lines 186–189) with the appropriate existing method.
🤖 Prompt for AI Agents
In
components/openai/actions/chat-with-opeai-responses-api/chat-with-openai-responses-api.mjs
around lines 186 to 189, the call to this.openai.responses() is invalid because
the OpenAI client does not have a responses method. To fix this, verify the
correct existing method name for the intended API call (such as chat.completions
or chat.stream) and replace this.openai.responses() with that method. If the
responses method is required, implement it in the OpenAI app module under
components/openai by adding the appropriate API endpoint wiring before using it
here.

if (response) {
$.export("$summary", `Chat sent (id: ${response.id})`);
$.export("chat_responses", response.output);
}
return response;
},
};
Loading