n8n-nodes-github-copilot 3.27.6 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/credentials/GitHubCopilotApi.credentials.d.ts +1 -1
- package/dist/credentials/GitHubCopilotApi.credentials.js +19 -19
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.backup.d.ts +1 -1
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.backup.js +71 -71
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.d.ts +1 -1
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.js +67 -67
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.oauth.d.ts +1 -1
- package/dist/credentials/GitHubCopilotOAuth2Api.credentials.oauth.js +38 -38
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilot/GitHubCopilot.node.js +188 -181
- package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/GitHubCopilotChatAPI.node.js +38 -38
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/nodeProperties.js +97 -97
- package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.d.ts +2 -2
- package/dist/nodes/GitHubCopilotChatAPI/utils/imageProcessor.js +16 -15
- package/dist/nodes/GitHubCopilotChatAPI/utils/index.d.ts +3 -3
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.d.ts +3 -3
- package/dist/nodes/GitHubCopilotChatAPI/utils/mediaDetection.js +20 -26
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatAPI/utils/modelCapabilities.js +24 -24
- package/dist/nodes/GitHubCopilotChatAPI/utils/types.d.ts +4 -4
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotChatModel/GitHubCopilotChatModel.node.js +86 -82
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.d.ts +5 -0
- package/dist/nodes/GitHubCopilotOpenAI/GitHubCopilotOpenAI.node.js +142 -0
- package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.d.ts +2 -0
- package/dist/nodes/GitHubCopilotOpenAI/nodeProperties.js +326 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/index.d.ts +2 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/index.js +24 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.d.ts +95 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/openaiCompat.js +175 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/types.d.ts +101 -0
- package/dist/nodes/GitHubCopilotOpenAI/utils/types.js +2 -0
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.d.ts +1 -1
- package/dist/nodes/GitHubCopilotTest/GitHubCopilotTest.node.js +96 -94
- package/package.json +75 -74
|
@@ -9,34 +9,34 @@ const GitHubCopilotEndpoints_1 = require("../../shared/utils/GitHubCopilotEndpoi
|
|
|
9
9
|
class GitHubCopilotChatAPI {
|
|
10
10
|
constructor() {
|
|
11
11
|
this.description = {
|
|
12
|
-
displayName:
|
|
13
|
-
name:
|
|
14
|
-
icon:
|
|
15
|
-
group: [
|
|
12
|
+
displayName: "GitHub Copilot Chat API",
|
|
13
|
+
name: "gitHubCopilotChatAPI",
|
|
14
|
+
icon: "file:../../shared/icons/copilot.svg",
|
|
15
|
+
group: ["AI"],
|
|
16
16
|
version: 1,
|
|
17
|
-
subtitle:
|
|
18
|
-
description:
|
|
17
|
+
subtitle: "={{$parameter[\"operation\"] + \": \" + $parameter[\"model\"]}}",
|
|
18
|
+
description: "Use official GitHub Copilot Chat API with your subscription - access GPT-5, Claude, Gemini and more",
|
|
19
19
|
defaults: {
|
|
20
|
-
name:
|
|
20
|
+
name: "GitHub Copilot Chat API",
|
|
21
21
|
},
|
|
22
22
|
inputs: ["main"],
|
|
23
23
|
outputs: ["main"],
|
|
24
24
|
credentials: [
|
|
25
25
|
{
|
|
26
|
-
name:
|
|
26
|
+
name: "githubCopilotApi",
|
|
27
27
|
required: true,
|
|
28
28
|
displayOptions: {
|
|
29
29
|
show: {
|
|
30
|
-
credentialType: [
|
|
30
|
+
credentialType: ["githubCopilotApi"],
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
|
-
name:
|
|
35
|
+
name: "githubCopilotOAuth2Api",
|
|
36
36
|
required: true,
|
|
37
37
|
displayOptions: {
|
|
38
38
|
show: {
|
|
39
|
-
credentialType: [
|
|
39
|
+
credentialType: ["githubCopilotOAuth2Api"],
|
|
40
40
|
},
|
|
41
41
|
},
|
|
42
42
|
},
|
|
@@ -50,15 +50,15 @@ class GitHubCopilotChatAPI {
|
|
|
50
50
|
const returnData = [];
|
|
51
51
|
for (let i = 0; i < items.length; i++) {
|
|
52
52
|
try {
|
|
53
|
-
const operation = this.getNodeParameter(
|
|
54
|
-
const model = this.getNodeParameter(
|
|
55
|
-
if (operation ===
|
|
56
|
-
const userMessage = this.getNodeParameter(
|
|
57
|
-
const systemMessage = this.getNodeParameter(
|
|
58
|
-
const advancedOptions = this.getNodeParameter(
|
|
53
|
+
const operation = this.getNodeParameter("operation", i);
|
|
54
|
+
const model = this.getNodeParameter("model", i);
|
|
55
|
+
if (operation === "chat") {
|
|
56
|
+
const userMessage = this.getNodeParameter("message", i);
|
|
57
|
+
const systemMessage = this.getNodeParameter("systemMessage", i, "");
|
|
58
|
+
const advancedOptions = this.getNodeParameter("advancedOptions", i, {});
|
|
59
59
|
const enableRetry = advancedOptions.enableRetry !== false;
|
|
60
60
|
const maxRetries = advancedOptions.maxRetries || 3;
|
|
61
|
-
const includeMedia = this.getNodeParameter(
|
|
61
|
+
const includeMedia = this.getNodeParameter("includeMedia", i, false);
|
|
62
62
|
const modelInfo = GitHubCopilotModels_1.GitHubCopilotModelsManager.getModelByValue(model);
|
|
63
63
|
if (includeMedia) {
|
|
64
64
|
if (!(modelInfo === null || modelInfo === void 0 ? void 0 : modelInfo.capabilities.vision) && !(modelInfo === null || modelInfo === void 0 ? void 0 : modelInfo.capabilities.multimodal)) {
|
|
@@ -68,28 +68,28 @@ class GitHubCopilotChatAPI {
|
|
|
68
68
|
const messages = [];
|
|
69
69
|
if (systemMessage) {
|
|
70
70
|
messages.push({
|
|
71
|
-
role:
|
|
71
|
+
role: "system",
|
|
72
72
|
content: systemMessage,
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
let userContent = userMessage;
|
|
76
76
|
if (includeMedia) {
|
|
77
|
-
const mediaSource = this.getNodeParameter(
|
|
78
|
-
const mediaFile = this.getNodeParameter(
|
|
79
|
-
const mediaUrl = this.getNodeParameter(
|
|
80
|
-
const mediaBinaryProperty = this.getNodeParameter(
|
|
77
|
+
const mediaSource = this.getNodeParameter("mediaSource", i);
|
|
78
|
+
const mediaFile = this.getNodeParameter("mediaFile", i, "");
|
|
79
|
+
const mediaUrl = this.getNodeParameter("mediaUrl", i, "");
|
|
80
|
+
const mediaBinaryProperty = this.getNodeParameter("mediaBinaryProperty", i, "");
|
|
81
81
|
const contentArray = [];
|
|
82
82
|
if (userMessage.trim()) {
|
|
83
83
|
contentArray.push({
|
|
84
|
-
type:
|
|
84
|
+
type: "text",
|
|
85
85
|
text: userMessage,
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
try {
|
|
89
89
|
const mediaResult = await (0, mediaDetection_1.processMediaFile)(this, i, mediaSource, mediaFile, mediaUrl, mediaBinaryProperty);
|
|
90
|
-
if (mediaResult.type ===
|
|
90
|
+
if (mediaResult.type === "image" && mediaResult.dataUrl) {
|
|
91
91
|
contentArray.push({
|
|
92
|
-
type:
|
|
92
|
+
type: "image_url",
|
|
93
93
|
image_url: {
|
|
94
94
|
url: mediaResult.dataUrl,
|
|
95
95
|
},
|
|
@@ -97,21 +97,21 @@ class GitHubCopilotChatAPI {
|
|
|
97
97
|
}
|
|
98
98
|
else {
|
|
99
99
|
contentArray.push({
|
|
100
|
-
type:
|
|
100
|
+
type: "text",
|
|
101
101
|
text: `[Image processing failed: ${mediaResult.description}]`,
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
catch (error) {
|
|
106
106
|
contentArray.push({
|
|
107
|
-
type:
|
|
108
|
-
text: `[Media processing error: ${error instanceof Error ? error.message :
|
|
107
|
+
type: "text",
|
|
108
|
+
text: `[Media processing error: ${error instanceof Error ? error.message : "Unknown error"}]`,
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
userContent = contentArray;
|
|
112
112
|
}
|
|
113
113
|
messages.push({
|
|
114
|
-
role:
|
|
114
|
+
role: "user",
|
|
115
115
|
content: userContent,
|
|
116
116
|
});
|
|
117
117
|
const requestBody = {
|
|
@@ -131,11 +131,11 @@ class GitHubCopilotChatAPI {
|
|
|
131
131
|
catch (error) {
|
|
132
132
|
const isLastAttempt = attempt >= maxRetries + 1;
|
|
133
133
|
const errorObj = error;
|
|
134
|
-
const is403Error = errorObj.status === 403 || ((_a = errorObj.message) === null || _a === void 0 ? void 0 : _a.includes(
|
|
134
|
+
const is403Error = errorObj.status === 403 || ((_a = errorObj.message) === null || _a === void 0 ? void 0 : _a.includes("403"));
|
|
135
135
|
if (is403Error && enableRetry && !isLastAttempt) {
|
|
136
136
|
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 30000);
|
|
137
137
|
console.log(`GitHub Copilot API attempt ${attempt} failed with 403, retrying in ${delay}ms...`);
|
|
138
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
138
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
139
139
|
attempt++;
|
|
140
140
|
continue;
|
|
141
141
|
}
|
|
@@ -143,14 +143,14 @@ class GitHubCopilotChatAPI {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
if (!response) {
|
|
146
|
-
throw new Error(
|
|
146
|
+
throw new Error("Failed to get response from GitHub Copilot API after all retry attempts");
|
|
147
147
|
}
|
|
148
148
|
const result = {
|
|
149
|
-
message: ((_c = (_b = response.choices[0]) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.content) ||
|
|
149
|
+
message: ((_c = (_b = response.choices[0]) === null || _b === void 0 ? void 0 : _b.message) === null || _c === void 0 ? void 0 : _c.content) || "",
|
|
150
150
|
model,
|
|
151
151
|
operation,
|
|
152
152
|
usage: response.usage || null,
|
|
153
|
-
finish_reason: ((_d = response.choices[0]) === null || _d === void 0 ? void 0 : _d.finish_reason) ||
|
|
153
|
+
finish_reason: ((_d = response.choices[0]) === null || _d === void 0 ? void 0 : _d.finish_reason) || "unknown",
|
|
154
154
|
};
|
|
155
155
|
returnData.push({
|
|
156
156
|
json: result,
|
|
@@ -160,12 +160,12 @@ class GitHubCopilotChatAPI {
|
|
|
160
160
|
}
|
|
161
161
|
catch (error) {
|
|
162
162
|
if (this.continueOnFail()) {
|
|
163
|
-
const errorMessage = error instanceof Error ? error.message :
|
|
163
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
164
164
|
returnData.push({
|
|
165
165
|
json: {
|
|
166
166
|
error: errorMessage,
|
|
167
|
-
operation: this.getNodeParameter(
|
|
168
|
-
model: this.getNodeParameter(
|
|
167
|
+
operation: this.getNodeParameter("operation", i),
|
|
168
|
+
model: this.getNodeParameter("model", i),
|
|
169
169
|
},
|
|
170
170
|
pairedItem: { item: i },
|
|
171
171
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { INodeProperties } from
|
|
1
|
+
import { INodeProperties } from "n8n-workflow";
|
|
2
2
|
export declare const nodeProperties: INodeProperties[];
|
|
@@ -4,79 +4,79 @@ exports.nodeProperties = void 0;
|
|
|
4
4
|
const GitHubCopilotModels_1 = require("../../shared/models/GitHubCopilotModels");
|
|
5
5
|
exports.nodeProperties = [
|
|
6
6
|
{
|
|
7
|
-
displayName:
|
|
8
|
-
name:
|
|
9
|
-
type:
|
|
7
|
+
displayName: "Credential Type",
|
|
8
|
+
name: "credentialType",
|
|
9
|
+
type: "options",
|
|
10
10
|
options: [
|
|
11
11
|
{
|
|
12
|
-
name:
|
|
13
|
-
value:
|
|
14
|
-
description:
|
|
12
|
+
name: "GitHub Copilot API (Manual Token)",
|
|
13
|
+
value: "githubCopilotApi",
|
|
14
|
+
description: "Use manual GitHub CLI token",
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
|
-
name:
|
|
18
|
-
value:
|
|
19
|
-
description:
|
|
17
|
+
name: "GitHub Copilot OAuth2 (with Helper)",
|
|
18
|
+
value: "githubCopilotOAuth2Api",
|
|
19
|
+
description: "Use OAuth2 credential with helper script",
|
|
20
20
|
},
|
|
21
21
|
],
|
|
22
|
-
default:
|
|
23
|
-
description:
|
|
22
|
+
default: "githubCopilotApi",
|
|
23
|
+
description: "Type of credential to use for GitHub Copilot authentication",
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
displayName:
|
|
27
|
-
name:
|
|
28
|
-
type:
|
|
26
|
+
displayName: "Operation",
|
|
27
|
+
name: "operation",
|
|
28
|
+
type: "options",
|
|
29
29
|
noDataExpression: true,
|
|
30
30
|
options: [
|
|
31
31
|
{
|
|
32
|
-
name:
|
|
33
|
-
value:
|
|
34
|
-
description:
|
|
32
|
+
name: "Chat Completion",
|
|
33
|
+
value: "chat",
|
|
34
|
+
description: "Send messages to GitHub Copilot Chat API",
|
|
35
35
|
},
|
|
36
36
|
],
|
|
37
|
-
default:
|
|
37
|
+
default: "chat",
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
-
displayName:
|
|
41
|
-
name:
|
|
42
|
-
type:
|
|
40
|
+
displayName: "Model",
|
|
41
|
+
name: "model",
|
|
42
|
+
type: "options",
|
|
43
43
|
options: GitHubCopilotModels_1.GitHubCopilotModelsManager.toN8nOptions(),
|
|
44
44
|
default: GitHubCopilotModels_1.DEFAULT_MODELS.GENERAL,
|
|
45
|
-
description:
|
|
45
|
+
description: "Select the GitHub Copilot model to use",
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
|
-
displayName:
|
|
49
|
-
name:
|
|
50
|
-
type:
|
|
48
|
+
displayName: "Message",
|
|
49
|
+
name: "message",
|
|
50
|
+
type: "string",
|
|
51
51
|
typeOptions: {
|
|
52
52
|
rows: 4,
|
|
53
53
|
},
|
|
54
|
-
default:
|
|
55
|
-
placeholder:
|
|
56
|
-
description:
|
|
54
|
+
default: "",
|
|
55
|
+
placeholder: "What can I help you with?",
|
|
56
|
+
description: "The message to send to the AI model",
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
|
-
displayName:
|
|
60
|
-
name:
|
|
61
|
-
type:
|
|
59
|
+
displayName: "System Message",
|
|
60
|
+
name: "systemMessage",
|
|
61
|
+
type: "string",
|
|
62
62
|
typeOptions: {
|
|
63
63
|
rows: 3,
|
|
64
64
|
},
|
|
65
|
-
default:
|
|
66
|
-
placeholder:
|
|
67
|
-
description:
|
|
65
|
+
default: "",
|
|
66
|
+
placeholder: "You are a helpful assistant...",
|
|
67
|
+
description: "System message to set the behavior of the AI model",
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
|
-
displayName:
|
|
71
|
-
name:
|
|
72
|
-
type:
|
|
70
|
+
displayName: "Include Image",
|
|
71
|
+
name: "includeMedia",
|
|
72
|
+
type: "boolean",
|
|
73
73
|
default: false,
|
|
74
|
-
description:
|
|
74
|
+
description: "Whether to include an image file in the message. Supported formats: PNG, JPEG, GIF, WebP.",
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
|
-
displayName:
|
|
78
|
-
name:
|
|
79
|
-
type:
|
|
77
|
+
displayName: "Image Source",
|
|
78
|
+
name: "mediaSource",
|
|
79
|
+
type: "options",
|
|
80
80
|
displayOptions: {
|
|
81
81
|
show: {
|
|
82
82
|
includeMedia: [true],
|
|
@@ -84,121 +84,121 @@ exports.nodeProperties = [
|
|
|
84
84
|
},
|
|
85
85
|
options: [
|
|
86
86
|
{
|
|
87
|
-
name:
|
|
88
|
-
value:
|
|
89
|
-
description:
|
|
87
|
+
name: "Manual Input",
|
|
88
|
+
value: "manual",
|
|
89
|
+
description: "Provide image as base64 string or file path",
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
|
-
name:
|
|
93
|
-
value:
|
|
94
|
-
description:
|
|
92
|
+
name: "URL",
|
|
93
|
+
value: "url",
|
|
94
|
+
description: "Download image from URL",
|
|
95
95
|
},
|
|
96
96
|
{
|
|
97
|
-
name:
|
|
98
|
-
value:
|
|
99
|
-
description:
|
|
97
|
+
name: "Binary Data",
|
|
98
|
+
value: "binary",
|
|
99
|
+
description: "Use binary data from previous node",
|
|
100
100
|
},
|
|
101
101
|
],
|
|
102
|
-
default:
|
|
103
|
-
description:
|
|
102
|
+
default: "manual",
|
|
103
|
+
description: "Source of the image data",
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
|
-
displayName:
|
|
107
|
-
name:
|
|
108
|
-
type:
|
|
106
|
+
displayName: "Image File",
|
|
107
|
+
name: "mediaFile",
|
|
108
|
+
type: "string",
|
|
109
109
|
displayOptions: {
|
|
110
110
|
show: {
|
|
111
111
|
includeMedia: [true],
|
|
112
|
-
mediaSource: [
|
|
112
|
+
mediaSource: ["manual"],
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
|
-
default:
|
|
116
|
-
placeholder:
|
|
117
|
-
description:
|
|
115
|
+
default: "",
|
|
116
|
+
placeholder: "Paste base64 string or file path",
|
|
117
|
+
description: "Image file as base64 string or file path. Supported formats: PNG, JPEG, GIF, WebP.",
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
|
-
displayName:
|
|
121
|
-
name:
|
|
122
|
-
type:
|
|
120
|
+
displayName: "Image URL",
|
|
121
|
+
name: "mediaUrl",
|
|
122
|
+
type: "string",
|
|
123
123
|
displayOptions: {
|
|
124
124
|
show: {
|
|
125
125
|
includeMedia: [true],
|
|
126
|
-
mediaSource: [
|
|
126
|
+
mediaSource: ["url"],
|
|
127
127
|
},
|
|
128
128
|
},
|
|
129
|
-
default:
|
|
130
|
-
placeholder:
|
|
131
|
-
description:
|
|
129
|
+
default: "",
|
|
130
|
+
placeholder: "https://example.com/image.jpg",
|
|
131
|
+
description: "URL of the image file to download. Supported formats: PNG, JPEG, GIF, WebP.",
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
|
-
displayName:
|
|
135
|
-
name:
|
|
136
|
-
type:
|
|
134
|
+
displayName: "Image Binary Property",
|
|
135
|
+
name: "mediaBinaryProperty",
|
|
136
|
+
type: "string",
|
|
137
137
|
displayOptions: {
|
|
138
138
|
show: {
|
|
139
139
|
includeMedia: [true],
|
|
140
|
-
mediaSource: [
|
|
140
|
+
mediaSource: ["binary"],
|
|
141
141
|
},
|
|
142
142
|
},
|
|
143
|
-
default:
|
|
144
|
-
placeholder:
|
|
145
|
-
description:
|
|
143
|
+
default: "data",
|
|
144
|
+
placeholder: "data",
|
|
145
|
+
description: "Name of the binary property containing the image file",
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
|
-
displayName:
|
|
149
|
-
name:
|
|
150
|
-
type:
|
|
151
|
-
placeholder:
|
|
148
|
+
displayName: "Advanced Options",
|
|
149
|
+
name: "advancedOptions",
|
|
150
|
+
type: "collection",
|
|
151
|
+
placeholder: "Add Field",
|
|
152
152
|
default: {},
|
|
153
153
|
options: [
|
|
154
154
|
{
|
|
155
|
-
displayName:
|
|
156
|
-
name:
|
|
157
|
-
type:
|
|
155
|
+
displayName: "Temperature",
|
|
156
|
+
name: "temperature",
|
|
157
|
+
type: "number",
|
|
158
158
|
typeOptions: {
|
|
159
159
|
minValue: 0,
|
|
160
160
|
maxValue: 2,
|
|
161
161
|
numberPrecision: 2,
|
|
162
162
|
},
|
|
163
163
|
default: 1,
|
|
164
|
-
description:
|
|
164
|
+
description: "Controls randomness of the response. Higher values make output more random.",
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
|
-
displayName:
|
|
168
|
-
name:
|
|
169
|
-
type:
|
|
167
|
+
displayName: "Max Tokens",
|
|
168
|
+
name: "max_tokens",
|
|
169
|
+
type: "number",
|
|
170
170
|
typeOptions: {
|
|
171
171
|
minValue: 1,
|
|
172
172
|
maxValue: 128000,
|
|
173
173
|
},
|
|
174
174
|
default: 4096,
|
|
175
|
-
description:
|
|
175
|
+
description: "Maximum number of tokens to generate in the response",
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
|
-
displayName:
|
|
179
|
-
name:
|
|
180
|
-
type:
|
|
178
|
+
displayName: "Top P",
|
|
179
|
+
name: "top_p",
|
|
180
|
+
type: "number",
|
|
181
181
|
typeOptions: {
|
|
182
182
|
minValue: 0,
|
|
183
183
|
maxValue: 1,
|
|
184
184
|
numberPrecision: 2,
|
|
185
185
|
},
|
|
186
186
|
default: 1,
|
|
187
|
-
description:
|
|
187
|
+
description: "Alternative to temperature, controls diversity via nucleus sampling",
|
|
188
188
|
},
|
|
189
189
|
{
|
|
190
|
-
displayName:
|
|
191
|
-
name:
|
|
192
|
-
type:
|
|
190
|
+
displayName: "Auto Retry on 403 Error",
|
|
191
|
+
name: "enableRetry",
|
|
192
|
+
type: "boolean",
|
|
193
193
|
default: true,
|
|
194
|
-
description:
|
|
194
|
+
description: "Automatically retry requests when hitting TPM (Transactions Per Minute) quota limits (HTTP 403)",
|
|
195
195
|
},
|
|
196
196
|
{
|
|
197
|
-
displayName:
|
|
198
|
-
name:
|
|
199
|
-
type:
|
|
197
|
+
displayName: "Max Retry Attempts",
|
|
198
|
+
name: "maxRetries",
|
|
199
|
+
type: "number",
|
|
200
200
|
default: 3,
|
|
201
|
-
description:
|
|
201
|
+
description: "Maximum number of retry attempts for 403 errors",
|
|
202
202
|
displayOptions: {
|
|
203
203
|
show: {
|
|
204
204
|
enableRetry: [true],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IExecuteFunctions } from
|
|
2
|
-
import { ProcessedFileResult, OptimizationOptions } from
|
|
1
|
+
import { IExecuteFunctions } from "n8n-workflow";
|
|
2
|
+
import { ProcessedFileResult, OptimizationOptions } from "./types";
|
|
3
3
|
export declare function processImageFile(context: IExecuteFunctions, itemIndex: number, imageSource: string, imageFile?: string, imageUrl?: string, imageProperty?: string, optimization?: OptimizationOptions): Promise<ProcessedFileResult>;
|
|
4
4
|
export declare function compressImageToTokenLimit(base64Data: string, maxTokens?: number): string;
|
|
5
5
|
export declare function resizeImageDimensions(originalWidth: number, originalHeight: number, maxWidth?: number, maxHeight?: number): {
|
|
@@ -9,29 +9,30 @@ async function processImageFile(context, itemIndex, imageSource, imageFile, imag
|
|
|
9
9
|
let imageBuffer;
|
|
10
10
|
let filename;
|
|
11
11
|
switch (imageSource) {
|
|
12
|
-
case
|
|
12
|
+
case "file":
|
|
13
13
|
if (!imageFile) {
|
|
14
|
-
throw new Error(
|
|
14
|
+
throw new Error("Image file content is required when source is \"file\"");
|
|
15
15
|
}
|
|
16
|
-
imageBuffer = Buffer.from(imageFile,
|
|
17
|
-
filename =
|
|
16
|
+
imageBuffer = Buffer.from(imageFile, "base64");
|
|
17
|
+
filename = "uploaded_image.jpg";
|
|
18
18
|
break;
|
|
19
|
-
case
|
|
19
|
+
case "url":
|
|
20
20
|
if (!imageUrl) {
|
|
21
|
-
throw new Error(
|
|
21
|
+
throw new Error("Image URL is required when source is \"url\"");
|
|
22
22
|
}
|
|
23
23
|
imageBuffer = await (0, helpers_1.downloadFileFromUrl)(imageUrl);
|
|
24
|
-
filename = imageUrl.split(
|
|
24
|
+
filename = imageUrl.split("/").pop() || "downloaded_image.jpg";
|
|
25
25
|
break;
|
|
26
|
-
case
|
|
26
|
+
case "binary": {
|
|
27
27
|
if (!imageProperty) {
|
|
28
|
-
throw new Error(
|
|
28
|
+
throw new Error("Image property name is required when source is \"binary\"");
|
|
29
29
|
}
|
|
30
30
|
imageBuffer = await (0, helpers_1.getFileFromBinary)(context, itemIndex, imageProperty);
|
|
31
31
|
const items = context.getInputData();
|
|
32
32
|
const item = items[itemIndex];
|
|
33
|
-
filename = ((_b = (_a = item.binary) === null || _a === void 0 ? void 0 : _a[imageProperty]) === null || _b === void 0 ? void 0 : _b.fileName) ||
|
|
33
|
+
filename = ((_b = (_a = item.binary) === null || _a === void 0 ? void 0 : _a[imageProperty]) === null || _b === void 0 ? void 0 : _b.fileName) || "binary_image.jpg";
|
|
34
34
|
break;
|
|
35
|
+
}
|
|
35
36
|
default:
|
|
36
37
|
throw new Error(`Invalid image source: ${imageSource}`);
|
|
37
38
|
}
|
|
@@ -39,14 +40,14 @@ async function processImageFile(context, itemIndex, imageSource, imageFile, imag
|
|
|
39
40
|
imageBuffer = await optimizeImage(imageBuffer, optimization);
|
|
40
41
|
}
|
|
41
42
|
(0, helpers_1.validateFileSize)(imageBuffer, 20480);
|
|
42
|
-
const base64Image = imageBuffer.toString(
|
|
43
|
+
const base64Image = imageBuffer.toString("base64");
|
|
43
44
|
const estimatedTokens = (0, helpers_1.estimateTokens)(base64Image);
|
|
44
45
|
if (estimatedTokens > 50000) {
|
|
45
46
|
const compressedBuffer = await optimizeImage(imageBuffer, {
|
|
46
47
|
quality: 70,
|
|
47
|
-
maxSizeKB: (optimization === null || optimization === void 0 ? void 0 : optimization.maxSizeKB) || 1024
|
|
48
|
+
maxSizeKB: (optimization === null || optimization === void 0 ? void 0 : optimization.maxSizeKB) || 1024,
|
|
48
49
|
});
|
|
49
|
-
const compressedBase64 = compressedBuffer.toString(
|
|
50
|
+
const compressedBase64 = compressedBuffer.toString("base64");
|
|
50
51
|
const compressedTokens = (0, helpers_1.estimateTokens)(compressedBase64);
|
|
51
52
|
if (compressedTokens < estimatedTokens) {
|
|
52
53
|
return {
|
|
@@ -54,7 +55,7 @@ async function processImageFile(context, itemIndex, imageSource, imageFile, imag
|
|
|
54
55
|
mimeType: (0, helpers_1.getImageMimeType)(compressedBuffer),
|
|
55
56
|
filename,
|
|
56
57
|
size: compressedBuffer.length,
|
|
57
|
-
estimatedTokens: compressedTokens
|
|
58
|
+
estimatedTokens: compressedTokens,
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
}
|
|
@@ -64,7 +65,7 @@ async function processImageFile(context, itemIndex, imageSource, imageFile, imag
|
|
|
64
65
|
mimeType,
|
|
65
66
|
filename,
|
|
66
67
|
size: imageBuffer.length,
|
|
67
|
-
estimatedTokens
|
|
68
|
+
estimatedTokens,
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
71
|
async function optimizeImage(buffer, options) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from "./types";
|
|
2
|
+
export * from "./helpers";
|
|
3
|
+
export * from "./imageProcessor";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IExecuteFunctions } from
|
|
2
|
-
export declare function processMediaFile(context: IExecuteFunctions, itemIndex: number, source:
|
|
3
|
-
type:
|
|
1
|
+
import { IExecuteFunctions } from "n8n-workflow";
|
|
2
|
+
export declare function processMediaFile(context: IExecuteFunctions, itemIndex: number, source: "manual" | "url" | "binary", mediaFile?: string, mediaUrl?: string, binaryProperty?: string): Promise<{
|
|
3
|
+
type: "image" | "unknown";
|
|
4
4
|
dataUrl?: string;
|
|
5
5
|
description: string;
|
|
6
6
|
mimeType: string;
|