donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
113 lines • 5.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DonobuGptClient = void 0;
const v4_1 = require("zod/v4");
const envVars_1 = require("../envVars");
const GptPlatformAuthenticationFailedException_1 = require("../exceptions/GptPlatformAuthenticationFailedException");
const GptPlatformInsufficientQuotaException_1 = require("../exceptions/GptPlatformInsufficientQuotaException");
const GptPlatformInternalErrorException_1 = require("../exceptions/GptPlatformInternalErrorException");
const GptPlatformNotReachableException_1 = require("../exceptions/GptPlatformNotReachableException");
const GoogleGenerativeAiGptClient_1 = require("./GoogleGenerativeAiGptClient");
const GptClient_1 = require("./GptClient");
const OpenAiGptClient_1 = require("./OpenAiGptClient");
/**
* A GPT client implemented using the Donobu API.
*/
class DonobuGptClient extends GptClient_1.GptClient {
constructor(donobuGptClientConfig, apiUrl = envVars_1.env.data.DONOBU_API_BASE_URL) {
super(donobuGptClientConfig);
this.apiUrl = apiUrl;
this.delegate = new OpenAiGptClient_1.OpenAiGptClient({
type: 'OPENAI',
modelName: '',
apiKey: donobuGptClientConfig.apiKey,
}, apiUrl);
}
async ping(options) {
const donobuConfig = this.config;
const resp = await fetch(`${this.apiUrl}/v1/flows?limit=1`, {
method: 'GET',
headers: { Authorization: `Bearer ${donobuConfig.apiKey}` },
signal: options?.signal,
});
if (resp.status === 401) {
throw new GptPlatformAuthenticationFailedException_1.GptPlatformAuthenticationFailedException(this.config.type);
}
// 402 Payment Required = the key is valid, but the account has no
// wallet / no credits. The credential itself authenticated fine, so
// accept the config — the user just can't run flows until they top up
// (Studio surfaces a "0 credits remaining" nudge). Rejecting here would
// block the managed donobu gpt-config from ever being created.
if (resp.status === 402) {
return;
}
if (!resp.ok) {
throw new Error(`Donobu API ping failed with status ${resp.status}: ${await resp.text()}`);
}
}
async getMessage(messages, options) {
return this.rethrowWithCorrectPlatform(() => this.delegate.getMessage(messages, options));
}
async getStructuredOutput(messages, zodSchema, options) {
// The Donobu API proxy is not reliable when using traditional structured outputs,
// so we work around it by faking it as a tool call.
const resp = await this.getToolCalls(messages, [
{
name: 'output',
description: 'The schema of the expected response structure.',
inputSchema: zodSchema,
},
], options);
const toolCall = resp.proposedToolCalls.at(0);
return {
completionTokensUsed: resp.completionTokensUsed,
promptTokensUsed: resp.promptTokensUsed,
type: 'structured_output',
output: (0, GptClient_1.parseOrLogAndThrow)(toolCall?.parameters, zodSchema),
};
}
async getToolCalls(messages, tools, options) {
const preprocessedTools = tools.map((tool) => ({
name: tool.name,
description: tool.description,
inputSchema: v4_1.z.preprocess((data) => {
(0, GoogleGenerativeAiGptClient_1.fixAssertFields)(data);
return data;
}, tool.inputSchema),
}));
const resp = await this.rethrowWithCorrectPlatform(() => this.delegate.getToolCalls(messages, preprocessedTools, options));
resp.proposedToolCalls.forEach((t) => {
(0, GoogleGenerativeAiGptClient_1.fixAssertFields)(t.parameters);
});
return resp;
}
/**
* The delegate {@link OpenAiGptClient} stamps exceptions with platform
* `'OPENAI'`. This wrapper re-throws them with the actual platform type
* (e.g. `'DONOBU'`) so that user-facing messages reference the correct
* provider.
*/
async rethrowWithCorrectPlatform(fn) {
try {
return await fn();
}
catch (error) {
const platform = this.config.type;
if (error instanceof GptPlatformInsufficientQuotaException_1.GptPlatformInsufficientQuotaException) {
throw new GptPlatformInsufficientQuotaException_1.GptPlatformInsufficientQuotaException(platform);
}
else if (error instanceof GptPlatformAuthenticationFailedException_1.GptPlatformAuthenticationFailedException) {
throw new GptPlatformAuthenticationFailedException_1.GptPlatformAuthenticationFailedException(platform);
}
else if (error instanceof GptPlatformNotReachableException_1.GptPlatformNotReachableException) {
throw new GptPlatformNotReachableException_1.GptPlatformNotReachableException(platform);
}
else if (error instanceof GptPlatformInternalErrorException_1.GptPlatformInternalErrorException) {
throw new GptPlatformInternalErrorException_1.GptPlatformInternalErrorException(error.message.replace(/OPENAI/g, platform));
}
throw error;
}
}
}
exports.DonobuGptClient = DonobuGptClient;
//# sourceMappingURL=DonobuGptClient.js.map