Error in : API request failed
arihantJ24 opened this issue · 9 comments
arihantJ24 commented
i am getting this issue . can anyone help me with this
[llm/error] [1:llm:replicate] [101.13s] LLM run errored with error: "API request failed: Payment Required"
Error: API request failed: Payment Required
at Replicate.request (webpack-internal:///(rsc)/./node_modules/replicate/index.js:144:13)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Replicate.createPrediction (webpack-internal:///(rsc)/./node_modules/replicate/lib/predictions.js:24:22)
at async Replicate.run (webpack-internal:///(rsc)/./node_modules/replicate/index.js:93:24)
at async RetryOperation.eval [as _fn] (webpack-internal:///(rsc)/./node_modules/p-retry/index.js:50:12) {
attemptNumber: 7,
retriesLeft: 0
}
this is my node_modules/replicate/index.js:144:13) file
const collections = require('./lib/collections');
const models = require('./lib/models');
const predictions = require('./lib/predictions');
const trainings = require('./lib/trainings');
const packageJSON = require('./package.json');
/**
* Replicate API client library
*
* @see https://replicate.com/docs/reference/http
* @example
* // Create a new Replicate API client instance
* const Replicate = require("replicate");
* const replicate = new Replicate({
* // get your token from https://replicate.com/account
* auth: process.env.REPLICATE_API_TOKEN,
* userAgent: "my-app/1.2.3"
* });
*
* // Run a model and await the result:
* const model = 'owner/model:version-id'
* const input = {text: 'Hello, world!'}
* const output = await replicate.run(model, { input });
*/
class Replicate {
/**
* Create a new Replicate API client instance.
*
* @param {object} options - Configuration options for the client
* @param {string} options.auth - Required. API access token
* @param {string} options.userAgent - Identifier of your app
* @param {string} [options.baseUrl] - Defaults to https://api.replicate.com/v1
* @param {Function} [options.fetch] - Defaults to native fetch
*/
constructor(options) {
this.auth = options.auth;
this.userAgent =
options.userAgent || `replicate-javascript/${packageJSON.version}`;
this.baseUrl = options.baseUrl || 'https://api.replicate.com/v1';
this.fetch = options.fetch || fetch;
this.collections = {
get: collections.get.bind(this),
};
this.models = {
get: models.get.bind(this),
versions: {
list: models.versions.list.bind(this),
get: models.versions.get.bind(this),
},
};
this.predictions = {
create: predictions.create.bind(this),
get: predictions.get.bind(this),
list: predictions.list.bind(this),
};
this.trainings = {
create: trainings.create.bind(this),
get: trainings.get.bind(this),
cancel: trainings.cancel.bind(this),
};
}
/**
* Run a model and wait for its output.
*
* @param {string} identifier - Required. The model version identifier in the format "{owner}/{name}:{version}"
* @param {object} options
* @param {object} options.input - Required. An object with the model inputs
* @param {object} [options.wait] - Whether to wait for the prediction to finish. Defaults to false
* @param {number} [options.wait.interval] - Polling interval in milliseconds. Defaults to 250
* @param {number} [options.wait.maxAttempts] - Maximum number of polling attempts. Defaults to no limit
* @param {string} [options.webhook] - An HTTPS URL for receiving a webhook when the prediction has new output
* @param {string[]} [options.webhook_events_filter] - You can change which events trigger webhook requests by specifying webhook events (`start`|`output`|`logs`|`completed`)
* @throws {Error} If the prediction failed
* @returns {Promise<object>} - Resolves with the output of running the model
*/
async run(identifier, options) {
const pattern =
/^(?<owner>[a-zA-Z0-9-_]+?)\/(?<name>[a-zA-Z0-9-_]+?):(?<version>[0-9a-fA-F]+)$/;
const match = identifier.match(pattern);
if (!match || !match.groups) {
throw new Error(
'Invalid version. It must be in the format "owner/name:version"'
);
}
const { version } = match.groups;
const prediction = await this.predictions.create({
wait: true,
...options,
version,
});
if (prediction.status === 'failed') {
throw new Error(`Prediction failed: ${prediction.error}`);
}
return prediction.output;
}
/**
* Make a request to the Replicate API.
*
* @param {string} route - REST API endpoint path
* @param {object} parameters - Request parameters
* @param {string} [parameters.method] - HTTP method. Defaults to GET
* @param {object} [parameters.params] - Query parameters
* @param {object} [parameters.data] - Body parameters
* @returns {Promise<object>} - Resolves with the API response data
* @throws {Error} If the request failed
*/
async request(route, parameters) {
const { auth, baseUrl, userAgent } = this;
const url = new URL(
route.startsWith('/') ? route.slice(1) : route,
baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`
);
const { method = 'GET', params = {}, data } = parameters;
Object.entries(params).forEach(([key, value]) => {
url.searchParams.append(key, value);
});
const headers = {
Authorization: `Token ${auth}`,
'Content-Type': 'application/json',
'User-Agent': userAgent,
};
const response = await this.fetch(url, {
method,
headers,
body: data ? JSON.stringify(data) : undefined,
});
if (!response.ok) {
throw new Error(`API request failed: ${response.statusText}`);
}
return response.json();
}
/**
* Paginate through a list of results.
*
* @generator
* @example
* for await (const page of replicate.paginate(replicate.predictions.list) {
* console.log(page);
* }
* @param {Function} endpoint - Function that returns a promise for the next page of results
* @yields {object[]} Each page of results
*/
async *paginate(endpoint) {
const response = await endpoint();
yield response.results;
if (response.next) {
const nextPage = () => this.request(response.next, { method: 'GET' });
yield* this.paginate(nextPage);
}
}
/**
* Wait for a prediction to finish.
*
* If the prediction has already finished,
* this function returns immediately.
* Otherwise, it polls the API until the prediction finishes.
*
* @async
* @param {object} prediction - Prediction object
* @param {object} options - Options
* @param {number} [options.interval] - Polling interval in milliseconds. Defaults to 250
* @param {number} [options.maxAttempts] - Maximum number of polling attempts. Defaults to no limit
* @throws {Error} If the prediction doesn't complete within the maximum number of attempts
* @throws {Error} If the prediction failed
* @returns {Promise<object>} Resolves with the completed prediction object
*/
async wait(prediction, options) {
const { id } = prediction;
if (!id) {
throw new Error('Invalid prediction');
}
if (
prediction.status === 'succeeded' ||
prediction.status === 'failed' ||
prediction.status === 'canceled'
) {
return prediction;
}
let updatedPrediction = await this.predictions.get(id);
// eslint-disable-next-line no-promise-executor-return
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let attempts = 0;
const interval = options.interval || 250;
const maxAttempts = options.maxAttempts || null;
while (
updatedPrediction.status !== 'succeeded' &&
updatedPrediction.status !== 'failed' &&
updatedPrediction.status !== 'canceled'
) {
attempts += 1;
if (maxAttempts && attempts > maxAttempts) {
throw new Error(
`Prediction ${id} did not finish after ${maxAttempts} attempts`
);
}
/* eslint-disable no-await-in-loop */
await sleep(interval);
updatedPrediction = await this.predictions.get(prediction.id);
/* eslint-enable no-await-in-loop */
}
if (updatedPrediction.status === 'failed') {
throw new Error(`Prediction failed: ${updatedPrediction.error}`);
}
return updatedPrediction;
}
}
module.exports = Replicate;
this is my replicate/lib/predictions.js file
/**
* Create a new prediction
*
* @param {object} options
* @param {string} options.version - Required. The model version
* @param {object} options.input - Required. An object with the model inputs
* @param {object} [options.wait] - Whether to wait for the prediction to finish. Defaults to false
* @param {number} [options.wait.interval] - Polling interval in milliseconds. Defaults to 250
* @param {number} [options.wait.maxAttempts] - Maximum number of polling attempts. Defaults to no limit
* @param {string} [options.webhook] - An HTTPS URL for receiving a webhook when the prediction has new output
* @param {string[]} [options.webhook_events_filter] - You can change which events trigger webhook requests by specifying webhook events (`start`|`output`|`logs`|`completed`)
* @returns {Promise<object>} Resolves with the created prediction data
*/
async function createPrediction(options) {
const { wait, ...data } = options;
const prediction = this.request('/predictions', {
method: 'POST',
data,
});
if (wait) {
const { maxAttempts, interval } = wait;
return this.wait(await prediction, { maxAttempts, interval });
}
return prediction;
}
/**
* Fetch a prediction by ID
*
* @param {number} prediction_id - Required. The prediction ID
* @returns {Promise<object>} Resolves with the prediction data
*/
async function getPrediction(prediction_id) {
return this.request(`/predictions/${prediction_id}`, {
method: 'GET',
});
}
/**
* List all predictions
*
* @returns {Promise<object>} - Resolves with a page of predictions
*/
async function listPredictions() {
return this.request('/predictions', {
method: 'GET',
});
}
module.exports = {
create: createPrediction,
get: getPrediction,
list: listPredictions,
};
this is p-retry/index.js file
'use strict';
const retry = require('retry');
const networkErrorMsgs = [
'Failed to fetch', // Chrome
'NetworkError when attempting to fetch resource.', // Firefox
'The Internet connection appears to be offline.', // Safari
'Network request failed' // `cross-fetch`
];
class AbortError extends Error {
constructor(message) {
super();
if (message instanceof Error) {
this.originalError = message;
({message} = message);
} else {
this.originalError = new Error(message);
this.originalError.stack = this.stack;
}
this.name = 'AbortError';
this.message = message;
}
}
const decorateErrorWithCounts = (error, attemptNumber, options) => {
// Minus 1 from attemptNumber because the first attempt does not count as a retry
const retriesLeft = options.retries - (attemptNumber - 1);
error.attemptNumber = attemptNumber;
error.retriesLeft = retriesLeft;
return error;
};
const isNetworkError = errorMessage => networkErrorMsgs.includes(errorMessage);
const pRetry = (input, options) => new Promise((resolve, reject) => {
options = {
onFailedAttempt: () => {},
retries: 10,
...options
};
const operation = retry.operation(options);
operation.attempt(async attemptNumber => {
try {
resolve(await input(attemptNumber));
} catch (error) {
if (!(error instanceof Error)) {
reject(new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`));
return;
}
if (error instanceof AbortError) {
operation.stop();
reject(error.originalError);
} else if (error instanceof TypeError && !isNetworkError(error.message)) {
operation.stop();
reject(error);
} else {
decorateErrorWithCounts(error, attemptNumber, options);
try {
await options.onFailedAttempt(error);
} catch (error) {
reject(error);
return;
}
if (!operation.retry(error)) {
reject(operation.mainError());
}
}
}
});
});
module.exports = pRetry;
// TODO: remove this in the next major version
module.exports.default = pRetry;
module.exports.AbortError = AbortError;
mattt commented
Hi @arihantJ24. From the first line of your error message, "API request failed: Payment Required" suggests that your account has hit your free usage limit. Or else, the payment method you provided was unable to be charged. To solve this, please go to https://replicate.com/account/billing and provide your payment details.