Skip to content

Commit

Permalink
Proxy support (experimental) (#153)
Browse files Browse the repository at this point in the history
Support using a HTTP(s) proxy. Feature is experimental, and may not be
working for all users currently.

Technical side: Defined a custom `fetch` function that completely
replaces the previous one. All requests now go through this (with the
exception of curl), which allows us to apply the HTTP agent.
  • Loading branch information
XInTheDark authored Nov 18, 2024
1 parent b44d2cc commit 2096077
Show file tree
Hide file tree
Showing 23 changed files with 78 additions and 28 deletions.
7 changes: 2 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,16 @@
"default": "off"
},
{
"name": "smartChatNaming",
"name": "proxyURL",
"title": "Proxy URL (Experimental)",
"description": "Optional. HTTP(s) proxy URL to use for requests.",
"required": false,
"type": "textfield",
"default": ""
},
{
"title": "Features",
"name": "smartChatNaming",
"label": "Enable Smart Chat Naming",
"description": "Automatically rename chat sessions based on the messages you send.",
"required": false,
Expand Down Expand Up @@ -813,6 +821,7 @@
"fetch-to-curl": "^0.6.0",
"g4f-image": "^1.3.3",
"gemini-g4f": "^12.3.10-beta.1",
"http-proxy-agent": "^7.0.2",
"lodash.throttle": "^4.1.1",
"node-fetch": "^3.3.2",
"untruncate-json": "^0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/ai4chat.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

import { format_chat_to_prompt } from "../../classes/message.js";

Expand Down
9 changes: 6 additions & 3 deletions src/api/Providers/blackbox.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { format_chat_to_prompt } from "../../classes/message.js";
import { randomBytes, randomUUID } from "crypto";
import { Storage } from "../storage.js";
Expand Down Expand Up @@ -133,8 +133,11 @@ export const BlackboxProvider = {

// Update 7/11/24: if not validated properly, blackbox now returns an advertisement instead
// of the actual response. if we detect such a message, we attempt to revalidate the token.
if (max_retries > 0 && (chunk.includes("BLACKBOX.AI") || chunk.includes("https://www.blackbox.ai"))) {
await initValidatedToken({ forceUpdate: true });
if (chunk.includes("BLACKBOX.AI") || chunk.includes("https://www.blackbox.ai")) {
if (max_retries > 0 && max_retries <= 3) {
// only retry once
await initValidatedToken({ forceUpdate: true });
}
yield* this.generate(chat, options, { max_retries: max_retries - 3 });
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/darkai.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

import { format_chat_to_prompt } from "../../classes/message.js";

Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/deepinfra.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import fs from "fs";

import { messages_to_json } from "../../classes/message.js";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/deprecated/ecosia.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const EcosiaProvider = "EcosiaProvider";
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { messages_to_json } from "../../../classes/message.js";

const api_url = "https://api.ecosia.org/v2/chat/?sp=productivity";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/deprecated/sambanova.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { messages_to_json } from "../../../classes/message.js";

const api_url = "https://cloud.sambanova.ai/api/completion";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/dev/blackbox/blackbox_engineer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

let puppeteer;

Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/duckduckgo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { format_chat_to_prompt } from "../../classes/message.js";
import { sleep } from "../../helpers/helper.js";

Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/google_gemini.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Gemini, { messageToParts } from "gemini-g4f";
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

import fs from "fs";
import { Preferences } from "../preferences.js";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/metaAI.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { randomUUID } from "crypto";
import { format_chat_to_prompt } from "../../classes/message.js";
import { sleep } from "../../helpers/helper.js";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/mhystical.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { messages_to_json } from "#root/src/classes/message.js";

const api_url = "https://api.mhystical.cc/v1/completions";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/nexra.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { format_chat_to_prompt, messages_to_json } from "../../classes/message.js";
import { sleep } from "#root/src/helpers/helper.js";

Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/pizzagpt.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { format_chat_to_prompt } from "../../classes/message.js";

const url = "https://www.pizzagpt.it";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/replicate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { format_chat_to_prompt } from "../../classes/message.js";

// Implementation ported from gpt4free Replicate provider.
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/rocks.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

const api_url = "https://api.airforce/chat/completions";

Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/special/custom_openai.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getCustomAPIInfo } from "./g4f_local";

import { messages_to_json } from "../../../classes/message.js";
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

const DEFAULT_API_URL = "https://api.openai.com/v1/chat/completions";
const DEFAULT_MODEL = "gpt-4";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/special/g4f_local.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Read more here: https://github.com/xtekky/gpt4free/blob/main/docs/interference.md

import { exec } from "child_process";
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

import { Storage } from "../../storage.js";
import { messages_to_json } from "../../../classes/message.js";
Expand Down
2 changes: 1 addition & 1 deletion src/api/Providers/special/ollama_local.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This module allows communication and requests to the local Ollama API.
// Read more here: https://github.com/ollama/ollama/blob/main/docs/api.md

import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

import { Storage } from "../../storage.js";
import { messages_to_json } from "../../../classes/message.js";
Expand Down
41 changes: 41 additions & 0 deletions src/api/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/// This is the custom fetch function used in this extension.
/// It is a wrapper around the node-fetch library, with added support for proxies.

import default_fetch from "node-fetch";
import { HttpProxyAgent } from "http-proxy-agent";
import { Preferences } from "./preferences.js";

const devMode = Preferences["devMode"] || false;

/**
* Custom fetch function with optional proxy support
* @param {string} url - The URL to fetch
* @param {Object} [options={}] - Fetch options
* @param {string|null} [proxy=null] - Proxy URL
* @returns {Promise<Response>} - Fetch response
*/
async function fetchWithProxy(url, options = {}, proxy = null) {
if (proxy) {
options.agent = new HttpProxyAgent(proxy);
}
if (devMode) {
console.log(`${options.method || "GET"} : ${url}, proxy: ${proxy}`);
}

const response = await default_fetch(url, options);
if (devMode) {
console.log(`response:\n ${response}, status: ${response.status} : ${response.statusText}`);
if (!response.ok) {
console.log(`error: ${await response.text()}`);
}
}

return response;
}

async function fetch(url, options = {}) {
let proxy = Preferences["proxyURL"] || null; // load proxy from preferences
return fetchWithProxy(url, options, proxy);
}

export default fetch;
2 changes: 1 addition & 1 deletion src/genImage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from "@raycast/api";
import { useEffect, useState } from "react";
import fs from "fs";
import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";

import { Storage } from "./api/storage.js";
import { Preferences } from "./api/preferences.js";
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/update.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { version } from "../../package.json";

import fetch from "node-fetch";
import fetch from "#root/src/api/fetch.js";
import { exec } from "child_process";

import { popToRoot, showToast, Toast, confirmAlert, Icon } from "@raycast/api";
Expand Down

0 comments on commit 2096077

Please sign in to comment.