Files
2026-07-23 20:36:13 +08:00

7461 lines
286 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// main.ts
var main_exports = {};
__export(main_exports, {
default: () => MemosSyncPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian6 = require("obsidian");
// src/models/settings.ts
var DEFAULT_SETTINGS = {
memosApiUrl: "",
memosAccessToken: "",
syncDirectory: "memos",
syncFrequency: "manual",
autoSyncInterval: 30,
syncLimit: 1e3,
ai: {
enabled: false,
modelType: "openai",
apiKey: "",
modelName: "gpt-4o",
customModelName: "",
openaiBaseUrl: "https://api.openai.com/v1",
ollamaBaseUrl: "http://localhost:11434",
weeklyDigest: true,
autoTags: true,
intelligentSummary: true,
summaryLanguage: "zh"
}
};
// src/ui/settings-tab.ts
var import_obsidian2 = require("obsidian");
// node_modules/@google/generative-ai/dist/index.mjs
var SchemaType;
(function(SchemaType2) {
SchemaType2["STRING"] = "string";
SchemaType2["NUMBER"] = "number";
SchemaType2["INTEGER"] = "integer";
SchemaType2["BOOLEAN"] = "boolean";
SchemaType2["ARRAY"] = "array";
SchemaType2["OBJECT"] = "object";
})(SchemaType || (SchemaType = {}));
var ExecutableCodeLanguage;
(function(ExecutableCodeLanguage2) {
ExecutableCodeLanguage2["LANGUAGE_UNSPECIFIED"] = "language_unspecified";
ExecutableCodeLanguage2["PYTHON"] = "python";
})(ExecutableCodeLanguage || (ExecutableCodeLanguage = {}));
var Outcome;
(function(Outcome2) {
Outcome2["OUTCOME_UNSPECIFIED"] = "outcome_unspecified";
Outcome2["OUTCOME_OK"] = "outcome_ok";
Outcome2["OUTCOME_FAILED"] = "outcome_failed";
Outcome2["OUTCOME_DEADLINE_EXCEEDED"] = "outcome_deadline_exceeded";
})(Outcome || (Outcome = {}));
var POSSIBLE_ROLES = ["user", "model", "function", "system"];
var HarmCategory;
(function(HarmCategory2) {
HarmCategory2["HARM_CATEGORY_UNSPECIFIED"] = "HARM_CATEGORY_UNSPECIFIED";
HarmCategory2["HARM_CATEGORY_HATE_SPEECH"] = "HARM_CATEGORY_HATE_SPEECH";
HarmCategory2["HARM_CATEGORY_SEXUALLY_EXPLICIT"] = "HARM_CATEGORY_SEXUALLY_EXPLICIT";
HarmCategory2["HARM_CATEGORY_HARASSMENT"] = "HARM_CATEGORY_HARASSMENT";
HarmCategory2["HARM_CATEGORY_DANGEROUS_CONTENT"] = "HARM_CATEGORY_DANGEROUS_CONTENT";
})(HarmCategory || (HarmCategory = {}));
var HarmBlockThreshold;
(function(HarmBlockThreshold2) {
HarmBlockThreshold2["HARM_BLOCK_THRESHOLD_UNSPECIFIED"] = "HARM_BLOCK_THRESHOLD_UNSPECIFIED";
HarmBlockThreshold2["BLOCK_LOW_AND_ABOVE"] = "BLOCK_LOW_AND_ABOVE";
HarmBlockThreshold2["BLOCK_MEDIUM_AND_ABOVE"] = "BLOCK_MEDIUM_AND_ABOVE";
HarmBlockThreshold2["BLOCK_ONLY_HIGH"] = "BLOCK_ONLY_HIGH";
HarmBlockThreshold2["BLOCK_NONE"] = "BLOCK_NONE";
})(HarmBlockThreshold || (HarmBlockThreshold = {}));
var HarmProbability;
(function(HarmProbability2) {
HarmProbability2["HARM_PROBABILITY_UNSPECIFIED"] = "HARM_PROBABILITY_UNSPECIFIED";
HarmProbability2["NEGLIGIBLE"] = "NEGLIGIBLE";
HarmProbability2["LOW"] = "LOW";
HarmProbability2["MEDIUM"] = "MEDIUM";
HarmProbability2["HIGH"] = "HIGH";
})(HarmProbability || (HarmProbability = {}));
var BlockReason;
(function(BlockReason2) {
BlockReason2["BLOCKED_REASON_UNSPECIFIED"] = "BLOCKED_REASON_UNSPECIFIED";
BlockReason2["SAFETY"] = "SAFETY";
BlockReason2["OTHER"] = "OTHER";
})(BlockReason || (BlockReason = {}));
var FinishReason;
(function(FinishReason2) {
FinishReason2["FINISH_REASON_UNSPECIFIED"] = "FINISH_REASON_UNSPECIFIED";
FinishReason2["STOP"] = "STOP";
FinishReason2["MAX_TOKENS"] = "MAX_TOKENS";
FinishReason2["SAFETY"] = "SAFETY";
FinishReason2["RECITATION"] = "RECITATION";
FinishReason2["LANGUAGE"] = "LANGUAGE";
FinishReason2["OTHER"] = "OTHER";
})(FinishReason || (FinishReason = {}));
var TaskType;
(function(TaskType2) {
TaskType2["TASK_TYPE_UNSPECIFIED"] = "TASK_TYPE_UNSPECIFIED";
TaskType2["RETRIEVAL_QUERY"] = "RETRIEVAL_QUERY";
TaskType2["RETRIEVAL_DOCUMENT"] = "RETRIEVAL_DOCUMENT";
TaskType2["SEMANTIC_SIMILARITY"] = "SEMANTIC_SIMILARITY";
TaskType2["CLASSIFICATION"] = "CLASSIFICATION";
TaskType2["CLUSTERING"] = "CLUSTERING";
})(TaskType || (TaskType = {}));
var FunctionCallingMode;
(function(FunctionCallingMode2) {
FunctionCallingMode2["MODE_UNSPECIFIED"] = "MODE_UNSPECIFIED";
FunctionCallingMode2["AUTO"] = "AUTO";
FunctionCallingMode2["ANY"] = "ANY";
FunctionCallingMode2["NONE"] = "NONE";
})(FunctionCallingMode || (FunctionCallingMode = {}));
var DynamicRetrievalMode;
(function(DynamicRetrievalMode2) {
DynamicRetrievalMode2["MODE_UNSPECIFIED"] = "MODE_UNSPECIFIED";
DynamicRetrievalMode2["MODE_DYNAMIC"] = "MODE_DYNAMIC";
})(DynamicRetrievalMode || (DynamicRetrievalMode = {}));
var GoogleGenerativeAIError = class extends Error {
constructor(message) {
super(`[GoogleGenerativeAI Error]: ${message}`);
}
};
var GoogleGenerativeAIResponseError = class extends GoogleGenerativeAIError {
constructor(message, response) {
super(message);
this.response = response;
}
};
var GoogleGenerativeAIFetchError = class extends GoogleGenerativeAIError {
constructor(message, status, statusText, errorDetails) {
super(message);
this.status = status;
this.statusText = statusText;
this.errorDetails = errorDetails;
}
};
var GoogleGenerativeAIRequestInputError = class extends GoogleGenerativeAIError {
};
var DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com";
var DEFAULT_API_VERSION = "v1beta";
var PACKAGE_VERSION = "0.21.0";
var PACKAGE_LOG_HEADER = "genai-js";
var Task;
(function(Task2) {
Task2["GENERATE_CONTENT"] = "generateContent";
Task2["STREAM_GENERATE_CONTENT"] = "streamGenerateContent";
Task2["COUNT_TOKENS"] = "countTokens";
Task2["EMBED_CONTENT"] = "embedContent";
Task2["BATCH_EMBED_CONTENTS"] = "batchEmbedContents";
})(Task || (Task = {}));
var RequestUrl = class {
constructor(model, task, apiKey, stream, requestOptions) {
this.model = model;
this.task = task;
this.apiKey = apiKey;
this.stream = stream;
this.requestOptions = requestOptions;
}
toString() {
var _a2, _b;
const apiVersion = ((_a2 = this.requestOptions) === null || _a2 === void 0 ? void 0 : _a2.apiVersion) || DEFAULT_API_VERSION;
const baseUrl = ((_b = this.requestOptions) === null || _b === void 0 ? void 0 : _b.baseUrl) || DEFAULT_BASE_URL;
let url = `${baseUrl}/${apiVersion}/${this.model}:${this.task}`;
if (this.stream) {
url += "?alt=sse";
}
return url;
}
};
function getClientHeaders(requestOptions) {
const clientHeaders = [];
if (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.apiClient) {
clientHeaders.push(requestOptions.apiClient);
}
clientHeaders.push(`${PACKAGE_LOG_HEADER}/${PACKAGE_VERSION}`);
return clientHeaders.join(" ");
}
async function getHeaders(url) {
var _a2;
const headers = new Headers();
headers.append("Content-Type", "application/json");
headers.append("x-goog-api-client", getClientHeaders(url.requestOptions));
headers.append("x-goog-api-key", url.apiKey);
let customHeaders = (_a2 = url.requestOptions) === null || _a2 === void 0 ? void 0 : _a2.customHeaders;
if (customHeaders) {
if (!(customHeaders instanceof Headers)) {
try {
customHeaders = new Headers(customHeaders);
} catch (e) {
throw new GoogleGenerativeAIRequestInputError(`unable to convert customHeaders value ${JSON.stringify(customHeaders)} to Headers: ${e.message}`);
}
}
for (const [headerName, headerValue] of customHeaders.entries()) {
if (headerName === "x-goog-api-key") {
throw new GoogleGenerativeAIRequestInputError(`Cannot set reserved header name ${headerName}`);
} else if (headerName === "x-goog-api-client") {
throw new GoogleGenerativeAIRequestInputError(`Header name ${headerName} can only be set using the apiClient field`);
}
headers.append(headerName, headerValue);
}
}
return headers;
}
async function constructModelRequest(model, task, apiKey, stream, body, requestOptions) {
const url = new RequestUrl(model, task, apiKey, stream, requestOptions);
return {
url: url.toString(),
fetchOptions: Object.assign(Object.assign({}, buildFetchOptions(requestOptions)), { method: "POST", headers: await getHeaders(url), body })
};
}
async function makeModelRequest(model, task, apiKey, stream, body, requestOptions = {}, fetchFn = fetch) {
const { url, fetchOptions } = await constructModelRequest(model, task, apiKey, stream, body, requestOptions);
return makeRequest(url, fetchOptions, fetchFn);
}
async function makeRequest(url, fetchOptions, fetchFn = fetch) {
let response;
try {
response = await fetchFn(url, fetchOptions);
} catch (e) {
handleResponseError(e, url);
}
if (!response.ok) {
await handleResponseNotOk(response, url);
}
return response;
}
function handleResponseError(e, url) {
let err = e;
if (!(e instanceof GoogleGenerativeAIFetchError || e instanceof GoogleGenerativeAIRequestInputError)) {
err = new GoogleGenerativeAIError(`Error fetching from ${url.toString()}: ${e.message}`);
err.stack = e.stack;
}
throw err;
}
async function handleResponseNotOk(response, url) {
let message = "";
let errorDetails;
try {
const json = await response.json();
message = json.error.message;
if (json.error.details) {
message += ` ${JSON.stringify(json.error.details)}`;
errorDetails = json.error.details;
}
} catch (e) {
}
throw new GoogleGenerativeAIFetchError(`Error fetching from ${url.toString()}: [${response.status} ${response.statusText}] ${message}`, response.status, response.statusText, errorDetails);
}
function buildFetchOptions(requestOptions) {
const fetchOptions = {};
if ((requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.signal) !== void 0 || (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeout) >= 0) {
const controller = new AbortController();
if ((requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.timeout) >= 0) {
setTimeout(() => controller.abort(), requestOptions.timeout);
}
if (requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.signal) {
requestOptions.signal.addEventListener("abort", () => {
controller.abort();
});
}
fetchOptions.signal = controller.signal;
}
return fetchOptions;
}
function addHelpers(response) {
response.text = () => {
if (response.candidates && response.candidates.length > 0) {
if (response.candidates.length > 1) {
console.warn(`This response had ${response.candidates.length} candidates. Returning text from the first candidate only. Access response.candidates directly to use the other candidates.`);
}
if (hadBadFinishReason(response.candidates[0])) {
throw new GoogleGenerativeAIResponseError(`${formatBlockErrorMessage(response)}`, response);
}
return getText(response);
} else if (response.promptFeedback) {
throw new GoogleGenerativeAIResponseError(`Text not available. ${formatBlockErrorMessage(response)}`, response);
}
return "";
};
response.functionCall = () => {
if (response.candidates && response.candidates.length > 0) {
if (response.candidates.length > 1) {
console.warn(`This response had ${response.candidates.length} candidates. Returning function calls from the first candidate only. Access response.candidates directly to use the other candidates.`);
}
if (hadBadFinishReason(response.candidates[0])) {
throw new GoogleGenerativeAIResponseError(`${formatBlockErrorMessage(response)}`, response);
}
console.warn(`response.functionCall() is deprecated. Use response.functionCalls() instead.`);
return getFunctionCalls(response)[0];
} else if (response.promptFeedback) {
throw new GoogleGenerativeAIResponseError(`Function call not available. ${formatBlockErrorMessage(response)}`, response);
}
return void 0;
};
response.functionCalls = () => {
if (response.candidates && response.candidates.length > 0) {
if (response.candidates.length > 1) {
console.warn(`This response had ${response.candidates.length} candidates. Returning function calls from the first candidate only. Access response.candidates directly to use the other candidates.`);
}
if (hadBadFinishReason(response.candidates[0])) {
throw new GoogleGenerativeAIResponseError(`${formatBlockErrorMessage(response)}`, response);
}
return getFunctionCalls(response);
} else if (response.promptFeedback) {
throw new GoogleGenerativeAIResponseError(`Function call not available. ${formatBlockErrorMessage(response)}`, response);
}
return void 0;
};
return response;
}
function getText(response) {
var _a2, _b, _c, _d;
const textStrings = [];
if ((_b = (_a2 = response.candidates) === null || _a2 === void 0 ? void 0 : _a2[0].content) === null || _b === void 0 ? void 0 : _b.parts) {
for (const part of (_d = (_c = response.candidates) === null || _c === void 0 ? void 0 : _c[0].content) === null || _d === void 0 ? void 0 : _d.parts) {
if (part.text) {
textStrings.push(part.text);
}
if (part.executableCode) {
textStrings.push("\n```" + part.executableCode.language + "\n" + part.executableCode.code + "\n```\n");
}
if (part.codeExecutionResult) {
textStrings.push("\n```\n" + part.codeExecutionResult.output + "\n```\n");
}
}
}
if (textStrings.length > 0) {
return textStrings.join("");
} else {
return "";
}
}
function getFunctionCalls(response) {
var _a2, _b, _c, _d;
const functionCalls = [];
if ((_b = (_a2 = response.candidates) === null || _a2 === void 0 ? void 0 : _a2[0].content) === null || _b === void 0 ? void 0 : _b.parts) {
for (const part of (_d = (_c = response.candidates) === null || _c === void 0 ? void 0 : _c[0].content) === null || _d === void 0 ? void 0 : _d.parts) {
if (part.functionCall) {
functionCalls.push(part.functionCall);
}
}
}
if (functionCalls.length > 0) {
return functionCalls;
} else {
return void 0;
}
}
var badFinishReasons = [
FinishReason.RECITATION,
FinishReason.SAFETY,
FinishReason.LANGUAGE
];
function hadBadFinishReason(candidate) {
return !!candidate.finishReason && badFinishReasons.includes(candidate.finishReason);
}
function formatBlockErrorMessage(response) {
var _a2, _b, _c;
let message = "";
if ((!response.candidates || response.candidates.length === 0) && response.promptFeedback) {
message += "Response was blocked";
if ((_a2 = response.promptFeedback) === null || _a2 === void 0 ? void 0 : _a2.blockReason) {
message += ` due to ${response.promptFeedback.blockReason}`;
}
if ((_b = response.promptFeedback) === null || _b === void 0 ? void 0 : _b.blockReasonMessage) {
message += `: ${response.promptFeedback.blockReasonMessage}`;
}
} else if ((_c = response.candidates) === null || _c === void 0 ? void 0 : _c[0]) {
const firstCandidate = response.candidates[0];
if (hadBadFinishReason(firstCandidate)) {
message += `Candidate was blocked due to ${firstCandidate.finishReason}`;
if (firstCandidate.finishMessage) {
message += `: ${firstCandidate.finishMessage}`;
}
}
}
return message;
}
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
return this;
}, i;
function verb(n) {
if (g[n])
i[n] = function(v) {
return new Promise(function(a, b) {
q.push([n, v, a, b]) > 1 || resume(n, v);
});
};
}
function resume(n, v) {
try {
step(g[n](v));
} catch (e) {
settle(q[0][3], e);
}
}
function step(r) {
r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
}
function fulfill(value) {
resume("next", value);
}
function reject(value) {
resume("throw", value);
}
function settle(f, v) {
if (f(v), q.shift(), q.length)
resume(q[0][0], q[0][1]);
}
}
var responseLineRE = /^data\: (.*)(?:\n\n|\r\r|\r\n\r\n)/;
function processStream(response) {
const inputStream = response.body.pipeThrough(new TextDecoderStream("utf8", { fatal: true }));
const responseStream = getResponseStream(inputStream);
const [stream1, stream2] = responseStream.tee();
return {
stream: generateResponseSequence(stream1),
response: getResponsePromise(stream2)
};
}
async function getResponsePromise(stream) {
const allResponses = [];
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
return addHelpers(aggregateResponses(allResponses));
}
allResponses.push(value);
}
}
function generateResponseSequence(stream) {
return __asyncGenerator(this, arguments, function* generateResponseSequence_1() {
const reader = stream.getReader();
while (true) {
const { value, done } = yield __await(reader.read());
if (done) {
break;
}
yield yield __await(addHelpers(value));
}
});
}
function getResponseStream(inputStream) {
const reader = inputStream.getReader();
const stream = new ReadableStream({
start(controller) {
let currentText = "";
return pump();
function pump() {
return reader.read().then(({ value, done }) => {
if (done) {
if (currentText.trim()) {
controller.error(new GoogleGenerativeAIError("Failed to parse stream"));
return;
}
controller.close();
return;
}
currentText += value;
let match = currentText.match(responseLineRE);
let parsedResponse;
while (match) {
try {
parsedResponse = JSON.parse(match[1]);
} catch (e) {
controller.error(new GoogleGenerativeAIError(`Error parsing JSON response: "${match[1]}"`));
return;
}
controller.enqueue(parsedResponse);
currentText = currentText.substring(match[0].length);
match = currentText.match(responseLineRE);
}
return pump();
});
}
}
});
return stream;
}
function aggregateResponses(responses) {
const lastResponse = responses[responses.length - 1];
const aggregatedResponse = {
promptFeedback: lastResponse === null || lastResponse === void 0 ? void 0 : lastResponse.promptFeedback
};
for (const response of responses) {
if (response.candidates) {
for (const candidate of response.candidates) {
const i = candidate.index;
if (!aggregatedResponse.candidates) {
aggregatedResponse.candidates = [];
}
if (!aggregatedResponse.candidates[i]) {
aggregatedResponse.candidates[i] = {
index: candidate.index
};
}
aggregatedResponse.candidates[i].citationMetadata = candidate.citationMetadata;
aggregatedResponse.candidates[i].groundingMetadata = candidate.groundingMetadata;
aggregatedResponse.candidates[i].finishReason = candidate.finishReason;
aggregatedResponse.candidates[i].finishMessage = candidate.finishMessage;
aggregatedResponse.candidates[i].safetyRatings = candidate.safetyRatings;
if (candidate.content && candidate.content.parts) {
if (!aggregatedResponse.candidates[i].content) {
aggregatedResponse.candidates[i].content = {
role: candidate.content.role || "user",
parts: []
};
}
const newPart = {};
for (const part of candidate.content.parts) {
if (part.text) {
newPart.text = part.text;
}
if (part.functionCall) {
newPart.functionCall = part.functionCall;
}
if (part.executableCode) {
newPart.executableCode = part.executableCode;
}
if (part.codeExecutionResult) {
newPart.codeExecutionResult = part.codeExecutionResult;
}
if (Object.keys(newPart).length === 0) {
newPart.text = "";
}
aggregatedResponse.candidates[i].content.parts.push(newPart);
}
}
}
}
if (response.usageMetadata) {
aggregatedResponse.usageMetadata = response.usageMetadata;
}
}
return aggregatedResponse;
}
async function generateContentStream(apiKey, model, params, requestOptions) {
const response = await makeModelRequest(
model,
Task.STREAM_GENERATE_CONTENT,
apiKey,
/* stream */
true,
JSON.stringify(params),
requestOptions
);
return processStream(response);
}
async function generateContent(apiKey, model, params, requestOptions) {
const response = await makeModelRequest(
model,
Task.GENERATE_CONTENT,
apiKey,
/* stream */
false,
JSON.stringify(params),
requestOptions
);
const responseJson = await response.json();
const enhancedResponse = addHelpers(responseJson);
return {
response: enhancedResponse
};
}
function formatSystemInstruction(input) {
if (input == null) {
return void 0;
} else if (typeof input === "string") {
return { role: "system", parts: [{ text: input }] };
} else if (input.text) {
return { role: "system", parts: [input] };
} else if (input.parts) {
if (!input.role) {
return { role: "system", parts: input.parts };
} else {
return input;
}
}
}
function formatNewContent(request) {
let newParts = [];
if (typeof request === "string") {
newParts = [{ text: request }];
} else {
for (const partOrString of request) {
if (typeof partOrString === "string") {
newParts.push({ text: partOrString });
} else {
newParts.push(partOrString);
}
}
}
return assignRoleToPartsAndValidateSendMessageRequest(newParts);
}
function assignRoleToPartsAndValidateSendMessageRequest(parts) {
const userContent = { role: "user", parts: [] };
const functionContent = { role: "function", parts: [] };
let hasUserContent = false;
let hasFunctionContent = false;
for (const part of parts) {
if ("functionResponse" in part) {
functionContent.parts.push(part);
hasFunctionContent = true;
} else {
userContent.parts.push(part);
hasUserContent = true;
}
}
if (hasUserContent && hasFunctionContent) {
throw new GoogleGenerativeAIError("Within a single message, FunctionResponse cannot be mixed with other type of part in the request for sending chat message.");
}
if (!hasUserContent && !hasFunctionContent) {
throw new GoogleGenerativeAIError("No content is provided for sending chat message.");
}
if (hasUserContent) {
return userContent;
}
return functionContent;
}
function formatCountTokensInput(params, modelParams) {
var _a2;
let formattedGenerateContentRequest = {
model: modelParams === null || modelParams === void 0 ? void 0 : modelParams.model,
generationConfig: modelParams === null || modelParams === void 0 ? void 0 : modelParams.generationConfig,
safetySettings: modelParams === null || modelParams === void 0 ? void 0 : modelParams.safetySettings,
tools: modelParams === null || modelParams === void 0 ? void 0 : modelParams.tools,
toolConfig: modelParams === null || modelParams === void 0 ? void 0 : modelParams.toolConfig,
systemInstruction: modelParams === null || modelParams === void 0 ? void 0 : modelParams.systemInstruction,
cachedContent: (_a2 = modelParams === null || modelParams === void 0 ? void 0 : modelParams.cachedContent) === null || _a2 === void 0 ? void 0 : _a2.name,
contents: []
};
const containsGenerateContentRequest = params.generateContentRequest != null;
if (params.contents) {
if (containsGenerateContentRequest) {
throw new GoogleGenerativeAIRequestInputError("CountTokensRequest must have one of contents or generateContentRequest, not both.");
}
formattedGenerateContentRequest.contents = params.contents;
} else if (containsGenerateContentRequest) {
formattedGenerateContentRequest = Object.assign(Object.assign({}, formattedGenerateContentRequest), params.generateContentRequest);
} else {
const content = formatNewContent(params);
formattedGenerateContentRequest.contents = [content];
}
return { generateContentRequest: formattedGenerateContentRequest };
}
function formatGenerateContentInput(params) {
let formattedRequest;
if (params.contents) {
formattedRequest = params;
} else {
const content = formatNewContent(params);
formattedRequest = { contents: [content] };
}
if (params.systemInstruction) {
formattedRequest.systemInstruction = formatSystemInstruction(params.systemInstruction);
}
return formattedRequest;
}
function formatEmbedContentInput(params) {
if (typeof params === "string" || Array.isArray(params)) {
const content = formatNewContent(params);
return { content };
}
return params;
}
var VALID_PART_FIELDS = [
"text",
"inlineData",
"functionCall",
"functionResponse",
"executableCode",
"codeExecutionResult"
];
var VALID_PARTS_PER_ROLE = {
user: ["text", "inlineData"],
function: ["functionResponse"],
model: ["text", "functionCall", "executableCode", "codeExecutionResult"],
// System instructions shouldn't be in history anyway.
system: ["text"]
};
function validateChatHistory(history) {
let prevContent = false;
for (const currContent of history) {
const { role, parts } = currContent;
if (!prevContent && role !== "user") {
throw new GoogleGenerativeAIError(`First content should be with role 'user', got ${role}`);
}
if (!POSSIBLE_ROLES.includes(role)) {
throw new GoogleGenerativeAIError(`Each item should include role field. Got ${role} but valid roles are: ${JSON.stringify(POSSIBLE_ROLES)}`);
}
if (!Array.isArray(parts)) {
throw new GoogleGenerativeAIError("Content should have 'parts' property with an array of Parts");
}
if (parts.length === 0) {
throw new GoogleGenerativeAIError("Each Content should have at least one part");
}
const countFields = {
text: 0,
inlineData: 0,
functionCall: 0,
functionResponse: 0,
fileData: 0,
executableCode: 0,
codeExecutionResult: 0
};
for (const part of parts) {
for (const key of VALID_PART_FIELDS) {
if (key in part) {
countFields[key] += 1;
}
}
}
const validParts = VALID_PARTS_PER_ROLE[role];
for (const key of VALID_PART_FIELDS) {
if (!validParts.includes(key) && countFields[key] > 0) {
throw new GoogleGenerativeAIError(`Content with role '${role}' can't contain '${key}' part`);
}
}
prevContent = true;
}
}
var SILENT_ERROR = "SILENT_ERROR";
var ChatSession = class {
constructor(apiKey, model, params, _requestOptions = {}) {
this.model = model;
this.params = params;
this._requestOptions = _requestOptions;
this._history = [];
this._sendPromise = Promise.resolve();
this._apiKey = apiKey;
if (params === null || params === void 0 ? void 0 : params.history) {
validateChatHistory(params.history);
this._history = params.history;
}
}
/**
* Gets the chat history so far. Blocked prompts are not added to history.
* Blocked candidates are not added to history, nor are the prompts that
* generated them.
*/
async getHistory() {
await this._sendPromise;
return this._history;
}
/**
* Sends a chat message and receives a non-streaming
* {@link GenerateContentResult}.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async sendMessage(request, requestOptions = {}) {
var _a2, _b, _c, _d, _e, _f;
await this._sendPromise;
const newContent = formatNewContent(request);
const generateContentRequest = {
safetySettings: (_a2 = this.params) === null || _a2 === void 0 ? void 0 : _a2.safetySettings,
generationConfig: (_b = this.params) === null || _b === void 0 ? void 0 : _b.generationConfig,
tools: (_c = this.params) === null || _c === void 0 ? void 0 : _c.tools,
toolConfig: (_d = this.params) === null || _d === void 0 ? void 0 : _d.toolConfig,
systemInstruction: (_e = this.params) === null || _e === void 0 ? void 0 : _e.systemInstruction,
cachedContent: (_f = this.params) === null || _f === void 0 ? void 0 : _f.cachedContent,
contents: [...this._history, newContent]
};
const chatSessionRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
let finalResult;
this._sendPromise = this._sendPromise.then(() => generateContent(this._apiKey, this.model, generateContentRequest, chatSessionRequestOptions)).then((result) => {
var _a3;
if (result.response.candidates && result.response.candidates.length > 0) {
this._history.push(newContent);
const responseContent = Object.assign({
parts: [],
// Response seems to come back without a role set.
role: "model"
}, (_a3 = result.response.candidates) === null || _a3 === void 0 ? void 0 : _a3[0].content);
this._history.push(responseContent);
} else {
const blockErrorMessage = formatBlockErrorMessage(result.response);
if (blockErrorMessage) {
console.warn(`sendMessage() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`);
}
}
finalResult = result;
});
await this._sendPromise;
return finalResult;
}
/**
* Sends a chat message and receives the response as a
* {@link GenerateContentStreamResult} containing an iterable stream
* and a response promise.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async sendMessageStream(request, requestOptions = {}) {
var _a2, _b, _c, _d, _e, _f;
await this._sendPromise;
const newContent = formatNewContent(request);
const generateContentRequest = {
safetySettings: (_a2 = this.params) === null || _a2 === void 0 ? void 0 : _a2.safetySettings,
generationConfig: (_b = this.params) === null || _b === void 0 ? void 0 : _b.generationConfig,
tools: (_c = this.params) === null || _c === void 0 ? void 0 : _c.tools,
toolConfig: (_d = this.params) === null || _d === void 0 ? void 0 : _d.toolConfig,
systemInstruction: (_e = this.params) === null || _e === void 0 ? void 0 : _e.systemInstruction,
cachedContent: (_f = this.params) === null || _f === void 0 ? void 0 : _f.cachedContent,
contents: [...this._history, newContent]
};
const chatSessionRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
const streamPromise = generateContentStream(this._apiKey, this.model, generateContentRequest, chatSessionRequestOptions);
this._sendPromise = this._sendPromise.then(() => streamPromise).catch((_ignored) => {
throw new Error(SILENT_ERROR);
}).then((streamResult) => streamResult.response).then((response) => {
if (response.candidates && response.candidates.length > 0) {
this._history.push(newContent);
const responseContent = Object.assign({}, response.candidates[0].content);
if (!responseContent.role) {
responseContent.role = "model";
}
this._history.push(responseContent);
} else {
const blockErrorMessage = formatBlockErrorMessage(response);
if (blockErrorMessage) {
console.warn(`sendMessageStream() was unsuccessful. ${blockErrorMessage}. Inspect response object for details.`);
}
}
}).catch((e) => {
if (e.message !== SILENT_ERROR) {
console.error(e);
}
});
return streamPromise;
}
};
async function countTokens(apiKey, model, params, singleRequestOptions) {
const response = await makeModelRequest(model, Task.COUNT_TOKENS, apiKey, false, JSON.stringify(params), singleRequestOptions);
return response.json();
}
async function embedContent(apiKey, model, params, requestOptions) {
const response = await makeModelRequest(model, Task.EMBED_CONTENT, apiKey, false, JSON.stringify(params), requestOptions);
return response.json();
}
async function batchEmbedContents(apiKey, model, params, requestOptions) {
const requestsWithModel = params.requests.map((request) => {
return Object.assign(Object.assign({}, request), { model });
});
const response = await makeModelRequest(model, Task.BATCH_EMBED_CONTENTS, apiKey, false, JSON.stringify({ requests: requestsWithModel }), requestOptions);
return response.json();
}
var GenerativeModel = class {
constructor(apiKey, modelParams, _requestOptions = {}) {
this.apiKey = apiKey;
this._requestOptions = _requestOptions;
if (modelParams.model.includes("/")) {
this.model = modelParams.model;
} else {
this.model = `models/${modelParams.model}`;
}
this.generationConfig = modelParams.generationConfig || {};
this.safetySettings = modelParams.safetySettings || [];
this.tools = modelParams.tools;
this.toolConfig = modelParams.toolConfig;
this.systemInstruction = formatSystemInstruction(modelParams.systemInstruction);
this.cachedContent = modelParams.cachedContent;
}
/**
* Makes a single non-streaming call to the model
* and returns an object containing a single {@link GenerateContentResponse}.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async generateContent(request, requestOptions = {}) {
var _a2;
const formattedParams = formatGenerateContentInput(request);
const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
return generateContent(this.apiKey, this.model, Object.assign({ generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, toolConfig: this.toolConfig, systemInstruction: this.systemInstruction, cachedContent: (_a2 = this.cachedContent) === null || _a2 === void 0 ? void 0 : _a2.name }, formattedParams), generativeModelRequestOptions);
}
/**
* Makes a single streaming call to the model and returns an object
* containing an iterable stream that iterates over all chunks in the
* streaming response as well as a promise that returns the final
* aggregated response.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async generateContentStream(request, requestOptions = {}) {
var _a2;
const formattedParams = formatGenerateContentInput(request);
const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
return generateContentStream(this.apiKey, this.model, Object.assign({ generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, toolConfig: this.toolConfig, systemInstruction: this.systemInstruction, cachedContent: (_a2 = this.cachedContent) === null || _a2 === void 0 ? void 0 : _a2.name }, formattedParams), generativeModelRequestOptions);
}
/**
* Gets a new {@link ChatSession} instance which can be used for
* multi-turn chats.
*/
startChat(startChatParams) {
var _a2;
return new ChatSession(this.apiKey, this.model, Object.assign({ generationConfig: this.generationConfig, safetySettings: this.safetySettings, tools: this.tools, toolConfig: this.toolConfig, systemInstruction: this.systemInstruction, cachedContent: (_a2 = this.cachedContent) === null || _a2 === void 0 ? void 0 : _a2.name }, startChatParams), this._requestOptions);
}
/**
* Counts the tokens in the provided request.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async countTokens(request, requestOptions = {}) {
const formattedParams = formatCountTokensInput(request, {
model: this.model,
generationConfig: this.generationConfig,
safetySettings: this.safetySettings,
tools: this.tools,
toolConfig: this.toolConfig,
systemInstruction: this.systemInstruction,
cachedContent: this.cachedContent
});
const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
return countTokens(this.apiKey, this.model, formattedParams, generativeModelRequestOptions);
}
/**
* Embeds the provided content.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async embedContent(request, requestOptions = {}) {
const formattedParams = formatEmbedContentInput(request);
const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
return embedContent(this.apiKey, this.model, formattedParams, generativeModelRequestOptions);
}
/**
* Embeds an array of {@link EmbedContentRequest}s.
*
* Fields set in the optional {@link SingleRequestOptions} parameter will
* take precedence over the {@link RequestOptions} values provided to
* {@link GoogleGenerativeAI.getGenerativeModel }.
*/
async batchEmbedContents(batchEmbedContentRequest, requestOptions = {}) {
const generativeModelRequestOptions = Object.assign(Object.assign({}, this._requestOptions), requestOptions);
return batchEmbedContents(this.apiKey, this.model, batchEmbedContentRequest, generativeModelRequestOptions);
}
};
var GoogleGenerativeAI = class {
constructor(apiKey) {
this.apiKey = apiKey;
}
/**
* Gets a {@link GenerativeModel} instance for the provided model name.
*/
getGenerativeModel(modelParams, requestOptions) {
if (!modelParams.model) {
throw new GoogleGenerativeAIError(`Must provide a model name. Example: genai.getGenerativeModel({ model: 'my-model-name' })`);
}
return new GenerativeModel(this.apiKey, modelParams, requestOptions);
}
/**
* Creates a {@link GenerativeModel} instance from provided content cache.
*/
getGenerativeModelFromCachedContent(cachedContent, modelParams, requestOptions) {
if (!cachedContent.name) {
throw new GoogleGenerativeAIRequestInputError("Cached content must contain a `name` field.");
}
if (!cachedContent.model) {
throw new GoogleGenerativeAIRequestInputError("Cached content must contain a `model` field.");
}
const disallowedDuplicates = ["model", "systemInstruction"];
for (const key of disallowedDuplicates) {
if ((modelParams === null || modelParams === void 0 ? void 0 : modelParams[key]) && cachedContent[key] && (modelParams === null || modelParams === void 0 ? void 0 : modelParams[key]) !== cachedContent[key]) {
if (key === "model") {
const modelParamsComp = modelParams.model.startsWith("models/") ? modelParams.model.replace("models/", "") : modelParams.model;
const cachedContentComp = cachedContent.model.startsWith("models/") ? cachedContent.model.replace("models/", "") : cachedContent.model;
if (modelParamsComp === cachedContentComp) {
continue;
}
}
throw new GoogleGenerativeAIRequestInputError(`Different value for "${key}" specified in modelParams (${modelParams[key]}) and cachedContent (${cachedContent[key]})`);
}
}
const modelParamsFromCache = Object.assign(Object.assign({}, modelParams), { model: cachedContent.model, tools: cachedContent.tools, toolConfig: cachedContent.toolConfig, systemInstruction: cachedContent.systemInstruction, cachedContent });
return new GenerativeModel(this.apiKey, modelParamsFromCache, requestOptions);
}
};
// node_modules/openai/internal/qs/formats.mjs
var default_format = "RFC3986";
var formatters = {
RFC1738: (v) => String(v).replace(/%20/g, "+"),
RFC3986: (v) => String(v)
};
var RFC1738 = "RFC1738";
// node_modules/openai/internal/qs/utils.mjs
var is_array = Array.isArray;
var hex_table = (() => {
const array = [];
for (let i = 0; i < 256; ++i) {
array.push("%" + ((i < 16 ? "0" : "") + i.toString(16)).toUpperCase());
}
return array;
})();
var limit = 1024;
var encode = (str2, _defaultEncoder, charset, _kind, format) => {
if (str2.length === 0) {
return str2;
}
let string = str2;
if (typeof str2 === "symbol") {
string = Symbol.prototype.toString.call(str2);
} else if (typeof str2 !== "string") {
string = String(str2);
}
if (charset === "iso-8859-1") {
return escape(string).replace(/%u[0-9a-f]{4}/gi, function($0) {
return "%26%23" + parseInt($0.slice(2), 16) + "%3B";
});
}
let out = "";
for (let j = 0; j < string.length; j += limit) {
const segment = string.length >= limit ? string.slice(j, j + limit) : string;
const arr = [];
for (let i = 0; i < segment.length; ++i) {
let c = segment.charCodeAt(i);
if (c === 45 || // -
c === 46 || // .
c === 95 || // _
c === 126 || // ~
c >= 48 && c <= 57 || // 0-9
c >= 65 && c <= 90 || // a-z
c >= 97 && c <= 122 || // A-Z
format === RFC1738 && (c === 40 || c === 41)) {
arr[arr.length] = segment.charAt(i);
continue;
}
if (c < 128) {
arr[arr.length] = hex_table[c];
continue;
}
if (c < 2048) {
arr[arr.length] = hex_table[192 | c >> 6] + hex_table[128 | c & 63];
continue;
}
if (c < 55296 || c >= 57344) {
arr[arr.length] = hex_table[224 | c >> 12] + hex_table[128 | c >> 6 & 63] + hex_table[128 | c & 63];
continue;
}
i += 1;
c = 65536 + ((c & 1023) << 10 | segment.charCodeAt(i) & 1023);
arr[arr.length] = hex_table[240 | c >> 18] + hex_table[128 | c >> 12 & 63] + hex_table[128 | c >> 6 & 63] + hex_table[128 | c & 63];
}
out += arr.join("");
}
return out;
};
function is_buffer(obj) {
if (!obj || typeof obj !== "object") {
return false;
}
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
}
function maybe_map(val, fn) {
if (is_array(val)) {
const mapped = [];
for (let i = 0; i < val.length; i += 1) {
mapped.push(fn(val[i]));
}
return mapped;
}
return fn(val);
}
// node_modules/openai/internal/qs/stringify.mjs
var has = Object.prototype.hasOwnProperty;
var array_prefix_generators = {
brackets(prefix) {
return String(prefix) + "[]";
},
comma: "comma",
indices(prefix, key) {
return String(prefix) + "[" + key + "]";
},
repeat(prefix) {
return String(prefix);
}
};
var is_array2 = Array.isArray;
var push = Array.prototype.push;
var push_to_array = function(arr, value_or_array) {
push.apply(arr, is_array2(value_or_array) ? value_or_array : [value_or_array]);
};
var to_ISO = Date.prototype.toISOString;
var defaults = {
addQueryPrefix: false,
allowDots: false,
allowEmptyArrays: false,
arrayFormat: "indices",
charset: "utf-8",
charsetSentinel: false,
delimiter: "&",
encode: true,
encodeDotInKeys: false,
encoder: encode,
encodeValuesOnly: false,
format: default_format,
formatter: formatters[default_format],
/** @deprecated */
indices: false,
serializeDate(date) {
return to_ISO.call(date);
},
skipNulls: false,
strictNullHandling: false
};
function is_non_nullish_primitive(v) {
return typeof v === "string" || typeof v === "number" || typeof v === "boolean" || typeof v === "symbol" || typeof v === "bigint";
}
var sentinel = {};
function inner_stringify(object, prefix, generateArrayPrefix, commaRoundTrip, allowEmptyArrays, strictNullHandling, skipNulls, encodeDotInKeys, encoder, filter, sort, allowDots, serializeDate, format, formatter, encodeValuesOnly, charset, sideChannel) {
let obj = object;
let tmp_sc = sideChannel;
let step = 0;
let find_flag = false;
while ((tmp_sc = tmp_sc.get(sentinel)) !== void 0 && !find_flag) {
const pos = tmp_sc.get(object);
step += 1;
if (typeof pos !== "undefined") {
if (pos === step) {
throw new RangeError("Cyclic object value");
} else {
find_flag = true;
}
}
if (typeof tmp_sc.get(sentinel) === "undefined") {
step = 0;
}
}
if (typeof filter === "function") {
obj = filter(prefix, obj);
} else if (obj instanceof Date) {
obj = serializeDate == null ? void 0 : serializeDate(obj);
} else if (generateArrayPrefix === "comma" && is_array2(obj)) {
obj = maybe_map(obj, function(value) {
if (value instanceof Date) {
return serializeDate == null ? void 0 : serializeDate(value);
}
return value;
});
}
if (obj === null) {
if (strictNullHandling) {
return encoder && !encodeValuesOnly ? (
// @ts-expect-error
encoder(prefix, defaults.encoder, charset, "key", format)
) : prefix;
}
obj = "";
}
if (is_non_nullish_primitive(obj) || is_buffer(obj)) {
if (encoder) {
const key_value = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, "key", format);
return [
(formatter == null ? void 0 : formatter(key_value)) + "=" + // @ts-expect-error
(formatter == null ? void 0 : formatter(encoder(obj, defaults.encoder, charset, "value", format)))
];
}
return [(formatter == null ? void 0 : formatter(prefix)) + "=" + (formatter == null ? void 0 : formatter(String(obj)))];
}
const values = [];
if (typeof obj === "undefined") {
return values;
}
let obj_keys;
if (generateArrayPrefix === "comma" && is_array2(obj)) {
if (encodeValuesOnly && encoder) {
obj = maybe_map(obj, encoder);
}
obj_keys = [{ value: obj.length > 0 ? obj.join(",") || null : void 0 }];
} else if (is_array2(filter)) {
obj_keys = filter;
} else {
const keys = Object.keys(obj);
obj_keys = sort ? keys.sort(sort) : keys;
}
const encoded_prefix = encodeDotInKeys ? String(prefix).replace(/\./g, "%2E") : String(prefix);
const adjusted_prefix = commaRoundTrip && is_array2(obj) && obj.length === 1 ? encoded_prefix + "[]" : encoded_prefix;
if (allowEmptyArrays && is_array2(obj) && obj.length === 0) {
return adjusted_prefix + "[]";
}
for (let j = 0; j < obj_keys.length; ++j) {
const key = obj_keys[j];
const value = (
// @ts-ignore
typeof key === "object" && typeof key.value !== "undefined" ? key.value : obj[key]
);
if (skipNulls && value === null) {
continue;
}
const encoded_key = allowDots && encodeDotInKeys ? key.replace(/\./g, "%2E") : key;
const key_prefix = is_array2(obj) ? typeof generateArrayPrefix === "function" ? generateArrayPrefix(adjusted_prefix, encoded_key) : adjusted_prefix : adjusted_prefix + (allowDots ? "." + encoded_key : "[" + encoded_key + "]");
sideChannel.set(object, step);
const valueSideChannel = /* @__PURE__ */ new WeakMap();
valueSideChannel.set(sentinel, sideChannel);
push_to_array(values, inner_stringify(
value,
key_prefix,
generateArrayPrefix,
commaRoundTrip,
allowEmptyArrays,
strictNullHandling,
skipNulls,
encodeDotInKeys,
// @ts-ignore
generateArrayPrefix === "comma" && encodeValuesOnly && is_array2(obj) ? null : encoder,
filter,
sort,
allowDots,
serializeDate,
format,
formatter,
encodeValuesOnly,
charset,
valueSideChannel
));
}
return values;
}
function normalize_stringify_options(opts = defaults) {
if (typeof opts.allowEmptyArrays !== "undefined" && typeof opts.allowEmptyArrays !== "boolean") {
throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");
}
if (typeof opts.encodeDotInKeys !== "undefined" && typeof opts.encodeDotInKeys !== "boolean") {
throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided");
}
if (opts.encoder !== null && typeof opts.encoder !== "undefined" && typeof opts.encoder !== "function") {
throw new TypeError("Encoder has to be a function.");
}
const charset = opts.charset || defaults.charset;
if (typeof opts.charset !== "undefined" && opts.charset !== "utf-8" && opts.charset !== "iso-8859-1") {
throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");
}
let format = default_format;
if (typeof opts.format !== "undefined") {
if (!has.call(formatters, opts.format)) {
throw new TypeError("Unknown format option provided.");
}
format = opts.format;
}
const formatter = formatters[format];
let filter = defaults.filter;
if (typeof opts.filter === "function" || is_array2(opts.filter)) {
filter = opts.filter;
}
let arrayFormat;
if (opts.arrayFormat && opts.arrayFormat in array_prefix_generators) {
arrayFormat = opts.arrayFormat;
} else if ("indices" in opts) {
arrayFormat = opts.indices ? "indices" : "repeat";
} else {
arrayFormat = defaults.arrayFormat;
}
if ("commaRoundTrip" in opts && typeof opts.commaRoundTrip !== "boolean") {
throw new TypeError("`commaRoundTrip` must be a boolean, or absent");
}
const allowDots = typeof opts.allowDots === "undefined" ? !!opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;
return {
addQueryPrefix: typeof opts.addQueryPrefix === "boolean" ? opts.addQueryPrefix : defaults.addQueryPrefix,
// @ts-ignore
allowDots,
allowEmptyArrays: typeof opts.allowEmptyArrays === "boolean" ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
arrayFormat,
charset,
charsetSentinel: typeof opts.charsetSentinel === "boolean" ? opts.charsetSentinel : defaults.charsetSentinel,
commaRoundTrip: !!opts.commaRoundTrip,
delimiter: typeof opts.delimiter === "undefined" ? defaults.delimiter : opts.delimiter,
encode: typeof opts.encode === "boolean" ? opts.encode : defaults.encode,
encodeDotInKeys: typeof opts.encodeDotInKeys === "boolean" ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
encoder: typeof opts.encoder === "function" ? opts.encoder : defaults.encoder,
encodeValuesOnly: typeof opts.encodeValuesOnly === "boolean" ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
filter,
format,
formatter,
serializeDate: typeof opts.serializeDate === "function" ? opts.serializeDate : defaults.serializeDate,
skipNulls: typeof opts.skipNulls === "boolean" ? opts.skipNulls : defaults.skipNulls,
// @ts-ignore
sort: typeof opts.sort === "function" ? opts.sort : null,
strictNullHandling: typeof opts.strictNullHandling === "boolean" ? opts.strictNullHandling : defaults.strictNullHandling
};
}
function stringify(object, opts = {}) {
let obj = object;
const options = normalize_stringify_options(opts);
let obj_keys;
let filter;
if (typeof options.filter === "function") {
filter = options.filter;
obj = filter("", obj);
} else if (is_array2(options.filter)) {
filter = options.filter;
obj_keys = filter;
}
const keys = [];
if (typeof obj !== "object" || obj === null) {
return "";
}
const generateArrayPrefix = array_prefix_generators[options.arrayFormat];
const commaRoundTrip = generateArrayPrefix === "comma" && options.commaRoundTrip;
if (!obj_keys) {
obj_keys = Object.keys(obj);
}
if (options.sort) {
obj_keys.sort(options.sort);
}
const sideChannel = /* @__PURE__ */ new WeakMap();
for (let i = 0; i < obj_keys.length; ++i) {
const key = obj_keys[i];
if (options.skipNulls && obj[key] === null) {
continue;
}
push_to_array(keys, inner_stringify(
obj[key],
key,
// @ts-expect-error
generateArrayPrefix,
commaRoundTrip,
options.allowEmptyArrays,
options.strictNullHandling,
options.skipNulls,
options.encodeDotInKeys,
options.encode ? options.encoder : null,
options.filter,
options.sort,
options.allowDots,
options.serializeDate,
options.format,
options.formatter,
options.encodeValuesOnly,
options.charset,
sideChannel
));
}
const joined = keys.join(options.delimiter);
let prefix = options.addQueryPrefix === true ? "?" : "";
if (options.charsetSentinel) {
if (options.charset === "iso-8859-1") {
prefix += "utf8=%26%2310003%3B&";
} else {
prefix += "utf8=%E2%9C%93&";
}
}
return joined.length > 0 ? prefix + joined : "";
}
// node_modules/openai/version.mjs
var VERSION = "4.76.1";
// node_modules/openai/_shims/registry.mjs
var auto = false;
var kind = void 0;
var fetch2 = void 0;
var Request2 = void 0;
var Response2 = void 0;
var Headers2 = void 0;
var FormData2 = void 0;
var Blob2 = void 0;
var File2 = void 0;
var ReadableStream2 = void 0;
var getMultipartRequestOptions = void 0;
var getDefaultAgent = void 0;
var fileFromPath = void 0;
var isFsReadStream = void 0;
function setShims(shims, options = { auto: false }) {
if (auto) {
throw new Error(`you must \`import 'openai/shims/${shims.kind}'\` before importing anything else from openai`);
}
if (kind) {
throw new Error(`can't \`import 'openai/shims/${shims.kind}'\` after \`import 'openai/shims/${kind}'\``);
}
auto = options.auto;
kind = shims.kind;
fetch2 = shims.fetch;
Request2 = shims.Request;
Response2 = shims.Response;
Headers2 = shims.Headers;
FormData2 = shims.FormData;
Blob2 = shims.Blob;
File2 = shims.File;
ReadableStream2 = shims.ReadableStream;
getMultipartRequestOptions = shims.getMultipartRequestOptions;
getDefaultAgent = shims.getDefaultAgent;
fileFromPath = shims.fileFromPath;
isFsReadStream = shims.isFsReadStream;
}
// node_modules/openai/_shims/MultipartBody.mjs
var MultipartBody = class {
constructor(body) {
this.body = body;
}
get [Symbol.toStringTag]() {
return "MultipartBody";
}
};
// node_modules/openai/_shims/web-runtime.mjs
function getRuntime({ manuallyImported } = {}) {
const recommendation = manuallyImported ? `You may need to use polyfills` : `Add one of these imports before your first \`import \u2026 from 'openai'\`:
- \`import 'openai/shims/node'\` (if you're running on Node)
- \`import 'openai/shims/web'\` (otherwise)
`;
let _fetch, _Request, _Response, _Headers;
try {
_fetch = fetch;
_Request = Request;
_Response = Response;
_Headers = Headers;
} catch (error) {
throw new Error(`this environment is missing the following Web Fetch API type: ${error.message}. ${recommendation}`);
}
return {
kind: "web",
fetch: _fetch,
Request: _Request,
Response: _Response,
Headers: _Headers,
FormData: (
// @ts-ignore
typeof FormData !== "undefined" ? FormData : class FormData {
// @ts-ignore
constructor() {
throw new Error(`file uploads aren't supported in this environment yet as 'FormData' is undefined. ${recommendation}`);
}
}
),
Blob: typeof Blob !== "undefined" ? Blob : class Blob {
constructor() {
throw new Error(`file uploads aren't supported in this environment yet as 'Blob' is undefined. ${recommendation}`);
}
},
File: (
// @ts-ignore
typeof File !== "undefined" ? File : class File {
// @ts-ignore
constructor() {
throw new Error(`file uploads aren't supported in this environment yet as 'File' is undefined. ${recommendation}`);
}
}
),
ReadableStream: (
// @ts-ignore
typeof ReadableStream !== "undefined" ? ReadableStream : class ReadableStream {
// @ts-ignore
constructor() {
throw new Error(`streaming isn't supported in this environment yet as 'ReadableStream' is undefined. ${recommendation}`);
}
}
),
getMultipartRequestOptions: async (form, opts) => ({
...opts,
body: new MultipartBody(form)
}),
getDefaultAgent: (url) => void 0,
fileFromPath: () => {
throw new Error("The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/openai/openai-node#file-uploads");
},
isFsReadStream: (value) => false
};
}
// node_modules/openai/_shims/index.mjs
if (!kind)
setShims(getRuntime(), { auto: true });
// node_modules/openai/error.mjs
var OpenAIError = class extends Error {
};
var APIError = class _APIError extends OpenAIError {
constructor(status, error, message, headers) {
super(`${_APIError.makeMessage(status, error, message)}`);
this.status = status;
this.headers = headers;
this.request_id = headers == null ? void 0 : headers["x-request-id"];
const data = error;
this.error = data;
this.code = data == null ? void 0 : data["code"];
this.param = data == null ? void 0 : data["param"];
this.type = data == null ? void 0 : data["type"];
}
static makeMessage(status, error, message) {
const msg = (error == null ? void 0 : error.message) ? typeof error.message === "string" ? error.message : JSON.stringify(error.message) : error ? JSON.stringify(error) : message;
if (status && msg) {
return `${status} ${msg}`;
}
if (status) {
return `${status} status code (no body)`;
}
if (msg) {
return msg;
}
return "(no status code or body)";
}
static generate(status, errorResponse, message, headers) {
if (!status) {
return new APIConnectionError({ message, cause: castToError(errorResponse) });
}
const error = errorResponse == null ? void 0 : errorResponse["error"];
if (status === 400) {
return new BadRequestError(status, error, message, headers);
}
if (status === 401) {
return new AuthenticationError(status, error, message, headers);
}
if (status === 403) {
return new PermissionDeniedError(status, error, message, headers);
}
if (status === 404) {
return new NotFoundError(status, error, message, headers);
}
if (status === 409) {
return new ConflictError(status, error, message, headers);
}
if (status === 422) {
return new UnprocessableEntityError(status, error, message, headers);
}
if (status === 429) {
return new RateLimitError(status, error, message, headers);
}
if (status >= 500) {
return new InternalServerError(status, error, message, headers);
}
return new _APIError(status, error, message, headers);
}
};
var APIUserAbortError = class extends APIError {
constructor({ message } = {}) {
super(void 0, void 0, message || "Request was aborted.", void 0);
this.status = void 0;
}
};
var APIConnectionError = class extends APIError {
constructor({ message, cause }) {
super(void 0, void 0, message || "Connection error.", void 0);
this.status = void 0;
if (cause)
this.cause = cause;
}
};
var APIConnectionTimeoutError = class extends APIConnectionError {
constructor({ message } = {}) {
super({ message: message != null ? message : "Request timed out." });
}
};
var BadRequestError = class extends APIError {
constructor() {
super(...arguments);
this.status = 400;
}
};
var AuthenticationError = class extends APIError {
constructor() {
super(...arguments);
this.status = 401;
}
};
var PermissionDeniedError = class extends APIError {
constructor() {
super(...arguments);
this.status = 403;
}
};
var NotFoundError = class extends APIError {
constructor() {
super(...arguments);
this.status = 404;
}
};
var ConflictError = class extends APIError {
constructor() {
super(...arguments);
this.status = 409;
}
};
var UnprocessableEntityError = class extends APIError {
constructor() {
super(...arguments);
this.status = 422;
}
};
var RateLimitError = class extends APIError {
constructor() {
super(...arguments);
this.status = 429;
}
};
var InternalServerError = class extends APIError {
};
var LengthFinishReasonError = class extends OpenAIError {
constructor() {
super(`Could not parse response content as the length limit was reached`);
}
};
var ContentFilterFinishReasonError = class extends OpenAIError {
constructor() {
super(`Could not parse response content as the request was rejected by the content filter`);
}
};
// node_modules/openai/internal/decoders/line.mjs
var LineDecoder = class _LineDecoder {
constructor() {
this.buffer = [];
this.trailingCR = false;
}
decode(chunk) {
let text = this.decodeText(chunk);
if (this.trailingCR) {
text = "\r" + text;
this.trailingCR = false;
}
if (text.endsWith("\r")) {
this.trailingCR = true;
text = text.slice(0, -1);
}
if (!text) {
return [];
}
const trailingNewline = _LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || "");
let lines = text.split(_LineDecoder.NEWLINE_REGEXP);
if (trailingNewline) {
lines.pop();
}
if (lines.length === 1 && !trailingNewline) {
this.buffer.push(lines[0]);
return [];
}
if (this.buffer.length > 0) {
lines = [this.buffer.join("") + lines[0], ...lines.slice(1)];
this.buffer = [];
}
if (!trailingNewline) {
this.buffer = [lines.pop() || ""];
}
return lines;
}
decodeText(bytes) {
var _a2;
if (bytes == null)
return "";
if (typeof bytes === "string")
return bytes;
if (typeof Buffer !== "undefined") {
if (bytes instanceof Buffer) {
return bytes.toString();
}
if (bytes instanceof Uint8Array) {
return Buffer.from(bytes).toString();
}
throw new OpenAIError(`Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`);
}
if (typeof TextDecoder !== "undefined") {
if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) {
(_a2 = this.textDecoder) != null ? _a2 : this.textDecoder = new TextDecoder("utf8");
return this.textDecoder.decode(bytes);
}
throw new OpenAIError(`Unexpected: received non-Uint8Array/ArrayBuffer (${bytes.constructor.name}) in a web platform. Please report this error.`);
}
throw new OpenAIError(`Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`);
}
flush() {
if (!this.buffer.length && !this.trailingCR) {
return [];
}
const lines = [this.buffer.join("")];
this.buffer = [];
this.trailingCR = false;
return lines;
}
};
LineDecoder.NEWLINE_CHARS = /* @__PURE__ */ new Set(["\n", "\r"]);
LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
// node_modules/openai/streaming.mjs
var Stream = class _Stream {
constructor(iterator, controller) {
this.iterator = iterator;
this.controller = controller;
}
static fromSSEResponse(response, controller) {
let consumed = false;
async function* iterator() {
if (consumed) {
throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
}
consumed = true;
let done = false;
try {
for await (const sse of _iterSSEMessages(response, controller)) {
if (done)
continue;
if (sse.data.startsWith("[DONE]")) {
done = true;
continue;
}
if (sse.event === null) {
let data;
try {
data = JSON.parse(sse.data);
} catch (e) {
console.error(`Could not parse message into JSON:`, sse.data);
console.error(`From chunk:`, sse.raw);
throw e;
}
if (data && data.error) {
throw new APIError(void 0, data.error, void 0, void 0);
}
yield data;
} else {
let data;
try {
data = JSON.parse(sse.data);
} catch (e) {
console.error(`Could not parse message into JSON:`, sse.data);
console.error(`From chunk:`, sse.raw);
throw e;
}
if (sse.event == "error") {
throw new APIError(void 0, data.error, data.message, void 0);
}
yield { event: sse.event, data };
}
}
done = true;
} catch (e) {
if (e instanceof Error && e.name === "AbortError")
return;
throw e;
} finally {
if (!done)
controller.abort();
}
}
return new _Stream(iterator, controller);
}
/**
* Generates a Stream from a newline-separated ReadableStream
* where each item is a JSON value.
*/
static fromReadableStream(readableStream, controller) {
let consumed = false;
async function* iterLines() {
const lineDecoder = new LineDecoder();
const iter = readableStreamAsyncIterable(readableStream);
for await (const chunk of iter) {
for (const line of lineDecoder.decode(chunk)) {
yield line;
}
}
for (const line of lineDecoder.flush()) {
yield line;
}
}
async function* iterator() {
if (consumed) {
throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
}
consumed = true;
let done = false;
try {
for await (const line of iterLines()) {
if (done)
continue;
if (line)
yield JSON.parse(line);
}
done = true;
} catch (e) {
if (e instanceof Error && e.name === "AbortError")
return;
throw e;
} finally {
if (!done)
controller.abort();
}
}
return new _Stream(iterator, controller);
}
[Symbol.asyncIterator]() {
return this.iterator();
}
/**
* Splits the stream into two streams which can be
* independently read from at different speeds.
*/
tee() {
const left = [];
const right = [];
const iterator = this.iterator();
const teeIterator = (queue) => {
return {
next: () => {
if (queue.length === 0) {
const result = iterator.next();
left.push(result);
right.push(result);
}
return queue.shift();
}
};
};
return [
new _Stream(() => teeIterator(left), this.controller),
new _Stream(() => teeIterator(right), this.controller)
];
}
/**
* Converts this stream to a newline-separated ReadableStream of
* JSON stringified values in the stream
* which can be turned back into a Stream with `Stream.fromReadableStream()`.
*/
toReadableStream() {
const self = this;
let iter;
const encoder = new TextEncoder();
return new ReadableStream2({
async start() {
iter = self[Symbol.asyncIterator]();
},
async pull(ctrl) {
try {
const { value, done } = await iter.next();
if (done)
return ctrl.close();
const bytes = encoder.encode(JSON.stringify(value) + "\n");
ctrl.enqueue(bytes);
} catch (err) {
ctrl.error(err);
}
},
async cancel() {
var _a2;
await ((_a2 = iter.return) == null ? void 0 : _a2.call(iter));
}
});
}
};
async function* _iterSSEMessages(response, controller) {
if (!response.body) {
controller.abort();
throw new OpenAIError(`Attempted to iterate over a response with no body`);
}
const sseDecoder = new SSEDecoder();
const lineDecoder = new LineDecoder();
const iter = readableStreamAsyncIterable(response.body);
for await (const sseChunk of iterSSEChunks(iter)) {
for (const line of lineDecoder.decode(sseChunk)) {
const sse = sseDecoder.decode(line);
if (sse)
yield sse;
}
}
for (const line of lineDecoder.flush()) {
const sse = sseDecoder.decode(line);
if (sse)
yield sse;
}
}
async function* iterSSEChunks(iterator) {
let data = new Uint8Array();
for await (const chunk of iterator) {
if (chunk == null) {
continue;
}
const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk;
let newData = new Uint8Array(data.length + binaryChunk.length);
newData.set(data);
newData.set(binaryChunk, data.length);
data = newData;
let patternIndex;
while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
yield data.slice(0, patternIndex);
data = data.slice(patternIndex);
}
}
if (data.length > 0) {
yield data;
}
}
function findDoubleNewlineIndex(buffer) {
const newline = 10;
const carriage = 13;
for (let i = 0; i < buffer.length - 2; i++) {
if (buffer[i] === newline && buffer[i + 1] === newline) {
return i + 2;
}
if (buffer[i] === carriage && buffer[i + 1] === carriage) {
return i + 2;
}
if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) {
return i + 4;
}
}
return -1;
}
var SSEDecoder = class {
constructor() {
this.event = null;
this.data = [];
this.chunks = [];
}
decode(line) {
if (line.endsWith("\r")) {
line = line.substring(0, line.length - 1);
}
if (!line) {
if (!this.event && !this.data.length)
return null;
const sse = {
event: this.event,
data: this.data.join("\n"),
raw: this.chunks
};
this.event = null;
this.data = [];
this.chunks = [];
return sse;
}
this.chunks.push(line);
if (line.startsWith(":")) {
return null;
}
let [fieldname, _, value] = partition(line, ":");
if (value.startsWith(" ")) {
value = value.substring(1);
}
if (fieldname === "event") {
this.event = value;
} else if (fieldname === "data") {
this.data.push(value);
}
return null;
}
};
function partition(str2, delimiter) {
const index = str2.indexOf(delimiter);
if (index !== -1) {
return [str2.substring(0, index), delimiter, str2.substring(index + delimiter.length)];
}
return [str2, "", ""];
}
function readableStreamAsyncIterable(stream) {
if (stream[Symbol.asyncIterator])
return stream;
const reader = stream.getReader();
return {
async next() {
try {
const result = await reader.read();
if (result == null ? void 0 : result.done)
reader.releaseLock();
return result;
} catch (e) {
reader.releaseLock();
throw e;
}
},
async return() {
const cancelPromise = reader.cancel();
reader.releaseLock();
await cancelPromise;
return { done: true, value: void 0 };
},
[Symbol.asyncIterator]() {
return this;
}
};
}
// node_modules/openai/uploads.mjs
var isResponseLike = (value) => value != null && typeof value === "object" && typeof value.url === "string" && typeof value.blob === "function";
var isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number" && isBlobLike(value);
var isBlobLike = (value) => value != null && typeof value === "object" && typeof value.size === "number" && typeof value.type === "string" && typeof value.text === "function" && typeof value.slice === "function" && typeof value.arrayBuffer === "function";
var isUploadable = (value) => {
return isFileLike(value) || isResponseLike(value) || isFsReadStream(value);
};
async function toFile(value, name, options) {
var _a2, _b, _c;
value = await value;
if (isFileLike(value)) {
return value;
}
if (isResponseLike(value)) {
const blob = await value.blob();
name || (name = (_a2 = new URL(value.url).pathname.split(/[\\/]/).pop()) != null ? _a2 : "unknown_file");
const data = isBlobLike(blob) ? [await blob.arrayBuffer()] : [blob];
return new File2(data, name, options);
}
const bits = await getBytes(value);
name || (name = (_b = getName(value)) != null ? _b : "unknown_file");
if (!(options == null ? void 0 : options.type)) {
const type = (_c = bits[0]) == null ? void 0 : _c.type;
if (typeof type === "string") {
options = { ...options, type };
}
}
return new File2(bits, name, options);
}
async function getBytes(value) {
var _a2;
let parts = [];
if (typeof value === "string" || ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
value instanceof ArrayBuffer) {
parts.push(value);
} else if (isBlobLike(value)) {
parts.push(await value.arrayBuffer());
} else if (isAsyncIterableIterator(value)) {
for await (const chunk of value) {
parts.push(chunk);
}
} else {
throw new Error(`Unexpected data type: ${typeof value}; constructor: ${(_a2 = value == null ? void 0 : value.constructor) == null ? void 0 : _a2.name}; props: ${propsForError(value)}`);
}
return parts;
}
function propsForError(value) {
const props = Object.getOwnPropertyNames(value);
return `[${props.map((p) => `"${p}"`).join(", ")}]`;
}
function getName(value) {
var _a2;
return getStringFromMaybeBuffer(value.name) || getStringFromMaybeBuffer(value.filename) || // For fs.ReadStream
((_a2 = getStringFromMaybeBuffer(value.path)) == null ? void 0 : _a2.split(/[\\/]/).pop());
}
var getStringFromMaybeBuffer = (x) => {
if (typeof x === "string")
return x;
if (typeof Buffer !== "undefined" && x instanceof Buffer)
return String(x);
return void 0;
};
var isAsyncIterableIterator = (value) => value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function";
var isMultipartBody = (body) => body && typeof body === "object" && body.body && body[Symbol.toStringTag] === "MultipartBody";
var multipartFormRequestOptions = async (opts) => {
const form = await createForm(opts.body);
return getMultipartRequestOptions(form, opts);
};
var createForm = async (body) => {
const form = new FormData2();
await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value)));
return form;
};
var addFormValue = async (form, key, value) => {
if (value === void 0)
return;
if (value == null) {
throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`);
}
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
form.append(key, String(value));
} else if (isUploadable(value)) {
const file = await toFile(value);
form.append(key, file);
} else if (Array.isArray(value)) {
await Promise.all(value.map((entry) => addFormValue(form, key + "[]", entry)));
} else if (typeof value === "object") {
await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)));
} else {
throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`);
}
};
// node_modules/openai/core.mjs
var __classPrivateFieldSet = function(receiver, state, value, kind2, f) {
if (kind2 === "m")
throw new TypeError("Private method is not writable");
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
};
var __classPrivateFieldGet = function(receiver, state, kind2, f) {
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _AbstractPage_client;
async function defaultParseResponse(props) {
const { response } = props;
if (props.options.stream) {
debug("response", response.status, response.url, response.headers, response.body);
if (props.options.__streamClass) {
return props.options.__streamClass.fromSSEResponse(response, props.controller);
}
return Stream.fromSSEResponse(response, props.controller);
}
if (response.status === 204) {
return null;
}
if (props.options.__binaryResponse) {
return response;
}
const contentType = response.headers.get("content-type");
const isJSON = (contentType == null ? void 0 : contentType.includes("application/json")) || (contentType == null ? void 0 : contentType.includes("application/vnd.api+json"));
if (isJSON) {
const json = await response.json();
debug("response", response.status, response.url, response.headers, json);
return _addRequestID(json, response);
}
const text = await response.text();
debug("response", response.status, response.url, response.headers, text);
return text;
}
function _addRequestID(value, response) {
if (!value || typeof value !== "object" || Array.isArray(value)) {
return value;
}
return Object.defineProperty(value, "_request_id", {
value: response.headers.get("x-request-id"),
enumerable: false
});
}
var APIPromise = class _APIPromise extends Promise {
constructor(responsePromise, parseResponse = defaultParseResponse) {
super((resolve) => {
resolve(null);
});
this.responsePromise = responsePromise;
this.parseResponse = parseResponse;
}
_thenUnwrap(transform) {
return new _APIPromise(this.responsePromise, async (props) => _addRequestID(transform(await this.parseResponse(props), props), props.response));
}
/**
* Gets the raw `Response` instance instead of parsing the response
* data.
*
* If you want to parse the response body but still get the `Response`
* instance, you can use {@link withResponse()}.
*
* 👋 Getting the wrong TypeScript type for `Response`?
* Try setting `"moduleResolution": "NodeNext"` if you can,
* or add one of these imports before your first `import … from 'openai'`:
* - `import 'openai/shims/node'` (if you're running on Node)
* - `import 'openai/shims/web'` (otherwise)
*/
asResponse() {
return this.responsePromise.then((p) => p.response);
}
/**
* Gets the parsed response data, the raw `Response` instance and the ID of the request,
* returned via the X-Request-ID header which is useful for debugging requests and reporting
* issues to OpenAI.
*
* If you just want to get the raw `Response` instance without parsing it,
* you can use {@link asResponse()}.
*
*
* 👋 Getting the wrong TypeScript type for `Response`?
* Try setting `"moduleResolution": "NodeNext"` if you can,
* or add one of these imports before your first `import … from 'openai'`:
* - `import 'openai/shims/node'` (if you're running on Node)
* - `import 'openai/shims/web'` (otherwise)
*/
async withResponse() {
const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
return { data, response, request_id: response.headers.get("x-request-id") };
}
parse() {
if (!this.parsedPromise) {
this.parsedPromise = this.responsePromise.then(this.parseResponse);
}
return this.parsedPromise;
}
then(onfulfilled, onrejected) {
return this.parse().then(onfulfilled, onrejected);
}
catch(onrejected) {
return this.parse().catch(onrejected);
}
finally(onfinally) {
return this.parse().finally(onfinally);
}
};
var APIClient = class {
constructor({
baseURL,
maxRetries = 2,
timeout = 6e5,
// 10 minutes
httpAgent,
fetch: overridenFetch
}) {
this.baseURL = baseURL;
this.maxRetries = validatePositiveInteger("maxRetries", maxRetries);
this.timeout = validatePositiveInteger("timeout", timeout);
this.httpAgent = httpAgent;
this.fetch = overridenFetch != null ? overridenFetch : fetch2;
}
authHeaders(opts) {
return {};
}
/**
* Override this to add your own default headers, for example:
*
* {
* ...super.defaultHeaders(),
* Authorization: 'Bearer 123',
* }
*/
defaultHeaders(opts) {
return {
Accept: "application/json",
"Content-Type": "application/json",
"User-Agent": this.getUserAgent(),
...getPlatformHeaders(),
...this.authHeaders(opts)
};
}
/**
* Override this to add your own headers validation:
*/
validateHeaders(headers, customHeaders) {
}
defaultIdempotencyKey() {
return `stainless-node-retry-${uuid4()}`;
}
get(path, opts) {
return this.methodRequest("get", path, opts);
}
post(path, opts) {
return this.methodRequest("post", path, opts);
}
patch(path, opts) {
return this.methodRequest("patch", path, opts);
}
put(path, opts) {
return this.methodRequest("put", path, opts);
}
delete(path, opts) {
return this.methodRequest("delete", path, opts);
}
methodRequest(method, path, opts) {
return this.request(Promise.resolve(opts).then(async (opts2) => {
const body = opts2 && isBlobLike(opts2 == null ? void 0 : opts2.body) ? new DataView(await opts2.body.arrayBuffer()) : (opts2 == null ? void 0 : opts2.body) instanceof DataView ? opts2.body : (opts2 == null ? void 0 : opts2.body) instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2 == null ? void 0 : opts2.body) ? new DataView(opts2.body.buffer) : opts2 == null ? void 0 : opts2.body;
return { method, path, ...opts2, body };
}));
}
getAPIList(path, Page2, opts) {
return this.requestAPIList(Page2, { method: "get", path, ...opts });
}
calculateContentLength(body) {
if (typeof body === "string") {
if (typeof Buffer !== "undefined") {
return Buffer.byteLength(body, "utf8").toString();
}
if (typeof TextEncoder !== "undefined") {
const encoder = new TextEncoder();
const encoded = encoder.encode(body);
return encoded.length.toString();
}
} else if (ArrayBuffer.isView(body)) {
return body.byteLength.toString();
}
return null;
}
buildRequest(options, { retryCount = 0 } = {}) {
var _a2, _b, _c, _d, _e, _f;
const { method, path, query, headers = {} } = options;
const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
const contentLength = this.calculateContentLength(body);
const url = this.buildURL(path, query);
if ("timeout" in options)
validatePositiveInteger("timeout", options.timeout);
const timeout = (_a2 = options.timeout) != null ? _a2 : this.timeout;
const httpAgent = (_c = (_b = options.httpAgent) != null ? _b : this.httpAgent) != null ? _c : getDefaultAgent(url);
const minAgentTimeout = timeout + 1e3;
if (typeof ((_d = httpAgent == null ? void 0 : httpAgent.options) == null ? void 0 : _d.timeout) === "number" && minAgentTimeout > ((_e = httpAgent.options.timeout) != null ? _e : 0)) {
httpAgent.options.timeout = minAgentTimeout;
}
if (this.idempotencyHeader && method !== "get") {
if (!options.idempotencyKey)
options.idempotencyKey = this.defaultIdempotencyKey();
headers[this.idempotencyHeader] = options.idempotencyKey;
}
const reqHeaders = this.buildHeaders({ options, headers, contentLength, retryCount });
const req = {
method,
...body && { body },
headers: reqHeaders,
...httpAgent && { agent: httpAgent },
// @ts-ignore node-fetch uses a custom AbortSignal type that is
// not compatible with standard web types
signal: (_f = options.signal) != null ? _f : null
};
return { req, url, timeout };
}
buildHeaders({ options, headers, contentLength, retryCount }) {
const reqHeaders = {};
if (contentLength) {
reqHeaders["content-length"] = contentLength;
}
const defaultHeaders = this.defaultHeaders(options);
applyHeadersMut(reqHeaders, defaultHeaders);
applyHeadersMut(reqHeaders, headers);
if (isMultipartBody(options.body) && kind !== "node") {
delete reqHeaders["content-type"];
}
if (getHeader(defaultHeaders, "x-stainless-retry-count") === void 0 && getHeader(headers, "x-stainless-retry-count") === void 0) {
reqHeaders["x-stainless-retry-count"] = String(retryCount);
}
this.validateHeaders(reqHeaders, headers);
return reqHeaders;
}
/**
* Used as a callback for mutating the given `FinalRequestOptions` object.
*/
async prepareOptions(options) {
}
/**
* Used as a callback for mutating the given `RequestInit` object.
*
* This is useful for cases where you want to add certain headers based off of
* the request properties, e.g. `method` or `url`.
*/
async prepareRequest(request, { url, options }) {
}
parseHeaders(headers) {
return !headers ? {} : Symbol.iterator in headers ? Object.fromEntries(Array.from(headers).map((header) => [...header])) : { ...headers };
}
makeStatusError(status, error, message, headers) {
return APIError.generate(status, error, message, headers);
}
request(options, remainingRetries = null) {
return new APIPromise(this.makeRequest(options, remainingRetries));
}
async makeRequest(optionsInput, retriesRemaining) {
var _a2, _b, _c;
const options = await optionsInput;
const maxRetries = (_a2 = options.maxRetries) != null ? _a2 : this.maxRetries;
if (retriesRemaining == null) {
retriesRemaining = maxRetries;
}
await this.prepareOptions(options);
const { req, url, timeout } = this.buildRequest(options, { retryCount: maxRetries - retriesRemaining });
await this.prepareRequest(req, { url, options });
debug("request", url, options, req.headers);
if ((_b = options.signal) == null ? void 0 : _b.aborted) {
throw new APIUserAbortError();
}
const controller = new AbortController();
const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
if (response instanceof Error) {
if ((_c = options.signal) == null ? void 0 : _c.aborted) {
throw new APIUserAbortError();
}
if (retriesRemaining) {
return this.retryRequest(options, retriesRemaining);
}
if (response.name === "AbortError") {
throw new APIConnectionTimeoutError();
}
throw new APIConnectionError({ cause: response });
}
const responseHeaders = createResponseHeaders(response.headers);
if (!response.ok) {
if (retriesRemaining && this.shouldRetry(response)) {
const retryMessage2 = `retrying, ${retriesRemaining} attempts remaining`;
debug(`response (error; ${retryMessage2})`, response.status, url, responseHeaders);
return this.retryRequest(options, retriesRemaining, responseHeaders);
}
const errText = await response.text().catch((e) => castToError(e).message);
const errJSON = safeJSON(errText);
const errMessage = errJSON ? void 0 : errText;
const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)`;
debug(`response (error; ${retryMessage})`, response.status, url, responseHeaders, errMessage);
const err = this.makeStatusError(response.status, errJSON, errMessage, responseHeaders);
throw err;
}
return { response, options, controller };
}
requestAPIList(Page2, options) {
const request = this.makeRequest(options, null);
return new PagePromise(this, request, Page2);
}
buildURL(path, query) {
const url = isAbsoluteURL(path) ? new URL(path) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path.startsWith("/") ? path.slice(1) : path));
const defaultQuery = this.defaultQuery();
if (!isEmptyObj(defaultQuery)) {
query = { ...defaultQuery, ...query };
}
if (typeof query === "object" && query && !Array.isArray(query)) {
url.search = this.stringifyQuery(query);
}
return url.toString();
}
stringifyQuery(query) {
return Object.entries(query).filter(([_, value]) => typeof value !== "undefined").map(([key, value]) => {
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
}
if (value === null) {
return `${encodeURIComponent(key)}=`;
}
throw new OpenAIError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
}).join("&");
}
async fetchWithTimeout(url, init, ms, controller) {
const { signal, ...options } = init || {};
if (signal)
signal.addEventListener("abort", () => controller.abort());
const timeout = setTimeout(() => controller.abort(), ms);
return (
// use undefined this binding; fetch errors if bound to something else in browser/cloudflare
this.fetch.call(void 0, url, { signal: controller.signal, ...options }).finally(() => {
clearTimeout(timeout);
})
);
}
shouldRetry(response) {
const shouldRetryHeader = response.headers.get("x-should-retry");
if (shouldRetryHeader === "true")
return true;
if (shouldRetryHeader === "false")
return false;
if (response.status === 408)
return true;
if (response.status === 409)
return true;
if (response.status === 429)
return true;
if (response.status >= 500)
return true;
return false;
}
async retryRequest(options, retriesRemaining, responseHeaders) {
var _a2;
let timeoutMillis;
const retryAfterMillisHeader = responseHeaders == null ? void 0 : responseHeaders["retry-after-ms"];
if (retryAfterMillisHeader) {
const timeoutMs = parseFloat(retryAfterMillisHeader);
if (!Number.isNaN(timeoutMs)) {
timeoutMillis = timeoutMs;
}
}
const retryAfterHeader = responseHeaders == null ? void 0 : responseHeaders["retry-after"];
if (retryAfterHeader && !timeoutMillis) {
const timeoutSeconds = parseFloat(retryAfterHeader);
if (!Number.isNaN(timeoutSeconds)) {
timeoutMillis = timeoutSeconds * 1e3;
} else {
timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
}
}
if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1e3)) {
const maxRetries = (_a2 = options.maxRetries) != null ? _a2 : this.maxRetries;
timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
}
await sleep(timeoutMillis);
return this.makeRequest(options, retriesRemaining - 1);
}
calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
const initialRetryDelay = 0.5;
const maxRetryDelay = 8;
const numRetries = maxRetries - retriesRemaining;
const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
const jitter = 1 - Math.random() * 0.25;
return sleepSeconds * jitter * 1e3;
}
getUserAgent() {
return `${this.constructor.name}/JS ${VERSION}`;
}
};
var AbstractPage = class {
constructor(client, response, body, options) {
_AbstractPage_client.set(this, void 0);
__classPrivateFieldSet(this, _AbstractPage_client, client, "f");
this.options = options;
this.response = response;
this.body = body;
}
hasNextPage() {
const items = this.getPaginatedItems();
if (!items.length)
return false;
return this.nextPageInfo() != null;
}
async getNextPage() {
const nextInfo = this.nextPageInfo();
if (!nextInfo) {
throw new OpenAIError("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");
}
const nextOptions = { ...this.options };
if ("params" in nextInfo && typeof nextOptions.query === "object") {
nextOptions.query = { ...nextOptions.query, ...nextInfo.params };
} else if ("url" in nextInfo) {
const params = [...Object.entries(nextOptions.query || {}), ...nextInfo.url.searchParams.entries()];
for (const [key, value] of params) {
nextInfo.url.searchParams.set(key, value);
}
nextOptions.query = void 0;
nextOptions.path = nextInfo.url.toString();
}
return await __classPrivateFieldGet(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions);
}
async *iterPages() {
let page = this;
yield page;
while (page.hasNextPage()) {
page = await page.getNextPage();
yield page;
}
}
async *[(_AbstractPage_client = /* @__PURE__ */ new WeakMap(), Symbol.asyncIterator)]() {
for await (const page of this.iterPages()) {
for (const item of page.getPaginatedItems()) {
yield item;
}
}
}
};
var PagePromise = class extends APIPromise {
constructor(client, request, Page2) {
super(request, async (props) => new Page2(client, props.response, await defaultParseResponse(props), props.options));
}
/**
* Allow auto-paginating iteration on an unawaited list call, eg:
*
* for await (const item of client.items.list()) {
* console.log(item)
* }
*/
async *[Symbol.asyncIterator]() {
const page = await this;
for await (const item of page) {
yield item;
}
}
};
var createResponseHeaders = (headers) => {
return new Proxy(Object.fromEntries(
// @ts-ignore
headers.entries()
), {
get(target, name) {
const key = name.toString();
return target[key.toLowerCase()] || target[key];
}
});
};
var requestOptionsKeys = {
method: true,
path: true,
query: true,
body: true,
headers: true,
maxRetries: true,
stream: true,
timeout: true,
httpAgent: true,
signal: true,
idempotencyKey: true,
__binaryRequest: true,
__binaryResponse: true,
__streamClass: true
};
var isRequestOptions = (obj) => {
return typeof obj === "object" && obj !== null && !isEmptyObj(obj) && Object.keys(obj).every((k) => hasOwn(requestOptionsKeys, k));
};
var getPlatformProperties = () => {
var _a2, _b;
if (typeof Deno !== "undefined" && Deno.build != null) {
return {
"X-Stainless-Lang": "js",
"X-Stainless-Package-Version": VERSION,
"X-Stainless-OS": normalizePlatform(Deno.build.os),
"X-Stainless-Arch": normalizeArch(Deno.build.arch),
"X-Stainless-Runtime": "deno",
"X-Stainless-Runtime-Version": typeof Deno.version === "string" ? Deno.version : (_b = (_a2 = Deno.version) == null ? void 0 : _a2.deno) != null ? _b : "unknown"
};
}
if (typeof EdgeRuntime !== "undefined") {
return {
"X-Stainless-Lang": "js",
"X-Stainless-Package-Version": VERSION,
"X-Stainless-OS": "Unknown",
"X-Stainless-Arch": `other:${EdgeRuntime}`,
"X-Stainless-Runtime": "edge",
"X-Stainless-Runtime-Version": process.version
};
}
if (Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]") {
return {
"X-Stainless-Lang": "js",
"X-Stainless-Package-Version": VERSION,
"X-Stainless-OS": normalizePlatform(process.platform),
"X-Stainless-Arch": normalizeArch(process.arch),
"X-Stainless-Runtime": "node",
"X-Stainless-Runtime-Version": process.version
};
}
const browserInfo = getBrowserInfo();
if (browserInfo) {
return {
"X-Stainless-Lang": "js",
"X-Stainless-Package-Version": VERSION,
"X-Stainless-OS": "Unknown",
"X-Stainless-Arch": "unknown",
"X-Stainless-Runtime": `browser:${browserInfo.browser}`,
"X-Stainless-Runtime-Version": browserInfo.version
};
}
return {
"X-Stainless-Lang": "js",
"X-Stainless-Package-Version": VERSION,
"X-Stainless-OS": "Unknown",
"X-Stainless-Arch": "unknown",
"X-Stainless-Runtime": "unknown",
"X-Stainless-Runtime-Version": "unknown"
};
};
function getBrowserInfo() {
if (typeof navigator === "undefined" || !navigator) {
return null;
}
const browserPatterns = [
{ key: "edge", pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
{ key: "ie", pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
{ key: "ie", pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
{ key: "chrome", pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
{ key: "firefox", pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
{ key: "safari", pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ }
];
for (const { key, pattern } of browserPatterns) {
const match = pattern.exec(navigator.userAgent);
if (match) {
const major = match[1] || 0;
const minor = match[2] || 0;
const patch = match[3] || 0;
return { browser: key, version: `${major}.${minor}.${patch}` };
}
}
return null;
}
var normalizeArch = (arch) => {
if (arch === "x32")
return "x32";
if (arch === "x86_64" || arch === "x64")
return "x64";
if (arch === "arm")
return "arm";
if (arch === "aarch64" || arch === "arm64")
return "arm64";
if (arch)
return `other:${arch}`;
return "unknown";
};
var normalizePlatform = (platform) => {
platform = platform.toLowerCase();
if (platform.includes("ios"))
return "iOS";
if (platform === "android")
return "Android";
if (platform === "darwin")
return "MacOS";
if (platform === "win32")
return "Windows";
if (platform === "freebsd")
return "FreeBSD";
if (platform === "openbsd")
return "OpenBSD";
if (platform === "linux")
return "Linux";
if (platform)
return `Other:${platform}`;
return "Unknown";
};
var _platformHeaders;
var getPlatformHeaders = () => {
return _platformHeaders != null ? _platformHeaders : _platformHeaders = getPlatformProperties();
};
var safeJSON = (text) => {
try {
return JSON.parse(text);
} catch (err) {
return void 0;
}
};
var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
var isAbsoluteURL = (url) => {
return startsWithSchemeRegexp.test(url);
};
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
var validatePositiveInteger = (name, n) => {
if (typeof n !== "number" || !Number.isInteger(n)) {
throw new OpenAIError(`${name} must be an integer`);
}
if (n < 0) {
throw new OpenAIError(`${name} must be a positive integer`);
}
return n;
};
var castToError = (err) => {
if (err instanceof Error)
return err;
if (typeof err === "object" && err !== null) {
try {
return new Error(JSON.stringify(err));
} catch (e) {
}
}
return new Error(err);
};
var readEnv = (env) => {
var _a2, _b, _c, _d, _e, _f;
if (typeof process !== "undefined") {
return (_c = (_b = (_a2 = process.env) == null ? void 0 : _a2[env]) == null ? void 0 : _b.trim()) != null ? _c : void 0;
}
if (typeof Deno !== "undefined") {
return (_f = (_e = (_d = Deno.env) == null ? void 0 : _d.get) == null ? void 0 : _e.call(_d, env)) == null ? void 0 : _f.trim();
}
return void 0;
};
function isEmptyObj(obj) {
if (!obj)
return true;
for (const _k in obj)
return false;
return true;
}
function hasOwn(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
function applyHeadersMut(targetHeaders, newHeaders) {
for (const k in newHeaders) {
if (!hasOwn(newHeaders, k))
continue;
const lowerKey = k.toLowerCase();
if (!lowerKey)
continue;
const val = newHeaders[k];
if (val === null) {
delete targetHeaders[lowerKey];
} else if (val !== void 0) {
targetHeaders[lowerKey] = val;
}
}
}
function debug(action, ...args) {
var _a2;
if (typeof process !== "undefined" && ((_a2 = process == null ? void 0 : process.env) == null ? void 0 : _a2["DEBUG"]) === "true") {
console.log(`OpenAI:DEBUG:${action}`, ...args);
}
}
var uuid4 = () => {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0;
const v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
};
var isRunningInBrowser = () => {
return (
// @ts-ignore
typeof window !== "undefined" && // @ts-ignore
typeof window.document !== "undefined" && // @ts-ignore
typeof navigator !== "undefined"
);
};
var isHeadersProtocol = (headers) => {
return typeof (headers == null ? void 0 : headers.get) === "function";
};
var getHeader = (headers, header) => {
var _a2;
const lowerCasedHeader = header.toLowerCase();
if (isHeadersProtocol(headers)) {
const intercapsHeader = ((_a2 = header[0]) == null ? void 0 : _a2.toUpperCase()) + header.substring(1).replace(/([^\w])(\w)/g, (_m, g1, g2) => g1 + g2.toUpperCase());
for (const key of [header, lowerCasedHeader, header.toUpperCase(), intercapsHeader]) {
const value = headers.get(key);
if (value) {
return value;
}
}
}
for (const [key, value] of Object.entries(headers)) {
if (key.toLowerCase() === lowerCasedHeader) {
if (Array.isArray(value)) {
if (value.length <= 1)
return value[0];
console.warn(`Received ${value.length} entries for the ${header} header, using the first entry.`);
return value[0];
}
return value;
}
}
return void 0;
};
function isObj(obj) {
return obj != null && typeof obj === "object" && !Array.isArray(obj);
}
// node_modules/openai/pagination.mjs
var Page = class extends AbstractPage {
constructor(client, response, body, options) {
super(client, response, body, options);
this.data = body.data || [];
this.object = body.object;
}
getPaginatedItems() {
var _a2;
return (_a2 = this.data) != null ? _a2 : [];
}
// @deprecated Please use `nextPageInfo()` instead
/**
* This page represents a response that isn't actually paginated at the API level
* so there will never be any next page params.
*/
nextPageParams() {
return null;
}
nextPageInfo() {
return null;
}
};
var CursorPage = class extends AbstractPage {
constructor(client, response, body, options) {
super(client, response, body, options);
this.data = body.data || [];
}
getPaginatedItems() {
var _a2;
return (_a2 = this.data) != null ? _a2 : [];
}
// @deprecated Please use `nextPageInfo()` instead
nextPageParams() {
const info = this.nextPageInfo();
if (!info)
return null;
if ("params" in info)
return info.params;
const params = Object.fromEntries(info.url.searchParams);
if (!Object.keys(params).length)
return null;
return params;
}
nextPageInfo() {
var _a2;
const data = this.getPaginatedItems();
if (!data.length) {
return null;
}
const id = (_a2 = data[data.length - 1]) == null ? void 0 : _a2.id;
if (!id) {
return null;
}
return { params: { after: id } };
}
};
// node_modules/openai/resource.mjs
var APIResource = class {
constructor(client) {
this._client = client;
}
};
// node_modules/openai/resources/chat/completions.mjs
var Completions = class extends APIResource {
create(body, options) {
var _a2;
return this._client.post("/chat/completions", { body, ...options, stream: (_a2 = body.stream) != null ? _a2 : false });
}
};
// node_modules/openai/resources/chat/chat.mjs
var Chat = class extends APIResource {
constructor() {
super(...arguments);
this.completions = new Completions(this._client);
}
};
Chat.Completions = Completions;
// node_modules/openai/resources/audio/speech.mjs
var Speech = class extends APIResource {
/**
* Generates audio from the input text.
*/
create(body, options) {
return this._client.post("/audio/speech", { body, ...options, __binaryResponse: true });
}
};
// node_modules/openai/resources/audio/transcriptions.mjs
var Transcriptions = class extends APIResource {
create(body, options) {
return this._client.post("/audio/transcriptions", multipartFormRequestOptions({ body, ...options }));
}
};
// node_modules/openai/resources/audio/translations.mjs
var Translations = class extends APIResource {
create(body, options) {
return this._client.post("/audio/translations", multipartFormRequestOptions({ body, ...options }));
}
};
// node_modules/openai/resources/audio/audio.mjs
var Audio = class extends APIResource {
constructor() {
super(...arguments);
this.transcriptions = new Transcriptions(this._client);
this.translations = new Translations(this._client);
this.speech = new Speech(this._client);
}
};
Audio.Transcriptions = Transcriptions;
Audio.Translations = Translations;
Audio.Speech = Speech;
// node_modules/openai/resources/batches.mjs
var Batches = class extends APIResource {
/**
* Creates and executes a batch from an uploaded file of requests
*/
create(body, options) {
return this._client.post("/batches", { body, ...options });
}
/**
* Retrieves a batch.
*/
retrieve(batchId, options) {
return this._client.get(`/batches/${batchId}`, options);
}
list(query = {}, options) {
if (isRequestOptions(query)) {
return this.list({}, query);
}
return this._client.getAPIList("/batches", BatchesPage, { query, ...options });
}
/**
* Cancels an in-progress batch. The batch will be in status `cancelling` for up to
* 10 minutes, before changing to `cancelled`, where it will have partial results
* (if any) available in the output file.
*/
cancel(batchId, options) {
return this._client.post(`/batches/${batchId}/cancel`, options);
}
};
var BatchesPage = class extends CursorPage {
};
Batches.BatchesPage = BatchesPage;
// node_modules/openai/resources/beta/assistants.mjs
var Assistants = class extends APIResource {
/**
* Create an assistant with a model and instructions.
*/
create(body, options) {
return this._client.post("/assistants", {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Retrieves an assistant.
*/
retrieve(assistantId, options) {
return this._client.get(`/assistants/${assistantId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Modifies an assistant.
*/
update(assistantId, body, options) {
return this._client.post(`/assistants/${assistantId}`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
list(query = {}, options) {
if (isRequestOptions(query)) {
return this.list({}, query);
}
return this._client.getAPIList("/assistants", AssistantsPage, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Delete an assistant.
*/
del(assistantId, options) {
return this._client.delete(`/assistants/${assistantId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
};
var AssistantsPage = class extends CursorPage {
};
Assistants.AssistantsPage = AssistantsPage;
// node_modules/openai/lib/RunnableFunction.mjs
function isRunnableFunctionWithParse(fn) {
return typeof fn.parse === "function";
}
// node_modules/openai/lib/chatCompletionUtils.mjs
var isAssistantMessage = (message) => {
return (message == null ? void 0 : message.role) === "assistant";
};
var isFunctionMessage = (message) => {
return (message == null ? void 0 : message.role) === "function";
};
var isToolMessage = (message) => {
return (message == null ? void 0 : message.role) === "tool";
};
// node_modules/openai/lib/EventStream.mjs
var __classPrivateFieldSet2 = function(receiver, state, value, kind2, f) {
if (kind2 === "m")
throw new TypeError("Private method is not writable");
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
};
var __classPrivateFieldGet2 = function(receiver, state, kind2, f) {
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _EventStream_instances;
var _EventStream_connectedPromise;
var _EventStream_resolveConnectedPromise;
var _EventStream_rejectConnectedPromise;
var _EventStream_endPromise;
var _EventStream_resolveEndPromise;
var _EventStream_rejectEndPromise;
var _EventStream_listeners;
var _EventStream_ended;
var _EventStream_errored;
var _EventStream_aborted;
var _EventStream_catchingPromiseCreated;
var _EventStream_handleError;
var EventStream = class {
constructor() {
_EventStream_instances.add(this);
this.controller = new AbortController();
_EventStream_connectedPromise.set(this, void 0);
_EventStream_resolveConnectedPromise.set(this, () => {
});
_EventStream_rejectConnectedPromise.set(this, () => {
});
_EventStream_endPromise.set(this, void 0);
_EventStream_resolveEndPromise.set(this, () => {
});
_EventStream_rejectEndPromise.set(this, () => {
});
_EventStream_listeners.set(this, {});
_EventStream_ended.set(this, false);
_EventStream_errored.set(this, false);
_EventStream_aborted.set(this, false);
_EventStream_catchingPromiseCreated.set(this, false);
__classPrivateFieldSet2(this, _EventStream_connectedPromise, new Promise((resolve, reject) => {
__classPrivateFieldSet2(this, _EventStream_resolveConnectedPromise, resolve, "f");
__classPrivateFieldSet2(this, _EventStream_rejectConnectedPromise, reject, "f");
}), "f");
__classPrivateFieldSet2(this, _EventStream_endPromise, new Promise((resolve, reject) => {
__classPrivateFieldSet2(this, _EventStream_resolveEndPromise, resolve, "f");
__classPrivateFieldSet2(this, _EventStream_rejectEndPromise, reject, "f");
}), "f");
__classPrivateFieldGet2(this, _EventStream_connectedPromise, "f").catch(() => {
});
__classPrivateFieldGet2(this, _EventStream_endPromise, "f").catch(() => {
});
}
_run(executor) {
setTimeout(() => {
executor().then(() => {
this._emitFinal();
this._emit("end");
}, __classPrivateFieldGet2(this, _EventStream_instances, "m", _EventStream_handleError).bind(this));
}, 0);
}
_connected() {
if (this.ended)
return;
__classPrivateFieldGet2(this, _EventStream_resolveConnectedPromise, "f").call(this);
this._emit("connect");
}
get ended() {
return __classPrivateFieldGet2(this, _EventStream_ended, "f");
}
get errored() {
return __classPrivateFieldGet2(this, _EventStream_errored, "f");
}
get aborted() {
return __classPrivateFieldGet2(this, _EventStream_aborted, "f");
}
abort() {
this.controller.abort();
}
/**
* Adds the listener function to the end of the listeners array for the event.
* No checks are made to see if the listener has already been added. Multiple calls passing
* the same combination of event and listener will result in the listener being added, and
* called, multiple times.
* @returns this ChatCompletionStream, so that calls can be chained
*/
on(event, listener) {
const listeners = __classPrivateFieldGet2(this, _EventStream_listeners, "f")[event] || (__classPrivateFieldGet2(this, _EventStream_listeners, "f")[event] = []);
listeners.push({ listener });
return this;
}
/**
* Removes the specified listener from the listener array for the event.
* off() will remove, at most, one instance of a listener from the listener array. If any single
* listener has been added multiple times to the listener array for the specified event, then
* off() must be called multiple times to remove each instance.
* @returns this ChatCompletionStream, so that calls can be chained
*/
off(event, listener) {
const listeners = __classPrivateFieldGet2(this, _EventStream_listeners, "f")[event];
if (!listeners)
return this;
const index = listeners.findIndex((l) => l.listener === listener);
if (index >= 0)
listeners.splice(index, 1);
return this;
}
/**
* Adds a one-time listener function for the event. The next time the event is triggered,
* this listener is removed and then invoked.
* @returns this ChatCompletionStream, so that calls can be chained
*/
once(event, listener) {
const listeners = __classPrivateFieldGet2(this, _EventStream_listeners, "f")[event] || (__classPrivateFieldGet2(this, _EventStream_listeners, "f")[event] = []);
listeners.push({ listener, once: true });
return this;
}
/**
* This is similar to `.once()`, but returns a Promise that resolves the next time
* the event is triggered, instead of calling a listener callback.
* @returns a Promise that resolves the next time given event is triggered,
* or rejects if an error is emitted. (If you request the 'error' event,
* returns a promise that resolves with the error).
*
* Example:
*
* const message = await stream.emitted('message') // rejects if the stream errors
*/
emitted(event) {
return new Promise((resolve, reject) => {
__classPrivateFieldSet2(this, _EventStream_catchingPromiseCreated, true, "f");
if (event !== "error")
this.once("error", reject);
this.once(event, resolve);
});
}
async done() {
__classPrivateFieldSet2(this, _EventStream_catchingPromiseCreated, true, "f");
await __classPrivateFieldGet2(this, _EventStream_endPromise, "f");
}
_emit(event, ...args) {
if (__classPrivateFieldGet2(this, _EventStream_ended, "f")) {
return;
}
if (event === "end") {
__classPrivateFieldSet2(this, _EventStream_ended, true, "f");
__classPrivateFieldGet2(this, _EventStream_resolveEndPromise, "f").call(this);
}
const listeners = __classPrivateFieldGet2(this, _EventStream_listeners, "f")[event];
if (listeners) {
__classPrivateFieldGet2(this, _EventStream_listeners, "f")[event] = listeners.filter((l) => !l.once);
listeners.forEach(({ listener }) => listener(...args));
}
if (event === "abort") {
const error = args[0];
if (!__classPrivateFieldGet2(this, _EventStream_catchingPromiseCreated, "f") && !(listeners == null ? void 0 : listeners.length)) {
Promise.reject(error);
}
__classPrivateFieldGet2(this, _EventStream_rejectConnectedPromise, "f").call(this, error);
__classPrivateFieldGet2(this, _EventStream_rejectEndPromise, "f").call(this, error);
this._emit("end");
return;
}
if (event === "error") {
const error = args[0];
if (!__classPrivateFieldGet2(this, _EventStream_catchingPromiseCreated, "f") && !(listeners == null ? void 0 : listeners.length)) {
Promise.reject(error);
}
__classPrivateFieldGet2(this, _EventStream_rejectConnectedPromise, "f").call(this, error);
__classPrivateFieldGet2(this, _EventStream_rejectEndPromise, "f").call(this, error);
this._emit("end");
}
}
_emitFinal() {
}
};
_EventStream_connectedPromise = /* @__PURE__ */ new WeakMap(), _EventStream_resolveConnectedPromise = /* @__PURE__ */ new WeakMap(), _EventStream_rejectConnectedPromise = /* @__PURE__ */ new WeakMap(), _EventStream_endPromise = /* @__PURE__ */ new WeakMap(), _EventStream_resolveEndPromise = /* @__PURE__ */ new WeakMap(), _EventStream_rejectEndPromise = /* @__PURE__ */ new WeakMap(), _EventStream_listeners = /* @__PURE__ */ new WeakMap(), _EventStream_ended = /* @__PURE__ */ new WeakMap(), _EventStream_errored = /* @__PURE__ */ new WeakMap(), _EventStream_aborted = /* @__PURE__ */ new WeakMap(), _EventStream_catchingPromiseCreated = /* @__PURE__ */ new WeakMap(), _EventStream_instances = /* @__PURE__ */ new WeakSet(), _EventStream_handleError = function _EventStream_handleError2(error) {
__classPrivateFieldSet2(this, _EventStream_errored, true, "f");
if (error instanceof Error && error.name === "AbortError") {
error = new APIUserAbortError();
}
if (error instanceof APIUserAbortError) {
__classPrivateFieldSet2(this, _EventStream_aborted, true, "f");
return this._emit("abort", error);
}
if (error instanceof OpenAIError) {
return this._emit("error", error);
}
if (error instanceof Error) {
const openAIError = new OpenAIError(error.message);
openAIError.cause = error;
return this._emit("error", openAIError);
}
return this._emit("error", new OpenAIError(String(error)));
};
// node_modules/openai/lib/parser.mjs
function isAutoParsableResponseFormat(response_format) {
return (response_format == null ? void 0 : response_format["$brand"]) === "auto-parseable-response-format";
}
function isAutoParsableTool(tool) {
return (tool == null ? void 0 : tool["$brand"]) === "auto-parseable-tool";
}
function maybeParseChatCompletion(completion, params) {
if (!params || !hasAutoParseableInput(params)) {
return {
...completion,
choices: completion.choices.map((choice) => {
var _a2;
return {
...choice,
message: { ...choice.message, parsed: null, tool_calls: (_a2 = choice.message.tool_calls) != null ? _a2 : [] }
};
})
};
}
return parseChatCompletion(completion, params);
}
function parseChatCompletion(completion, params) {
const choices = completion.choices.map((choice) => {
var _a2, _b;
if (choice.finish_reason === "length") {
throw new LengthFinishReasonError();
}
if (choice.finish_reason === "content_filter") {
throw new ContentFilterFinishReasonError();
}
return {
...choice,
message: {
...choice.message,
tool_calls: (_b = (_a2 = choice.message.tool_calls) == null ? void 0 : _a2.map((toolCall) => parseToolCall(params, toolCall))) != null ? _b : [],
parsed: choice.message.content && !choice.message.refusal ? parseResponseFormat(params, choice.message.content) : null
}
};
});
return { ...completion, choices };
}
function parseResponseFormat(params, content) {
var _a2, _b;
if (((_a2 = params.response_format) == null ? void 0 : _a2.type) !== "json_schema") {
return null;
}
if (((_b = params.response_format) == null ? void 0 : _b.type) === "json_schema") {
if ("$parseRaw" in params.response_format) {
const response_format = params.response_format;
return response_format.$parseRaw(content);
}
return JSON.parse(content);
}
return null;
}
function parseToolCall(params, toolCall) {
var _a2;
const inputTool = (_a2 = params.tools) == null ? void 0 : _a2.find((inputTool2) => {
var _a3;
return ((_a3 = inputTool2.function) == null ? void 0 : _a3.name) === toolCall.function.name;
});
return {
...toolCall,
function: {
...toolCall.function,
parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCall.function.arguments) : (inputTool == null ? void 0 : inputTool.function.strict) ? JSON.parse(toolCall.function.arguments) : null
}
};
}
function shouldParseToolCall(params, toolCall) {
var _a2;
if (!params) {
return false;
}
const inputTool = (_a2 = params.tools) == null ? void 0 : _a2.find((inputTool2) => {
var _a3;
return ((_a3 = inputTool2.function) == null ? void 0 : _a3.name) === toolCall.function.name;
});
return isAutoParsableTool(inputTool) || (inputTool == null ? void 0 : inputTool.function.strict) || false;
}
function hasAutoParseableInput(params) {
var _a2, _b;
if (isAutoParsableResponseFormat(params.response_format)) {
return true;
}
return (_b = (_a2 = params.tools) == null ? void 0 : _a2.some((t) => isAutoParsableTool(t) || t.type === "function" && t.function.strict === true)) != null ? _b : false;
}
function validateInputTools(tools) {
for (const tool of tools != null ? tools : []) {
if (tool.type !== "function") {
throw new OpenAIError(`Currently only \`function\` tool types support auto-parsing; Received \`${tool.type}\``);
}
if (tool.function.strict !== true) {
throw new OpenAIError(`The \`${tool.function.name}\` tool is not marked with \`strict: true\`. Only strict function tools can be auto-parsed`);
}
}
}
// node_modules/openai/lib/AbstractChatCompletionRunner.mjs
var __classPrivateFieldGet3 = function(receiver, state, kind2, f) {
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _AbstractChatCompletionRunner_instances;
var _AbstractChatCompletionRunner_getFinalContent;
var _AbstractChatCompletionRunner_getFinalMessage;
var _AbstractChatCompletionRunner_getFinalFunctionCall;
var _AbstractChatCompletionRunner_getFinalFunctionCallResult;
var _AbstractChatCompletionRunner_calculateTotalUsage;
var _AbstractChatCompletionRunner_validateParams;
var _AbstractChatCompletionRunner_stringifyFunctionCallResult;
var DEFAULT_MAX_CHAT_COMPLETIONS = 10;
var AbstractChatCompletionRunner = class extends EventStream {
constructor() {
super(...arguments);
_AbstractChatCompletionRunner_instances.add(this);
this._chatCompletions = [];
this.messages = [];
}
_addChatCompletion(chatCompletion) {
var _a2;
this._chatCompletions.push(chatCompletion);
this._emit("chatCompletion", chatCompletion);
const message = (_a2 = chatCompletion.choices[0]) == null ? void 0 : _a2.message;
if (message)
this._addMessage(message);
return chatCompletion;
}
_addMessage(message, emit = true) {
if (!("content" in message))
message.content = null;
this.messages.push(message);
if (emit) {
this._emit("message", message);
if ((isFunctionMessage(message) || isToolMessage(message)) && message.content) {
this._emit("functionCallResult", message.content);
} else if (isAssistantMessage(message) && message.function_call) {
this._emit("functionCall", message.function_call);
} else if (isAssistantMessage(message) && message.tool_calls) {
for (const tool_call of message.tool_calls) {
if (tool_call.type === "function") {
this._emit("functionCall", tool_call.function);
}
}
}
}
}
/**
* @returns a promise that resolves with the final ChatCompletion, or rejects
* if an error occurred or the stream ended prematurely without producing a ChatCompletion.
*/
async finalChatCompletion() {
await this.done();
const completion = this._chatCompletions[this._chatCompletions.length - 1];
if (!completion)
throw new OpenAIError("stream ended without producing a ChatCompletion");
return completion;
}
/**
* @returns a promise that resolves with the content of the final ChatCompletionMessage, or rejects
* if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage.
*/
async finalContent() {
await this.done();
return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this);
}
/**
* @returns a promise that resolves with the the final assistant ChatCompletionMessage response,
* or rejects if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage.
*/
async finalMessage() {
await this.done();
return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this);
}
/**
* @returns a promise that resolves with the content of the final FunctionCall, or rejects
* if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage.
*/
async finalFunctionCall() {
await this.done();
return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCall).call(this);
}
async finalFunctionCallResult() {
await this.done();
return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCallResult).call(this);
}
async totalUsage() {
await this.done();
return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this);
}
allChatCompletions() {
return [...this._chatCompletions];
}
_emitFinal() {
const completion = this._chatCompletions[this._chatCompletions.length - 1];
if (completion)
this._emit("finalChatCompletion", completion);
const finalMessage = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this);
if (finalMessage)
this._emit("finalMessage", finalMessage);
const finalContent = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this);
if (finalContent)
this._emit("finalContent", finalContent);
const finalFunctionCall = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCall).call(this);
if (finalFunctionCall)
this._emit("finalFunctionCall", finalFunctionCall);
const finalFunctionCallResult = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCallResult).call(this);
if (finalFunctionCallResult != null)
this._emit("finalFunctionCallResult", finalFunctionCallResult);
if (this._chatCompletions.some((c) => c.usage)) {
this._emit("totalUsage", __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this));
}
}
async _createChatCompletion(client, params, options) {
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_validateParams).call(this, params);
const chatCompletion = await client.chat.completions.create({ ...params, stream: false }, { ...options, signal: this.controller.signal });
this._connected();
return this._addChatCompletion(parseChatCompletion(chatCompletion, params));
}
async _runChatCompletion(client, params, options) {
for (const message of params.messages) {
this._addMessage(message, false);
}
return await this._createChatCompletion(client, params, options);
}
async _runFunctions(client, params, options) {
var _a2;
const role = "function";
const { function_call = "auto", stream, ...restParams } = params;
const singleFunctionToCall = typeof function_call !== "string" && (function_call == null ? void 0 : function_call.name);
const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {};
const functionsByName = {};
for (const f of params.functions) {
functionsByName[f.name || f.function.name] = f;
}
const functions = params.functions.map((f) => ({
name: f.name || f.function.name,
parameters: f.parameters,
description: f.description
}));
for (const message of params.messages) {
this._addMessage(message, false);
}
for (let i = 0; i < maxChatCompletions; ++i) {
const chatCompletion = await this._createChatCompletion(client, {
...restParams,
function_call,
functions,
messages: [...this.messages]
}, options);
const message = (_a2 = chatCompletion.choices[0]) == null ? void 0 : _a2.message;
if (!message) {
throw new OpenAIError(`missing message in ChatCompletion response`);
}
if (!message.function_call)
return;
const { name, arguments: args } = message.function_call;
const fn = functionsByName[name];
if (!fn) {
const content2 = `Invalid function_call: ${JSON.stringify(name)}. Available options are: ${functions.map((f) => JSON.stringify(f.name)).join(", ")}. Please try again`;
this._addMessage({ role, name, content: content2 });
continue;
} else if (singleFunctionToCall && singleFunctionToCall !== name) {
const content2 = `Invalid function_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`;
this._addMessage({ role, name, content: content2 });
continue;
}
let parsed;
try {
parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args;
} catch (error) {
this._addMessage({
role,
name,
content: error instanceof Error ? error.message : String(error)
});
continue;
}
const rawContent = await fn.function(parsed, this);
const content = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent);
this._addMessage({ role, name, content });
if (singleFunctionToCall)
return;
}
}
async _runTools(client, params, options) {
var _a2, _b, _c;
const role = "tool";
const { tool_choice = "auto", stream, ...restParams } = params;
const singleFunctionToCall = typeof tool_choice !== "string" && ((_a2 = tool_choice == null ? void 0 : tool_choice.function) == null ? void 0 : _a2.name);
const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {};
const inputTools = params.tools.map((tool) => {
if (isAutoParsableTool(tool)) {
if (!tool.$callback) {
throw new OpenAIError("Tool given to `.runTools()` that does not have an associated function");
}
return {
type: "function",
function: {
function: tool.$callback,
name: tool.function.name,
description: tool.function.description || "",
parameters: tool.function.parameters,
parse: tool.$parseRaw,
strict: true
}
};
}
return tool;
});
const functionsByName = {};
for (const f of inputTools) {
if (f.type === "function") {
functionsByName[f.function.name || f.function.function.name] = f.function;
}
}
const tools = "tools" in params ? inputTools.map((t) => t.type === "function" ? {
type: "function",
function: {
name: t.function.name || t.function.function.name,
parameters: t.function.parameters,
description: t.function.description,
strict: t.function.strict
}
} : t) : void 0;
for (const message of params.messages) {
this._addMessage(message, false);
}
for (let i = 0; i < maxChatCompletions; ++i) {
const chatCompletion = await this._createChatCompletion(client, {
...restParams,
tool_choice,
tools,
messages: [...this.messages]
}, options);
const message = (_b = chatCompletion.choices[0]) == null ? void 0 : _b.message;
if (!message) {
throw new OpenAIError(`missing message in ChatCompletion response`);
}
if (!((_c = message.tool_calls) == null ? void 0 : _c.length)) {
return;
}
for (const tool_call of message.tool_calls) {
if (tool_call.type !== "function")
continue;
const tool_call_id = tool_call.id;
const { name, arguments: args } = tool_call.function;
const fn = functionsByName[name];
if (!fn) {
const content2 = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${Object.keys(functionsByName).map((name2) => JSON.stringify(name2)).join(", ")}. Please try again`;
this._addMessage({ role, tool_call_id, content: content2 });
continue;
} else if (singleFunctionToCall && singleFunctionToCall !== name) {
const content2 = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`;
this._addMessage({ role, tool_call_id, content: content2 });
continue;
}
let parsed;
try {
parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args;
} catch (error) {
const content2 = error instanceof Error ? error.message : String(error);
this._addMessage({ role, tool_call_id, content: content2 });
continue;
}
const rawContent = await fn.function(parsed, this);
const content = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent);
this._addMessage({ role, tool_call_id, content });
if (singleFunctionToCall) {
return;
}
}
}
return;
}
};
_AbstractChatCompletionRunner_instances = /* @__PURE__ */ new WeakSet(), _AbstractChatCompletionRunner_getFinalContent = function _AbstractChatCompletionRunner_getFinalContent2() {
var _a2;
return (_a2 = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this).content) != null ? _a2 : null;
}, _AbstractChatCompletionRunner_getFinalMessage = function _AbstractChatCompletionRunner_getFinalMessage2() {
var _a2, _b;
let i = this.messages.length;
while (i-- > 0) {
const message = this.messages[i];
if (isAssistantMessage(message)) {
const { function_call, ...rest } = message;
const ret = {
...rest,
content: (_a2 = message.content) != null ? _a2 : null,
refusal: (_b = message.refusal) != null ? _b : null
};
if (function_call) {
ret.function_call = function_call;
}
return ret;
}
}
throw new OpenAIError("stream ended without producing a ChatCompletionMessage with role=assistant");
}, _AbstractChatCompletionRunner_getFinalFunctionCall = function _AbstractChatCompletionRunner_getFinalFunctionCall2() {
var _a2, _b;
for (let i = this.messages.length - 1; i >= 0; i--) {
const message = this.messages[i];
if (isAssistantMessage(message) && (message == null ? void 0 : message.function_call)) {
return message.function_call;
}
if (isAssistantMessage(message) && ((_a2 = message == null ? void 0 : message.tool_calls) == null ? void 0 : _a2.length)) {
return (_b = message.tool_calls.at(-1)) == null ? void 0 : _b.function;
}
}
return;
}, _AbstractChatCompletionRunner_getFinalFunctionCallResult = function _AbstractChatCompletionRunner_getFinalFunctionCallResult2() {
for (let i = this.messages.length - 1; i >= 0; i--) {
const message = this.messages[i];
if (isFunctionMessage(message) && message.content != null) {
return message.content;
}
if (isToolMessage(message) && message.content != null && typeof message.content === "string" && this.messages.some((x) => {
var _a2;
return x.role === "assistant" && ((_a2 = x.tool_calls) == null ? void 0 : _a2.some((y) => y.type === "function" && y.id === message.tool_call_id));
})) {
return message.content;
}
}
return;
}, _AbstractChatCompletionRunner_calculateTotalUsage = function _AbstractChatCompletionRunner_calculateTotalUsage2() {
const total = {
completion_tokens: 0,
prompt_tokens: 0,
total_tokens: 0
};
for (const { usage } of this._chatCompletions) {
if (usage) {
total.completion_tokens += usage.completion_tokens;
total.prompt_tokens += usage.prompt_tokens;
total.total_tokens += usage.total_tokens;
}
}
return total;
}, _AbstractChatCompletionRunner_validateParams = function _AbstractChatCompletionRunner_validateParams2(params) {
if (params.n != null && params.n > 1) {
throw new OpenAIError("ChatCompletion convenience helpers only support n=1 at this time. To use n>1, please use chat.completions.create() directly.");
}
}, _AbstractChatCompletionRunner_stringifyFunctionCallResult = function _AbstractChatCompletionRunner_stringifyFunctionCallResult2(rawContent) {
return typeof rawContent === "string" ? rawContent : rawContent === void 0 ? "undefined" : JSON.stringify(rawContent);
};
// node_modules/openai/lib/ChatCompletionRunner.mjs
var ChatCompletionRunner = class _ChatCompletionRunner extends AbstractChatCompletionRunner {
/** @deprecated - please use `runTools` instead. */
static runFunctions(client, params, options) {
const runner = new _ChatCompletionRunner();
const opts = {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "runFunctions" }
};
runner._run(() => runner._runFunctions(client, params, opts));
return runner;
}
static runTools(client, params, options) {
const runner = new _ChatCompletionRunner();
const opts = {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "runTools" }
};
runner._run(() => runner._runTools(client, params, opts));
return runner;
}
_addMessage(message, emit = true) {
super._addMessage(message, emit);
if (isAssistantMessage(message) && message.content) {
this._emit("content", message.content);
}
}
};
// node_modules/openai/_vendor/partial-json-parser/parser.mjs
var STR = 1;
var NUM = 2;
var ARR = 4;
var OBJ = 8;
var NULL = 16;
var BOOL = 32;
var NAN = 64;
var INFINITY = 128;
var MINUS_INFINITY = 256;
var INF = INFINITY | MINUS_INFINITY;
var SPECIAL = NULL | BOOL | INF | NAN;
var ATOM = STR | NUM | SPECIAL;
var COLLECTION = ARR | OBJ;
var ALL = ATOM | COLLECTION;
var Allow = {
STR,
NUM,
ARR,
OBJ,
NULL,
BOOL,
NAN,
INFINITY,
MINUS_INFINITY,
INF,
SPECIAL,
ATOM,
COLLECTION,
ALL
};
var PartialJSON = class extends Error {
};
var MalformedJSON = class extends Error {
};
function parseJSON(jsonString, allowPartial = Allow.ALL) {
if (typeof jsonString !== "string") {
throw new TypeError(`expecting str, got ${typeof jsonString}`);
}
if (!jsonString.trim()) {
throw new Error(`${jsonString} is empty`);
}
return _parseJSON(jsonString.trim(), allowPartial);
}
var _parseJSON = (jsonString, allow) => {
const length = jsonString.length;
let index = 0;
const markPartialJSON = (msg) => {
throw new PartialJSON(`${msg} at position ${index}`);
};
const throwMalformedError = (msg) => {
throw new MalformedJSON(`${msg} at position ${index}`);
};
const parseAny = () => {
skipBlank();
if (index >= length)
markPartialJSON("Unexpected end of input");
if (jsonString[index] === '"')
return parseStr();
if (jsonString[index] === "{")
return parseObj();
if (jsonString[index] === "[")
return parseArr();
if (jsonString.substring(index, index + 4) === "null" || Allow.NULL & allow && length - index < 4 && "null".startsWith(jsonString.substring(index))) {
index += 4;
return null;
}
if (jsonString.substring(index, index + 4) === "true" || Allow.BOOL & allow && length - index < 4 && "true".startsWith(jsonString.substring(index))) {
index += 4;
return true;
}
if (jsonString.substring(index, index + 5) === "false" || Allow.BOOL & allow && length - index < 5 && "false".startsWith(jsonString.substring(index))) {
index += 5;
return false;
}
if (jsonString.substring(index, index + 8) === "Infinity" || Allow.INFINITY & allow && length - index < 8 && "Infinity".startsWith(jsonString.substring(index))) {
index += 8;
return Infinity;
}
if (jsonString.substring(index, index + 9) === "-Infinity" || Allow.MINUS_INFINITY & allow && 1 < length - index && length - index < 9 && "-Infinity".startsWith(jsonString.substring(index))) {
index += 9;
return -Infinity;
}
if (jsonString.substring(index, index + 3) === "NaN" || Allow.NAN & allow && length - index < 3 && "NaN".startsWith(jsonString.substring(index))) {
index += 3;
return NaN;
}
return parseNum();
};
const parseStr = () => {
const start = index;
let escape2 = false;
index++;
while (index < length && (jsonString[index] !== '"' || escape2 && jsonString[index - 1] === "\\")) {
escape2 = jsonString[index] === "\\" ? !escape2 : false;
index++;
}
if (jsonString.charAt(index) == '"') {
try {
return JSON.parse(jsonString.substring(start, ++index - Number(escape2)));
} catch (e) {
throwMalformedError(String(e));
}
} else if (Allow.STR & allow) {
try {
return JSON.parse(jsonString.substring(start, index - Number(escape2)) + '"');
} catch (e) {
return JSON.parse(jsonString.substring(start, jsonString.lastIndexOf("\\")) + '"');
}
}
markPartialJSON("Unterminated string literal");
};
const parseObj = () => {
index++;
skipBlank();
const obj = {};
try {
while (jsonString[index] !== "}") {
skipBlank();
if (index >= length && Allow.OBJ & allow)
return obj;
const key = parseStr();
skipBlank();
index++;
try {
const value = parseAny();
Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
} catch (e) {
if (Allow.OBJ & allow)
return obj;
else
throw e;
}
skipBlank();
if (jsonString[index] === ",")
index++;
}
} catch (e) {
if (Allow.OBJ & allow)
return obj;
else
markPartialJSON("Expected '}' at end of object");
}
index++;
return obj;
};
const parseArr = () => {
index++;
const arr = [];
try {
while (jsonString[index] !== "]") {
arr.push(parseAny());
skipBlank();
if (jsonString[index] === ",") {
index++;
}
}
} catch (e) {
if (Allow.ARR & allow) {
return arr;
}
markPartialJSON("Expected ']' at end of array");
}
index++;
return arr;
};
const parseNum = () => {
if (index === 0) {
if (jsonString === "-" && Allow.NUM & allow)
markPartialJSON("Not sure what '-' is");
try {
return JSON.parse(jsonString);
} catch (e) {
if (Allow.NUM & allow) {
try {
if ("." === jsonString[jsonString.length - 1])
return JSON.parse(jsonString.substring(0, jsonString.lastIndexOf(".")));
return JSON.parse(jsonString.substring(0, jsonString.lastIndexOf("e")));
} catch (e2) {
}
}
throwMalformedError(String(e));
}
}
const start = index;
if (jsonString[index] === "-")
index++;
while (jsonString[index] && !",]}".includes(jsonString[index]))
index++;
if (index == length && !(Allow.NUM & allow))
markPartialJSON("Unterminated number literal");
try {
return JSON.parse(jsonString.substring(start, index));
} catch (e) {
if (jsonString.substring(start, index) === "-" && Allow.NUM & allow)
markPartialJSON("Not sure what '-' is");
try {
return JSON.parse(jsonString.substring(start, jsonString.lastIndexOf("e")));
} catch (e2) {
throwMalformedError(String(e2));
}
}
};
const skipBlank = () => {
while (index < length && " \n\r ".includes(jsonString[index])) {
index++;
}
};
return parseAny();
};
var partialParse = (input) => parseJSON(input, Allow.ALL ^ Allow.NUM);
// node_modules/openai/lib/ChatCompletionStream.mjs
var __classPrivateFieldSet3 = function(receiver, state, value, kind2, f) {
if (kind2 === "m")
throw new TypeError("Private method is not writable");
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
};
var __classPrivateFieldGet4 = function(receiver, state, kind2, f) {
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _ChatCompletionStream_instances;
var _ChatCompletionStream_params;
var _ChatCompletionStream_choiceEventStates;
var _ChatCompletionStream_currentChatCompletionSnapshot;
var _ChatCompletionStream_beginRequest;
var _ChatCompletionStream_getChoiceEventState;
var _ChatCompletionStream_addChunk;
var _ChatCompletionStream_emitToolCallDoneEvent;
var _ChatCompletionStream_emitContentDoneEvents;
var _ChatCompletionStream_endRequest;
var _ChatCompletionStream_getAutoParseableResponseFormat;
var _ChatCompletionStream_accumulateChatCompletion;
var ChatCompletionStream = class _ChatCompletionStream extends AbstractChatCompletionRunner {
constructor(params) {
super();
_ChatCompletionStream_instances.add(this);
_ChatCompletionStream_params.set(this, void 0);
_ChatCompletionStream_choiceEventStates.set(this, void 0);
_ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0);
__classPrivateFieldSet3(this, _ChatCompletionStream_params, params, "f");
__classPrivateFieldSet3(this, _ChatCompletionStream_choiceEventStates, [], "f");
}
get currentChatCompletionSnapshot() {
return __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
}
/**
* Intended for use on the frontend, consuming a stream produced with
* `.toReadableStream()` on the backend.
*
* Note that messages sent to the model do not appear in `.on('message')`
* in this context.
*/
static fromReadableStream(stream) {
const runner = new _ChatCompletionStream(null);
runner._run(() => runner._fromReadableStream(stream));
return runner;
}
static createChatCompletion(client, params, options) {
const runner = new _ChatCompletionStream(params);
runner._run(() => runner._runChatCompletion(client, { ...params, stream: true }, { ...options, headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "stream" } }));
return runner;
}
async _createChatCompletion(client, params, options) {
var _a2;
super._createChatCompletion;
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
const stream = await client.chat.completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal });
this._connected();
for await (const chunk of stream) {
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
}
if ((_a2 = stream.controller.signal) == null ? void 0 : _a2.aborted) {
throw new APIUserAbortError();
}
return this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
}
async _fromReadableStream(readableStream, options) {
var _a2;
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this);
this._connected();
const stream = Stream.fromReadableStream(readableStream, this.controller);
let chatId;
for await (const chunk of stream) {
if (chatId && chatId !== chunk.id) {
this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
}
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk);
chatId = chunk.id;
}
if ((_a2 = stream.controller.signal) == null ? void 0 : _a2.aborted) {
throw new APIUserAbortError();
}
return this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this));
}
[(_ChatCompletionStream_params = /* @__PURE__ */ new WeakMap(), _ChatCompletionStream_choiceEventStates = /* @__PURE__ */ new WeakMap(), _ChatCompletionStream_currentChatCompletionSnapshot = /* @__PURE__ */ new WeakMap(), _ChatCompletionStream_instances = /* @__PURE__ */ new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest2() {
if (this.ended)
return;
__classPrivateFieldSet3(this, _ChatCompletionStream_currentChatCompletionSnapshot, void 0, "f");
}, _ChatCompletionStream_getChoiceEventState = function _ChatCompletionStream_getChoiceEventState2(choice) {
let state = __classPrivateFieldGet4(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index];
if (state) {
return state;
}
state = {
content_done: false,
refusal_done: false,
logprobs_content_done: false,
logprobs_refusal_done: false,
done_tool_calls: /* @__PURE__ */ new Set(),
current_tool_call_index: null
};
__classPrivateFieldGet4(this, _ChatCompletionStream_choiceEventStates, "f")[choice.index] = state;
return state;
}, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk2(chunk) {
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
if (this.ended)
return;
const completion = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk);
this._emit("chunk", chunk, completion);
for (const choice of chunk.choices) {
const choiceSnapshot = completion.choices[choice.index];
if (choice.delta.content != null && ((_a2 = choiceSnapshot.message) == null ? void 0 : _a2.role) === "assistant" && ((_b = choiceSnapshot.message) == null ? void 0 : _b.content)) {
this._emit("content", choice.delta.content, choiceSnapshot.message.content);
this._emit("content.delta", {
delta: choice.delta.content,
snapshot: choiceSnapshot.message.content,
parsed: choiceSnapshot.message.parsed
});
}
if (choice.delta.refusal != null && ((_c = choiceSnapshot.message) == null ? void 0 : _c.role) === "assistant" && ((_d = choiceSnapshot.message) == null ? void 0 : _d.refusal)) {
this._emit("refusal.delta", {
delta: choice.delta.refusal,
snapshot: choiceSnapshot.message.refusal
});
}
if (((_e = choice.logprobs) == null ? void 0 : _e.content) != null && ((_f = choiceSnapshot.message) == null ? void 0 : _f.role) === "assistant") {
this._emit("logprobs.content.delta", {
content: (_g = choice.logprobs) == null ? void 0 : _g.content,
snapshot: (_i = (_h = choiceSnapshot.logprobs) == null ? void 0 : _h.content) != null ? _i : []
});
}
if (((_j = choice.logprobs) == null ? void 0 : _j.refusal) != null && ((_k = choiceSnapshot.message) == null ? void 0 : _k.role) === "assistant") {
this._emit("logprobs.refusal.delta", {
refusal: (_l = choice.logprobs) == null ? void 0 : _l.refusal,
snapshot: (_n = (_m = choiceSnapshot.logprobs) == null ? void 0 : _m.refusal) != null ? _n : []
});
}
const state = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
if (choiceSnapshot.finish_reason) {
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
if (state.current_tool_call_index != null) {
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
}
}
for (const toolCall of (_o = choice.delta.tool_calls) != null ? _o : []) {
if (state.current_tool_call_index !== toolCall.index) {
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitContentDoneEvents).call(this, choiceSnapshot);
if (state.current_tool_call_index != null) {
__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_emitToolCallDoneEvent).call(this, choiceSnapshot, state.current_tool_call_index);
}
}
state.current_tool_call_index = toolCall.index;
}
for (const toolCallDelta of (_p = choice.delta.tool_calls) != null ? _p : []) {
const toolCallSnapshot = (_q = choiceSnapshot.message.tool_calls) == null ? void 0 : _q[toolCallDelta.index];
if (!(toolCallSnapshot == null ? void 0 : toolCallSnapshot.type)) {
continue;
}
if ((toolCallSnapshot == null ? void 0 : toolCallSnapshot.type) === "function") {
this._emit("tool_calls.function.arguments.delta", {
name: (_r = toolCallSnapshot.function) == null ? void 0 : _r.name,
index: toolCallDelta.index,
arguments: toolCallSnapshot.function.arguments,
parsed_arguments: toolCallSnapshot.function.parsed_arguments,
arguments_delta: (_t = (_s = toolCallDelta.function) == null ? void 0 : _s.arguments) != null ? _t : ""
});
} else {
assertNever(toolCallSnapshot == null ? void 0 : toolCallSnapshot.type);
}
}
}
}, _ChatCompletionStream_emitToolCallDoneEvent = function _ChatCompletionStream_emitToolCallDoneEvent2(choiceSnapshot, toolCallIndex) {
var _a2, _b, _c;
const state = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
if (state.done_tool_calls.has(toolCallIndex)) {
return;
}
const toolCallSnapshot = (_a2 = choiceSnapshot.message.tool_calls) == null ? void 0 : _a2[toolCallIndex];
if (!toolCallSnapshot) {
throw new Error("no tool call snapshot");
}
if (!toolCallSnapshot.type) {
throw new Error("tool call snapshot missing `type`");
}
if (toolCallSnapshot.type === "function") {
const inputTool = (_c = (_b = __classPrivateFieldGet4(this, _ChatCompletionStream_params, "f")) == null ? void 0 : _b.tools) == null ? void 0 : _c.find((tool) => tool.type === "function" && tool.function.name === toolCallSnapshot.function.name);
this._emit("tool_calls.function.arguments.done", {
name: toolCallSnapshot.function.name,
index: toolCallIndex,
arguments: toolCallSnapshot.function.arguments,
parsed_arguments: isAutoParsableTool(inputTool) ? inputTool.$parseRaw(toolCallSnapshot.function.arguments) : (inputTool == null ? void 0 : inputTool.function.strict) ? JSON.parse(toolCallSnapshot.function.arguments) : null
});
} else {
assertNever(toolCallSnapshot.type);
}
}, _ChatCompletionStream_emitContentDoneEvents = function _ChatCompletionStream_emitContentDoneEvents2(choiceSnapshot) {
var _a2, _b;
const state = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getChoiceEventState).call(this, choiceSnapshot);
if (choiceSnapshot.message.content && !state.content_done) {
state.content_done = true;
const responseFormat = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this);
this._emit("content.done", {
content: choiceSnapshot.message.content,
parsed: responseFormat ? responseFormat.$parseRaw(choiceSnapshot.message.content) : null
});
}
if (choiceSnapshot.message.refusal && !state.refusal_done) {
state.refusal_done = true;
this._emit("refusal.done", { refusal: choiceSnapshot.message.refusal });
}
if (((_a2 = choiceSnapshot.logprobs) == null ? void 0 : _a2.content) && !state.logprobs_content_done) {
state.logprobs_content_done = true;
this._emit("logprobs.content.done", { content: choiceSnapshot.logprobs.content });
}
if (((_b = choiceSnapshot.logprobs) == null ? void 0 : _b.refusal) && !state.logprobs_refusal_done) {
state.logprobs_refusal_done = true;
this._emit("logprobs.refusal.done", { refusal: choiceSnapshot.logprobs.refusal });
}
}, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest2() {
if (this.ended) {
throw new OpenAIError(`stream has ended, this shouldn't happen`);
}
const snapshot = __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
if (!snapshot) {
throw new OpenAIError(`request ended without sending any chunks`);
}
__classPrivateFieldSet3(this, _ChatCompletionStream_currentChatCompletionSnapshot, void 0, "f");
__classPrivateFieldSet3(this, _ChatCompletionStream_choiceEventStates, [], "f");
return finalizeChatCompletion(snapshot, __classPrivateFieldGet4(this, _ChatCompletionStream_params, "f"));
}, _ChatCompletionStream_getAutoParseableResponseFormat = function _ChatCompletionStream_getAutoParseableResponseFormat2() {
var _a2;
const responseFormat = (_a2 = __classPrivateFieldGet4(this, _ChatCompletionStream_params, "f")) == null ? void 0 : _a2.response_format;
if (isAutoParsableResponseFormat(responseFormat)) {
return responseFormat;
}
return null;
}, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion2(chunk) {
var _a3, _b2, _c2, _d2, _e, _f;
var _a2, _b, _c, _d;
let snapshot = __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f");
const { choices, ...rest } = chunk;
if (!snapshot) {
snapshot = __classPrivateFieldSet3(this, _ChatCompletionStream_currentChatCompletionSnapshot, {
...rest,
choices: []
}, "f");
} else {
Object.assign(snapshot, rest);
}
for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) {
let choice = snapshot.choices[index];
if (!choice) {
choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other };
}
if (logprobs) {
if (!choice.logprobs) {
choice.logprobs = Object.assign({}, logprobs);
} else {
const { content: content2, refusal: refusal2, ...rest3 } = logprobs;
assertIsEmpty(rest3);
Object.assign(choice.logprobs, rest3);
if (content2) {
(_a3 = (_a2 = choice.logprobs).content) != null ? _a3 : _a2.content = [];
choice.logprobs.content.push(...content2);
}
if (refusal2) {
(_b2 = (_b = choice.logprobs).refusal) != null ? _b2 : _b.refusal = [];
choice.logprobs.refusal.push(...refusal2);
}
}
}
if (finish_reason) {
choice.finish_reason = finish_reason;
if (__classPrivateFieldGet4(this, _ChatCompletionStream_params, "f") && hasAutoParseableInput(__classPrivateFieldGet4(this, _ChatCompletionStream_params, "f"))) {
if (finish_reason === "length") {
throw new LengthFinishReasonError();
}
if (finish_reason === "content_filter") {
throw new ContentFilterFinishReasonError();
}
}
}
Object.assign(choice, other);
if (!delta)
continue;
const { content, refusal, function_call, role, tool_calls, ...rest2 } = delta;
assertIsEmpty(rest2);
Object.assign(choice.message, rest2);
if (refusal) {
choice.message.refusal = (choice.message.refusal || "") + refusal;
}
if (role)
choice.message.role = role;
if (function_call) {
if (!choice.message.function_call) {
choice.message.function_call = function_call;
} else {
if (function_call.name)
choice.message.function_call.name = function_call.name;
if (function_call.arguments) {
(_c2 = (_c = choice.message.function_call).arguments) != null ? _c2 : _c.arguments = "";
choice.message.function_call.arguments += function_call.arguments;
}
}
}
if (content) {
choice.message.content = (choice.message.content || "") + content;
if (!choice.message.refusal && __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_getAutoParseableResponseFormat).call(this)) {
choice.message.parsed = partialParse(choice.message.content);
}
}
if (tool_calls) {
if (!choice.message.tool_calls)
choice.message.tool_calls = [];
for (const { index: index2, id, type, function: fn, ...rest3 } of tool_calls) {
const tool_call = (_d2 = (_d = choice.message.tool_calls)[index2]) != null ? _d2 : _d[index2] = {};
Object.assign(tool_call, rest3);
if (id)
tool_call.id = id;
if (type)
tool_call.type = type;
if (fn)
(_f = tool_call.function) != null ? _f : tool_call.function = { name: (_e = fn.name) != null ? _e : "", arguments: "" };
if (fn == null ? void 0 : fn.name)
tool_call.function.name = fn.name;
if (fn == null ? void 0 : fn.arguments) {
tool_call.function.arguments += fn.arguments;
if (shouldParseToolCall(__classPrivateFieldGet4(this, _ChatCompletionStream_params, "f"), tool_call)) {
tool_call.function.parsed_arguments = partialParse(tool_call.function.arguments);
}
}
}
}
}
return snapshot;
}, Symbol.asyncIterator)]() {
const pushQueue = [];
const readQueue = [];
let done = false;
this.on("chunk", (chunk) => {
const reader = readQueue.shift();
if (reader) {
reader.resolve(chunk);
} else {
pushQueue.push(chunk);
}
});
this.on("end", () => {
done = true;
for (const reader of readQueue) {
reader.resolve(void 0);
}
readQueue.length = 0;
});
this.on("abort", (err) => {
done = true;
for (const reader of readQueue) {
reader.reject(err);
}
readQueue.length = 0;
});
this.on("error", (err) => {
done = true;
for (const reader of readQueue) {
reader.reject(err);
}
readQueue.length = 0;
});
return {
next: async () => {
if (!pushQueue.length) {
if (done) {
return { value: void 0, done: true };
}
return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
}
const chunk = pushQueue.shift();
return { value: chunk, done: false };
},
return: async () => {
this.abort();
return { value: void 0, done: true };
}
};
}
toReadableStream() {
const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
return stream.toReadableStream();
}
};
function finalizeChatCompletion(snapshot, params) {
const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
const completion = {
...rest,
id,
choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => {
var _a2, _b, _c;
if (!finish_reason) {
throw new OpenAIError(`missing finish_reason for choice ${index}`);
}
const { content = null, function_call, tool_calls, ...messageRest } = message;
const role = message.role;
if (!role) {
throw new OpenAIError(`missing role for choice ${index}`);
}
if (function_call) {
const { arguments: args, name } = function_call;
if (args == null) {
throw new OpenAIError(`missing function_call.arguments for choice ${index}`);
}
if (!name) {
throw new OpenAIError(`missing function_call.name for choice ${index}`);
}
return {
...choiceRest,
message: {
content,
function_call: { arguments: args, name },
role,
refusal: (_a2 = message.refusal) != null ? _a2 : null
},
finish_reason,
index,
logprobs
};
}
if (tool_calls) {
return {
...choiceRest,
index,
finish_reason,
logprobs,
message: {
...messageRest,
role,
content,
refusal: (_b = message.refusal) != null ? _b : null,
tool_calls: tool_calls.map((tool_call, i) => {
const { function: fn, type, id: id2, ...toolRest } = tool_call;
const { arguments: args, name, ...fnRest } = fn || {};
if (id2 == null) {
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].id
${str(snapshot)}`);
}
if (type == null) {
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type
${str(snapshot)}`);
}
if (name == null) {
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name
${str(snapshot)}`);
}
if (args == null) {
throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments
${str(snapshot)}`);
}
return { ...toolRest, id: id2, type, function: { ...fnRest, name, arguments: args } };
})
}
};
}
return {
...choiceRest,
message: { ...messageRest, content, role, refusal: (_c = message.refusal) != null ? _c : null },
finish_reason,
index,
logprobs
};
}),
created,
model,
object: "chat.completion",
...system_fingerprint ? { system_fingerprint } : {}
};
return maybeParseChatCompletion(completion, params);
}
function str(x) {
return JSON.stringify(x);
}
function assertIsEmpty(obj) {
return;
}
function assertNever(_x) {
}
// node_modules/openai/lib/ChatCompletionStreamingRunner.mjs
var ChatCompletionStreamingRunner = class _ChatCompletionStreamingRunner extends ChatCompletionStream {
static fromReadableStream(stream) {
const runner = new _ChatCompletionStreamingRunner(null);
runner._run(() => runner._fromReadableStream(stream));
return runner;
}
/** @deprecated - please use `runTools` instead. */
static runFunctions(client, params, options) {
const runner = new _ChatCompletionStreamingRunner(null);
const opts = {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "runFunctions" }
};
runner._run(() => runner._runFunctions(client, params, opts));
return runner;
}
static runTools(client, params, options) {
const runner = new _ChatCompletionStreamingRunner(
// @ts-expect-error TODO these types are incompatible
params
);
const opts = {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "runTools" }
};
runner._run(() => runner._runTools(client, params, opts));
return runner;
}
};
// node_modules/openai/resources/beta/chat/completions.mjs
var Completions2 = class extends APIResource {
parse(body, options) {
validateInputTools(body.tools);
return this._client.chat.completions.create(body, {
...options,
headers: {
...options == null ? void 0 : options.headers,
"X-Stainless-Helper-Method": "beta.chat.completions.parse"
}
})._thenUnwrap((completion) => parseChatCompletion(completion, body));
}
runFunctions(body, options) {
if (body.stream) {
return ChatCompletionStreamingRunner.runFunctions(this._client, body, options);
}
return ChatCompletionRunner.runFunctions(this._client, body, options);
}
runTools(body, options) {
if (body.stream) {
return ChatCompletionStreamingRunner.runTools(this._client, body, options);
}
return ChatCompletionRunner.runTools(this._client, body, options);
}
/**
* Creates a chat completion stream
*/
stream(body, options) {
return ChatCompletionStream.createChatCompletion(this._client, body, options);
}
};
// node_modules/openai/resources/beta/chat/chat.mjs
var Chat2 = class extends APIResource {
constructor() {
super(...arguments);
this.completions = new Completions2(this._client);
}
};
(function(Chat3) {
Chat3.Completions = Completions2;
})(Chat2 || (Chat2 = {}));
// node_modules/openai/lib/AssistantStream.mjs
var __classPrivateFieldGet5 = function(receiver, state, kind2, f) {
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet4 = function(receiver, state, value, kind2, f) {
if (kind2 === "m")
throw new TypeError("Private method is not writable");
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
};
var _AssistantStream_instances;
var _AssistantStream_events;
var _AssistantStream_runStepSnapshots;
var _AssistantStream_messageSnapshots;
var _AssistantStream_messageSnapshot;
var _AssistantStream_finalRun;
var _AssistantStream_currentContentIndex;
var _AssistantStream_currentContent;
var _AssistantStream_currentToolCallIndex;
var _AssistantStream_currentToolCall;
var _AssistantStream_currentEvent;
var _AssistantStream_currentRunSnapshot;
var _AssistantStream_currentRunStepSnapshot;
var _AssistantStream_addEvent;
var _AssistantStream_endRequest;
var _AssistantStream_handleMessage;
var _AssistantStream_handleRunStep;
var _AssistantStream_handleEvent;
var _AssistantStream_accumulateRunStep;
var _AssistantStream_accumulateMessage;
var _AssistantStream_accumulateContent;
var _AssistantStream_handleRun;
var AssistantStream = class _AssistantStream extends EventStream {
constructor() {
super(...arguments);
_AssistantStream_instances.add(this);
_AssistantStream_events.set(this, []);
_AssistantStream_runStepSnapshots.set(this, {});
_AssistantStream_messageSnapshots.set(this, {});
_AssistantStream_messageSnapshot.set(this, void 0);
_AssistantStream_finalRun.set(this, void 0);
_AssistantStream_currentContentIndex.set(this, void 0);
_AssistantStream_currentContent.set(this, void 0);
_AssistantStream_currentToolCallIndex.set(this, void 0);
_AssistantStream_currentToolCall.set(this, void 0);
_AssistantStream_currentEvent.set(this, void 0);
_AssistantStream_currentRunSnapshot.set(this, void 0);
_AssistantStream_currentRunStepSnapshot.set(this, void 0);
}
[(_AssistantStream_events = /* @__PURE__ */ new WeakMap(), _AssistantStream_runStepSnapshots = /* @__PURE__ */ new WeakMap(), _AssistantStream_messageSnapshots = /* @__PURE__ */ new WeakMap(), _AssistantStream_messageSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_finalRun = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentContentIndex = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentContent = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentToolCallIndex = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentToolCall = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentEvent = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentRunSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentRunStepSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_instances = /* @__PURE__ */ new WeakSet(), Symbol.asyncIterator)]() {
const pushQueue = [];
const readQueue = [];
let done = false;
this.on("event", (event) => {
const reader = readQueue.shift();
if (reader) {
reader.resolve(event);
} else {
pushQueue.push(event);
}
});
this.on("end", () => {
done = true;
for (const reader of readQueue) {
reader.resolve(void 0);
}
readQueue.length = 0;
});
this.on("abort", (err) => {
done = true;
for (const reader of readQueue) {
reader.reject(err);
}
readQueue.length = 0;
});
this.on("error", (err) => {
done = true;
for (const reader of readQueue) {
reader.reject(err);
}
readQueue.length = 0;
});
return {
next: async () => {
if (!pushQueue.length) {
if (done) {
return { value: void 0, done: true };
}
return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
}
const chunk = pushQueue.shift();
return { value: chunk, done: false };
},
return: async () => {
this.abort();
return { value: void 0, done: true };
}
};
}
static fromReadableStream(stream) {
const runner = new _AssistantStream();
runner._run(() => runner._fromReadableStream(stream));
return runner;
}
async _fromReadableStream(readableStream, options) {
var _a2;
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
this._connected();
const stream = Stream.fromReadableStream(readableStream, this.controller);
for await (const event of stream) {
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
}
if ((_a2 = stream.controller.signal) == null ? void 0 : _a2.aborted) {
throw new APIUserAbortError();
}
return this._addRun(__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
}
toReadableStream() {
const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller);
return stream.toReadableStream();
}
static createToolAssistantStream(threadId, runId, runs, params, options) {
const runner = new _AssistantStream();
runner._run(() => runner._runToolAssistantStream(threadId, runId, runs, params, {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "stream" }
}));
return runner;
}
async _createToolAssistantStream(run, threadId, runId, params, options) {
var _a2;
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
const body = { ...params, stream: true };
const stream = await run.submitToolOutputs(threadId, runId, body, {
...options,
signal: this.controller.signal
});
this._connected();
for await (const event of stream) {
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
}
if ((_a2 = stream.controller.signal) == null ? void 0 : _a2.aborted) {
throw new APIUserAbortError();
}
return this._addRun(__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
}
static createThreadAssistantStream(params, thread, options) {
const runner = new _AssistantStream();
runner._run(() => runner._threadAssistantStream(params, thread, {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "stream" }
}));
return runner;
}
static createAssistantStream(threadId, runs, params, options) {
const runner = new _AssistantStream();
runner._run(() => runner._runAssistantStream(threadId, runs, params, {
...options,
headers: { ...options == null ? void 0 : options.headers, "X-Stainless-Helper-Method": "stream" }
}));
return runner;
}
currentEvent() {
return __classPrivateFieldGet5(this, _AssistantStream_currentEvent, "f");
}
currentRun() {
return __classPrivateFieldGet5(this, _AssistantStream_currentRunSnapshot, "f");
}
currentMessageSnapshot() {
return __classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f");
}
currentRunStepSnapshot() {
return __classPrivateFieldGet5(this, _AssistantStream_currentRunStepSnapshot, "f");
}
async finalRunSteps() {
await this.done();
return Object.values(__classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f"));
}
async finalMessages() {
await this.done();
return Object.values(__classPrivateFieldGet5(this, _AssistantStream_messageSnapshots, "f"));
}
async finalRun() {
await this.done();
if (!__classPrivateFieldGet5(this, _AssistantStream_finalRun, "f"))
throw Error("Final run was not received.");
return __classPrivateFieldGet5(this, _AssistantStream_finalRun, "f");
}
async _createThreadAssistantStream(thread, params, options) {
var _a2;
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
const body = { ...params, stream: true };
const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal });
this._connected();
for await (const event of stream) {
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
}
if ((_a2 = stream.controller.signal) == null ? void 0 : _a2.aborted) {
throw new APIUserAbortError();
}
return this._addRun(__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
}
async _createAssistantStream(run, threadId, params, options) {
var _a2;
const signal = options == null ? void 0 : options.signal;
if (signal) {
if (signal.aborted)
this.controller.abort();
signal.addEventListener("abort", () => this.controller.abort());
}
const body = { ...params, stream: true };
const stream = await run.create(threadId, body, { ...options, signal: this.controller.signal });
this._connected();
for await (const event of stream) {
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event);
}
if ((_a2 = stream.controller.signal) == null ? void 0 : _a2.aborted) {
throw new APIUserAbortError();
}
return this._addRun(__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this));
}
static accumulateDelta(acc, delta) {
for (const [key, deltaValue] of Object.entries(delta)) {
if (!acc.hasOwnProperty(key)) {
acc[key] = deltaValue;
continue;
}
let accValue = acc[key];
if (accValue === null || accValue === void 0) {
acc[key] = deltaValue;
continue;
}
if (key === "index" || key === "type") {
acc[key] = deltaValue;
continue;
}
if (typeof accValue === "string" && typeof deltaValue === "string") {
accValue += deltaValue;
} else if (typeof accValue === "number" && typeof deltaValue === "number") {
accValue += deltaValue;
} else if (isObj(accValue) && isObj(deltaValue)) {
accValue = this.accumulateDelta(accValue, deltaValue);
} else if (Array.isArray(accValue) && Array.isArray(deltaValue)) {
if (accValue.every((x) => typeof x === "string" || typeof x === "number")) {
accValue.push(...deltaValue);
continue;
}
for (const deltaEntry of deltaValue) {
if (!isObj(deltaEntry)) {
throw new Error(`Expected array delta entry to be an object but got: ${deltaEntry}`);
}
const index = deltaEntry["index"];
if (index == null) {
console.error(deltaEntry);
throw new Error("Expected array delta entry to have an `index` property");
}
if (typeof index !== "number") {
throw new Error(`Expected array delta entry \`index\` property to be a number but got ${index}`);
}
const accEntry = accValue[index];
if (accEntry == null) {
accValue.push(deltaEntry);
} else {
accValue[index] = this.accumulateDelta(accEntry, deltaEntry);
}
}
continue;
} else {
throw Error(`Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accValue}`);
}
acc[key] = accValue;
}
return acc;
}
_addRun(run) {
return run;
}
async _threadAssistantStream(params, thread, options) {
return await this._createThreadAssistantStream(thread, params, options);
}
async _runAssistantStream(threadId, runs, params, options) {
return await this._createAssistantStream(runs, threadId, params, options);
}
async _runToolAssistantStream(threadId, runId, runs, params, options) {
return await this._createToolAssistantStream(runs, threadId, runId, params, options);
}
};
_AssistantStream_addEvent = function _AssistantStream_addEvent2(event) {
if (this.ended)
return;
__classPrivateFieldSet4(this, _AssistantStream_currentEvent, event, "f");
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_handleEvent).call(this, event);
switch (event.event) {
case "thread.created":
break;
case "thread.run.created":
case "thread.run.queued":
case "thread.run.in_progress":
case "thread.run.requires_action":
case "thread.run.completed":
case "thread.run.failed":
case "thread.run.cancelling":
case "thread.run.cancelled":
case "thread.run.expired":
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_handleRun).call(this, event);
break;
case "thread.run.step.created":
case "thread.run.step.in_progress":
case "thread.run.step.delta":
case "thread.run.step.completed":
case "thread.run.step.failed":
case "thread.run.step.cancelled":
case "thread.run.step.expired":
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_handleRunStep).call(this, event);
break;
case "thread.message.created":
case "thread.message.in_progress":
case "thread.message.delta":
case "thread.message.completed":
case "thread.message.incomplete":
__classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_handleMessage).call(this, event);
break;
case "error":
throw new Error("Encountered an error event in event processing - errors should be processed earlier");
}
}, _AssistantStream_endRequest = function _AssistantStream_endRequest2() {
if (this.ended) {
throw new OpenAIError(`stream has ended, this shouldn't happen`);
}
if (!__classPrivateFieldGet5(this, _AssistantStream_finalRun, "f"))
throw Error("Final run has not been received");
return __classPrivateFieldGet5(this, _AssistantStream_finalRun, "f");
}, _AssistantStream_handleMessage = function _AssistantStream_handleMessage2(event) {
const [accumulatedMessage, newContent] = __classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_accumulateMessage).call(this, event, __classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f"));
__classPrivateFieldSet4(this, _AssistantStream_messageSnapshot, accumulatedMessage, "f");
__classPrivateFieldGet5(this, _AssistantStream_messageSnapshots, "f")[accumulatedMessage.id] = accumulatedMessage;
for (const content of newContent) {
const snapshotContent = accumulatedMessage.content[content.index];
if ((snapshotContent == null ? void 0 : snapshotContent.type) == "text") {
this._emit("textCreated", snapshotContent.text);
}
}
switch (event.event) {
case "thread.message.created":
this._emit("messageCreated", event.data);
break;
case "thread.message.in_progress":
break;
case "thread.message.delta":
this._emit("messageDelta", event.data.delta, accumulatedMessage);
if (event.data.delta.content) {
for (const content of event.data.delta.content) {
if (content.type == "text" && content.text) {
let textDelta = content.text;
let snapshot = accumulatedMessage.content[content.index];
if (snapshot && snapshot.type == "text") {
this._emit("textDelta", textDelta, snapshot.text);
} else {
throw Error("The snapshot associated with this text delta is not text or missing");
}
}
if (content.index != __classPrivateFieldGet5(this, _AssistantStream_currentContentIndex, "f")) {
if (__classPrivateFieldGet5(this, _AssistantStream_currentContent, "f")) {
switch (__classPrivateFieldGet5(this, _AssistantStream_currentContent, "f").type) {
case "text":
this._emit("textDone", __classPrivateFieldGet5(this, _AssistantStream_currentContent, "f").text, __classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f"));
break;
case "image_file":
this._emit("imageFileDone", __classPrivateFieldGet5(this, _AssistantStream_currentContent, "f").image_file, __classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f"));
break;
}
}
__classPrivateFieldSet4(this, _AssistantStream_currentContentIndex, content.index, "f");
}
__classPrivateFieldSet4(this, _AssistantStream_currentContent, accumulatedMessage.content[content.index], "f");
}
}
break;
case "thread.message.completed":
case "thread.message.incomplete":
if (__classPrivateFieldGet5(this, _AssistantStream_currentContentIndex, "f") !== void 0) {
const currentContent = event.data.content[__classPrivateFieldGet5(this, _AssistantStream_currentContentIndex, "f")];
if (currentContent) {
switch (currentContent.type) {
case "image_file":
this._emit("imageFileDone", currentContent.image_file, __classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f"));
break;
case "text":
this._emit("textDone", currentContent.text, __classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f"));
break;
}
}
}
if (__classPrivateFieldGet5(this, _AssistantStream_messageSnapshot, "f")) {
this._emit("messageDone", event.data);
}
__classPrivateFieldSet4(this, _AssistantStream_messageSnapshot, void 0, "f");
}
}, _AssistantStream_handleRunStep = function _AssistantStream_handleRunStep2(event) {
const accumulatedRunStep = __classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_accumulateRunStep).call(this, event);
__classPrivateFieldSet4(this, _AssistantStream_currentRunStepSnapshot, accumulatedRunStep, "f");
switch (event.event) {
case "thread.run.step.created":
this._emit("runStepCreated", event.data);
break;
case "thread.run.step.delta":
const delta = event.data.delta;
if (delta.step_details && delta.step_details.type == "tool_calls" && delta.step_details.tool_calls && accumulatedRunStep.step_details.type == "tool_calls") {
for (const toolCall of delta.step_details.tool_calls) {
if (toolCall.index == __classPrivateFieldGet5(this, _AssistantStream_currentToolCallIndex, "f")) {
this._emit("toolCallDelta", toolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]);
} else {
if (__classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f")) {
this._emit("toolCallDone", __classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f"));
}
__classPrivateFieldSet4(this, _AssistantStream_currentToolCallIndex, toolCall.index, "f");
__classPrivateFieldSet4(this, _AssistantStream_currentToolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index], "f");
if (__classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f"))
this._emit("toolCallCreated", __classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f"));
}
}
}
this._emit("runStepDelta", event.data.delta, accumulatedRunStep);
break;
case "thread.run.step.completed":
case "thread.run.step.failed":
case "thread.run.step.cancelled":
case "thread.run.step.expired":
__classPrivateFieldSet4(this, _AssistantStream_currentRunStepSnapshot, void 0, "f");
const details = event.data.step_details;
if (details.type == "tool_calls") {
if (__classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f")) {
this._emit("toolCallDone", __classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f"));
__classPrivateFieldSet4(this, _AssistantStream_currentToolCall, void 0, "f");
}
}
this._emit("runStepDone", event.data, accumulatedRunStep);
break;
case "thread.run.step.in_progress":
break;
}
}, _AssistantStream_handleEvent = function _AssistantStream_handleEvent2(event) {
__classPrivateFieldGet5(this, _AssistantStream_events, "f").push(event);
this._emit("event", event);
}, _AssistantStream_accumulateRunStep = function _AssistantStream_accumulateRunStep2(event) {
switch (event.event) {
case "thread.run.step.created":
__classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data;
return event.data;
case "thread.run.step.delta":
let snapshot = __classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id];
if (!snapshot) {
throw Error("Received a RunStepDelta before creation of a snapshot");
}
let data = event.data;
if (data.delta) {
const accumulated = AssistantStream.accumulateDelta(snapshot, data.delta);
__classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = accumulated;
}
return __classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id];
case "thread.run.step.completed":
case "thread.run.step.failed":
case "thread.run.step.cancelled":
case "thread.run.step.expired":
case "thread.run.step.in_progress":
__classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data;
break;
}
if (__classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id])
return __classPrivateFieldGet5(this, _AssistantStream_runStepSnapshots, "f")[event.data.id];
throw new Error("No snapshot available");
}, _AssistantStream_accumulateMessage = function _AssistantStream_accumulateMessage2(event, snapshot) {
let newContent = [];
switch (event.event) {
case "thread.message.created":
return [event.data, newContent];
case "thread.message.delta":
if (!snapshot) {
throw Error("Received a delta with no existing snapshot (there should be one from message creation)");
}
let data = event.data;
if (data.delta.content) {
for (const contentElement of data.delta.content) {
if (contentElement.index in snapshot.content) {
let currentContent = snapshot.content[contentElement.index];
snapshot.content[contentElement.index] = __classPrivateFieldGet5(this, _AssistantStream_instances, "m", _AssistantStream_accumulateContent).call(this, contentElement, currentContent);
} else {
snapshot.content[contentElement.index] = contentElement;
newContent.push(contentElement);
}
}
}
return [snapshot, newContent];
case "thread.message.in_progress":
case "thread.message.completed":
case "thread.message.incomplete":
if (snapshot) {
return [snapshot, newContent];
} else {
throw Error("Received thread message event with no existing snapshot");
}
}
throw Error("Tried to accumulate a non-message event");
}, _AssistantStream_accumulateContent = function _AssistantStream_accumulateContent2(contentElement, currentContent) {
return AssistantStream.accumulateDelta(currentContent, contentElement);
}, _AssistantStream_handleRun = function _AssistantStream_handleRun2(event) {
__classPrivateFieldSet4(this, _AssistantStream_currentRunSnapshot, event.data, "f");
switch (event.event) {
case "thread.run.created":
break;
case "thread.run.queued":
break;
case "thread.run.in_progress":
break;
case "thread.run.requires_action":
case "thread.run.cancelled":
case "thread.run.failed":
case "thread.run.completed":
case "thread.run.expired":
__classPrivateFieldSet4(this, _AssistantStream_finalRun, event.data, "f");
if (__classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f")) {
this._emit("toolCallDone", __classPrivateFieldGet5(this, _AssistantStream_currentToolCall, "f"));
__classPrivateFieldSet4(this, _AssistantStream_currentToolCall, void 0, "f");
}
break;
case "thread.run.cancelling":
break;
}
};
// node_modules/openai/resources/beta/threads/messages.mjs
var Messages = class extends APIResource {
/**
* Create a message.
*/
create(threadId, body, options) {
return this._client.post(`/threads/${threadId}/messages`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Retrieve a message.
*/
retrieve(threadId, messageId, options) {
return this._client.get(`/threads/${threadId}/messages/${messageId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Modifies a message.
*/
update(threadId, messageId, body, options) {
return this._client.post(`/threads/${threadId}/messages/${messageId}`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
list(threadId, query = {}, options) {
if (isRequestOptions(query)) {
return this.list(threadId, {}, query);
}
return this._client.getAPIList(`/threads/${threadId}/messages`, MessagesPage, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Deletes a message.
*/
del(threadId, messageId, options) {
return this._client.delete(`/threads/${threadId}/messages/${messageId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
};
var MessagesPage = class extends CursorPage {
};
Messages.MessagesPage = MessagesPage;
// node_modules/openai/resources/beta/threads/runs/steps.mjs
var Steps = class extends APIResource {
retrieve(threadId, runId, stepId, query = {}, options) {
if (isRequestOptions(query)) {
return this.retrieve(threadId, runId, stepId, {}, query);
}
return this._client.get(`/threads/${threadId}/runs/${runId}/steps/${stepId}`, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
list(threadId, runId, query = {}, options) {
if (isRequestOptions(query)) {
return this.list(threadId, runId, {}, query);
}
return this._client.getAPIList(`/threads/${threadId}/runs/${runId}/steps`, RunStepsPage, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
};
var RunStepsPage = class extends CursorPage {
};
Steps.RunStepsPage = RunStepsPage;
// node_modules/openai/resources/beta/threads/runs/runs.mjs
var Runs = class extends APIResource {
constructor() {
super(...arguments);
this.steps = new Steps(this._client);
}
create(threadId, params, options) {
var _a2;
const { include, ...body } = params;
return this._client.post(`/threads/${threadId}/runs`, {
query: { include },
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers },
stream: (_a2 = params.stream) != null ? _a2 : false
});
}
/**
* Retrieves a run.
*/
retrieve(threadId, runId, options) {
return this._client.get(`/threads/${threadId}/runs/${runId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Modifies a run.
*/
update(threadId, runId, body, options) {
return this._client.post(`/threads/${threadId}/runs/${runId}`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
list(threadId, query = {}, options) {
if (isRequestOptions(query)) {
return this.list(threadId, {}, query);
}
return this._client.getAPIList(`/threads/${threadId}/runs`, RunsPage, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Cancels a run that is `in_progress`.
*/
cancel(threadId, runId, options) {
return this._client.post(`/threads/${threadId}/runs/${runId}/cancel`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* A helper to create a run an poll for a terminal state. More information on Run
* lifecycles can be found here:
* https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps
*/
async createAndPoll(threadId, body, options) {
const run = await this.create(threadId, body, options);
return await this.poll(threadId, run.id, options);
}
/**
* Create a Run stream
*
* @deprecated use `stream` instead
*/
createAndStream(threadId, body, options) {
return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options);
}
/**
* A helper to poll a run status until it reaches a terminal state. More
* information on Run lifecycles can be found here:
* https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps
*/
async poll(threadId, runId, options) {
const headers = { ...options == null ? void 0 : options.headers, "X-Stainless-Poll-Helper": "true" };
if (options == null ? void 0 : options.pollIntervalMs) {
headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString();
}
while (true) {
const { data: run, response } = await this.retrieve(threadId, runId, {
...options,
headers: { ...options == null ? void 0 : options.headers, ...headers }
}).withResponse();
switch (run.status) {
case "queued":
case "in_progress":
case "cancelling":
let sleepInterval = 5e3;
if (options == null ? void 0 : options.pollIntervalMs) {
sleepInterval = options.pollIntervalMs;
} else {
const headerInterval = response.headers.get("openai-poll-after-ms");
if (headerInterval) {
const headerIntervalMs = parseInt(headerInterval);
if (!isNaN(headerIntervalMs)) {
sleepInterval = headerIntervalMs;
}
}
}
await sleep(sleepInterval);
break;
case "requires_action":
case "incomplete":
case "cancelled":
case "completed":
case "failed":
case "expired":
return run;
}
}
}
/**
* Create a Run stream
*/
stream(threadId, body, options) {
return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options);
}
submitToolOutputs(threadId, runId, body, options) {
var _a2;
return this._client.post(`/threads/${threadId}/runs/${runId}/submit_tool_outputs`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers },
stream: (_a2 = body.stream) != null ? _a2 : false
});
}
/**
* A helper to submit a tool output to a run and poll for a terminal run state.
* More information on Run lifecycles can be found here:
* https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps
*/
async submitToolOutputsAndPoll(threadId, runId, body, options) {
const run = await this.submitToolOutputs(threadId, runId, body, options);
return await this.poll(threadId, run.id, options);
}
/**
* Submit the tool outputs from a previous run and stream the run to a terminal
* state. More information on Run lifecycles can be found here:
* https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps
*/
submitToolOutputsStream(threadId, runId, body, options) {
return AssistantStream.createToolAssistantStream(threadId, runId, this._client.beta.threads.runs, body, options);
}
};
var RunsPage = class extends CursorPage {
};
Runs.RunsPage = RunsPage;
Runs.Steps = Steps;
Runs.RunStepsPage = RunStepsPage;
// node_modules/openai/resources/beta/threads/threads.mjs
var Threads = class extends APIResource {
constructor() {
super(...arguments);
this.runs = new Runs(this._client);
this.messages = new Messages(this._client);
}
create(body = {}, options) {
if (isRequestOptions(body)) {
return this.create({}, body);
}
return this._client.post("/threads", {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Retrieves a thread.
*/
retrieve(threadId, options) {
return this._client.get(`/threads/${threadId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Modifies a thread.
*/
update(threadId, body, options) {
return this._client.post(`/threads/${threadId}`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Delete a thread.
*/
del(threadId, options) {
return this._client.delete(`/threads/${threadId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
createAndRun(body, options) {
var _a2;
return this._client.post("/threads/runs", {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers },
stream: (_a2 = body.stream) != null ? _a2 : false
});
}
/**
* A helper to create a thread, start a run and then poll for a terminal state.
* More information on Run lifecycles can be found here:
* https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps
*/
async createAndRunPoll(body, options) {
const run = await this.createAndRun(body, options);
return await this.runs.poll(run.thread_id, run.id, options);
}
/**
* Create a thread and stream the run back
*/
createAndRunStream(body, options) {
return AssistantStream.createThreadAssistantStream(body, this._client.beta.threads, options);
}
};
Threads.Runs = Runs;
Threads.RunsPage = RunsPage;
Threads.Messages = Messages;
Threads.MessagesPage = MessagesPage;
// node_modules/openai/lib/Util.mjs
var allSettledWithThrow = async (promises) => {
const results = await Promise.allSettled(promises);
const rejected = results.filter((result) => result.status === "rejected");
if (rejected.length) {
for (const result of rejected) {
console.error(result.reason);
}
throw new Error(`${rejected.length} promise(s) failed - see the above errors`);
}
const values = [];
for (const result of results) {
if (result.status === "fulfilled") {
values.push(result.value);
}
}
return values;
};
// node_modules/openai/resources/beta/vector-stores/files.mjs
var Files = class extends APIResource {
/**
* Create a vector store file by attaching a
* [File](https://platform.openai.com/docs/api-reference/files) to a
* [vector store](https://platform.openai.com/docs/api-reference/vector-stores/object).
*/
create(vectorStoreId, body, options) {
return this._client.post(`/vector_stores/${vectorStoreId}/files`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Retrieves a vector store file.
*/
retrieve(vectorStoreId, fileId, options) {
return this._client.get(`/vector_stores/${vectorStoreId}/files/${fileId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
list(vectorStoreId, query = {}, options) {
if (isRequestOptions(query)) {
return this.list(vectorStoreId, {}, query);
}
return this._client.getAPIList(`/vector_stores/${vectorStoreId}/files`, VectorStoreFilesPage, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Delete a vector store file. This will remove the file from the vector store but
* the file itself will not be deleted. To delete the file, use the
* [delete file](https://platform.openai.com/docs/api-reference/files/delete)
* endpoint.
*/
del(vectorStoreId, fileId, options) {
return this._client.delete(`/vector_stores/${vectorStoreId}/files/${fileId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Attach a file to the given vector store and wait for it to be processed.
*/
async createAndPoll(vectorStoreId, body, options) {
const file = await this.create(vectorStoreId, body, options);
return await this.poll(vectorStoreId, file.id, options);
}
/**
* Wait for the vector store file to finish processing.
*
* Note: this will return even if the file failed to process, you need to check
* file.last_error and file.status to handle these cases
*/
async poll(vectorStoreId, fileId, options) {
const headers = { ...options == null ? void 0 : options.headers, "X-Stainless-Poll-Helper": "true" };
if (options == null ? void 0 : options.pollIntervalMs) {
headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString();
}
while (true) {
const fileResponse = await this.retrieve(vectorStoreId, fileId, {
...options,
headers
}).withResponse();
const file = fileResponse.data;
switch (file.status) {
case "in_progress":
let sleepInterval = 5e3;
if (options == null ? void 0 : options.pollIntervalMs) {
sleepInterval = options.pollIntervalMs;
} else {
const headerInterval = fileResponse.response.headers.get("openai-poll-after-ms");
if (headerInterval) {
const headerIntervalMs = parseInt(headerInterval);
if (!isNaN(headerIntervalMs)) {
sleepInterval = headerIntervalMs;
}
}
}
await sleep(sleepInterval);
break;
case "failed":
case "completed":
return file;
}
}
}
/**
* Upload a file to the `files` API and then attach it to the given vector store.
*
* Note the file will be asynchronously processed (you can use the alternative
* polling helper method to wait for processing to complete).
*/
async upload(vectorStoreId, file, options) {
const fileInfo = await this._client.files.create({ file, purpose: "assistants" }, options);
return this.create(vectorStoreId, { file_id: fileInfo.id }, options);
}
/**
* Add a file to a vector store and poll until processing is complete.
*/
async uploadAndPoll(vectorStoreId, file, options) {
const fileInfo = await this.upload(vectorStoreId, file, options);
return await this.poll(vectorStoreId, fileInfo.id, options);
}
};
var VectorStoreFilesPage = class extends CursorPage {
};
Files.VectorStoreFilesPage = VectorStoreFilesPage;
// node_modules/openai/resources/beta/vector-stores/file-batches.mjs
var FileBatches = class extends APIResource {
/**
* Create a vector store file batch.
*/
create(vectorStoreId, body, options) {
return this._client.post(`/vector_stores/${vectorStoreId}/file_batches`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Retrieves a vector store file batch.
*/
retrieve(vectorStoreId, batchId, options) {
return this._client.get(`/vector_stores/${vectorStoreId}/file_batches/${batchId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Cancel a vector store file batch. This attempts to cancel the processing of
* files in this batch as soon as possible.
*/
cancel(vectorStoreId, batchId, options) {
return this._client.post(`/vector_stores/${vectorStoreId}/file_batches/${batchId}/cancel`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Create a vector store batch and poll until all files have been processed.
*/
async createAndPoll(vectorStoreId, body, options) {
const batch = await this.create(vectorStoreId, body);
return await this.poll(vectorStoreId, batch.id, options);
}
listFiles(vectorStoreId, batchId, query = {}, options) {
if (isRequestOptions(query)) {
return this.listFiles(vectorStoreId, batchId, {}, query);
}
return this._client.getAPIList(`/vector_stores/${vectorStoreId}/file_batches/${batchId}/files`, VectorStoreFilesPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers } });
}
/**
* Wait for the given file batch to be processed.
*
* Note: this will return even if one of the files failed to process, you need to
* check batch.file_counts.failed_count to handle this case.
*/
async poll(vectorStoreId, batchId, options) {
const headers = { ...options == null ? void 0 : options.headers, "X-Stainless-Poll-Helper": "true" };
if (options == null ? void 0 : options.pollIntervalMs) {
headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString();
}
while (true) {
const { data: batch, response } = await this.retrieve(vectorStoreId, batchId, {
...options,
headers
}).withResponse();
switch (batch.status) {
case "in_progress":
let sleepInterval = 5e3;
if (options == null ? void 0 : options.pollIntervalMs) {
sleepInterval = options.pollIntervalMs;
} else {
const headerInterval = response.headers.get("openai-poll-after-ms");
if (headerInterval) {
const headerIntervalMs = parseInt(headerInterval);
if (!isNaN(headerIntervalMs)) {
sleepInterval = headerIntervalMs;
}
}
}
await sleep(sleepInterval);
break;
case "failed":
case "cancelled":
case "completed":
return batch;
}
}
}
/**
* Uploads the given files concurrently and then creates a vector store file batch.
*
* The concurrency limit is configurable using the `maxConcurrency` parameter.
*/
async uploadAndPoll(vectorStoreId, { files, fileIds = [] }, options) {
var _a2;
if (files == null || files.length == 0) {
throw new Error(`No \`files\` provided to process. If you've already uploaded files you should use \`.createAndPoll()\` instead`);
}
const configuredConcurrency = (_a2 = options == null ? void 0 : options.maxConcurrency) != null ? _a2 : 5;
const concurrencyLimit = Math.min(configuredConcurrency, files.length);
const client = this._client;
const fileIterator = files.values();
const allFileIds = [...fileIds];
async function processFiles(iterator) {
for (let item of iterator) {
const fileObj = await client.files.create({ file: item, purpose: "assistants" }, options);
allFileIds.push(fileObj.id);
}
}
const workers = Array(concurrencyLimit).fill(fileIterator).map(processFiles);
await allSettledWithThrow(workers);
return await this.createAndPoll(vectorStoreId, {
file_ids: allFileIds
});
}
};
// node_modules/openai/resources/beta/vector-stores/vector-stores.mjs
var VectorStores = class extends APIResource {
constructor() {
super(...arguments);
this.files = new Files(this._client);
this.fileBatches = new FileBatches(this._client);
}
/**
* Create a vector store.
*/
create(body, options) {
return this._client.post("/vector_stores", {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Retrieves a vector store.
*/
retrieve(vectorStoreId, options) {
return this._client.get(`/vector_stores/${vectorStoreId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Modifies a vector store.
*/
update(vectorStoreId, body, options) {
return this._client.post(`/vector_stores/${vectorStoreId}`, {
body,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
list(query = {}, options) {
if (isRequestOptions(query)) {
return this.list({}, query);
}
return this._client.getAPIList("/vector_stores", VectorStoresPage, {
query,
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
/**
* Delete a vector store.
*/
del(vectorStoreId, options) {
return this._client.delete(`/vector_stores/${vectorStoreId}`, {
...options,
headers: { "OpenAI-Beta": "assistants=v2", ...options == null ? void 0 : options.headers }
});
}
};
var VectorStoresPage = class extends CursorPage {
};
VectorStores.VectorStoresPage = VectorStoresPage;
VectorStores.Files = Files;
VectorStores.VectorStoreFilesPage = VectorStoreFilesPage;
VectorStores.FileBatches = FileBatches;
// node_modules/openai/resources/beta/beta.mjs
var Beta = class extends APIResource {
constructor() {
super(...arguments);
this.vectorStores = new VectorStores(this._client);
this.chat = new Chat2(this._client);
this.assistants = new Assistants(this._client);
this.threads = new Threads(this._client);
}
};
Beta.VectorStores = VectorStores;
Beta.VectorStoresPage = VectorStoresPage;
Beta.Assistants = Assistants;
Beta.AssistantsPage = AssistantsPage;
Beta.Threads = Threads;
// node_modules/openai/resources/completions.mjs
var Completions3 = class extends APIResource {
create(body, options) {
var _a2;
return this._client.post("/completions", { body, ...options, stream: (_a2 = body.stream) != null ? _a2 : false });
}
};
// node_modules/openai/resources/embeddings.mjs
var Embeddings = class extends APIResource {
/**
* Creates an embedding vector representing the input text.
*/
create(body, options) {
return this._client.post("/embeddings", { body, ...options });
}
};
// node_modules/openai/resources/files.mjs
var Files2 = class extends APIResource {
/**
* Upload a file that can be used across various endpoints. Individual files can be
* up to 512 MB, and the size of all files uploaded by one organization can be up
* to 100 GB.
*
* The Assistants API supports files up to 2 million tokens and of specific file
* types. See the
* [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) for
* details.
*
* The Fine-tuning API only supports `.jsonl` files. The input also has certain
* required formats for fine-tuning
* [chat](https://platform.openai.com/docs/api-reference/fine-tuning/chat-input) or
* [completions](https://platform.openai.com/docs/api-reference/fine-tuning/completions-input)
* models.
*
* The Batch API only supports `.jsonl` files up to 200 MB in size. The input also
* has a specific required
* [format](https://platform.openai.com/docs/api-reference/batch/request-input).
*
* Please [contact us](https://help.openai.com/) if you need to increase these
* storage limits.
*/
create(body, options) {
return this._client.post("/files", multipartFormRequestOptions({ body, ...options }));
}
/**
* Returns information about a specific file.
*/
retrieve(fileId, options) {
return this._client.get(`/files/${fileId}`, options);
}
list(query = {}, options) {
if (isRequestOptions(query)) {
return this.list({}, query);
}
return this._client.getAPIList("/files", FileObjectsPage, { query, ...options });
}
/**
* Delete a file.
*/
del(fileId, options) {
return this._client.delete(`/files/${fileId}`, options);
}
/**
* Returns the contents of the specified file.
*/
content(fileId, options) {
return this._client.get(`/files/${fileId}/content`, { ...options, __binaryResponse: true });
}
/**
* Returns the contents of the specified file.
*
* @deprecated The `.content()` method should be used instead
*/
retrieveContent(fileId, options) {
return this._client.get(`/files/${fileId}/content`, {
...options,
headers: { Accept: "application/json", ...options == null ? void 0 : options.headers }
});
}
/**
* Waits for the given file to be processed, default timeout is 30 mins.
*/
async waitForProcessing(id, { pollInterval = 5e3, maxWait = 30 * 60 * 1e3 } = {}) {
const TERMINAL_STATES = /* @__PURE__ */ new Set(["processed", "error", "deleted"]);
const start = Date.now();
let file = await this.retrieve(id);
while (!file.status || !TERMINAL_STATES.has(file.status)) {
await sleep(pollInterval);
file = await this.retrieve(id);
if (Date.now() - start > maxWait) {
throw new APIConnectionTimeoutError({
message: `Giving up on waiting for file ${id} to finish processing after ${maxWait} milliseconds.`
});
}
}
return file;
}
};
var FileObjectsPage = class extends CursorPage {
};
Files2.FileObjectsPage = FileObjectsPage;
// node_modules/openai/resources/fine-tuning/jobs/checkpoints.mjs
var Checkpoints = class extends APIResource {
list(fineTuningJobId, query = {}, options) {
if (isRequestOptions(query)) {
return this.list(fineTuningJobId, {}, query);
}
return this._client.getAPIList(`/fine_tuning/jobs/${fineTuningJobId}/checkpoints`, FineTuningJobCheckpointsPage, { query, ...options });
}
};
var FineTuningJobCheckpointsPage = class extends CursorPage {
};
Checkpoints.FineTuningJobCheckpointsPage = FineTuningJobCheckpointsPage;
// node_modules/openai/resources/fine-tuning/jobs/jobs.mjs
var Jobs = class extends APIResource {
constructor() {
super(...arguments);
this.checkpoints = new Checkpoints(this._client);
}
/**
* Creates a fine-tuning job which begins the process of creating a new model from
* a given dataset.
*
* Response includes details of the enqueued job including job status and the name
* of the fine-tuned models once complete.
*
* [Learn more about fine-tuning](https://platform.openai.com/docs/guides/fine-tuning)
*/
create(body, options) {
return this._client.post("/fine_tuning/jobs", { body, ...options });
}
/**
* Get info about a fine-tuning job.
*
* [Learn more about fine-tuning](https://platform.openai.com/docs/guides/fine-tuning)
*/
retrieve(fineTuningJobId, options) {
return this._client.get(`/fine_tuning/jobs/${fineTuningJobId}`, options);
}
list(query = {}, options) {
if (isRequestOptions(query)) {
return this.list({}, query);
}
return this._client.getAPIList("/fine_tuning/jobs", FineTuningJobsPage, { query, ...options });
}
/**
* Immediately cancel a fine-tune job.
*/
cancel(fineTuningJobId, options) {
return this._client.post(`/fine_tuning/jobs/${fineTuningJobId}/cancel`, options);
}
listEvents(fineTuningJobId, query = {}, options) {
if (isRequestOptions(query)) {
return this.listEvents(fineTuningJobId, {}, query);
}
return this._client.getAPIList(`/fine_tuning/jobs/${fineTuningJobId}/events`, FineTuningJobEventsPage, {
query,
...options
});
}
};
var FineTuningJobsPage = class extends CursorPage {
};
var FineTuningJobEventsPage = class extends CursorPage {
};
Jobs.FineTuningJobsPage = FineTuningJobsPage;
Jobs.FineTuningJobEventsPage = FineTuningJobEventsPage;
Jobs.Checkpoints = Checkpoints;
Jobs.FineTuningJobCheckpointsPage = FineTuningJobCheckpointsPage;
// node_modules/openai/resources/fine-tuning/fine-tuning.mjs
var FineTuning = class extends APIResource {
constructor() {
super(...arguments);
this.jobs = new Jobs(this._client);
}
};
FineTuning.Jobs = Jobs;
FineTuning.FineTuningJobsPage = FineTuningJobsPage;
FineTuning.FineTuningJobEventsPage = FineTuningJobEventsPage;
// node_modules/openai/resources/images.mjs
var Images = class extends APIResource {
/**
* Creates a variation of a given image.
*/
createVariation(body, options) {
return this._client.post("/images/variations", multipartFormRequestOptions({ body, ...options }));
}
/**
* Creates an edited or extended image given an original image and a prompt.
*/
edit(body, options) {
return this._client.post("/images/edits", multipartFormRequestOptions({ body, ...options }));
}
/**
* Creates an image given a prompt.
*/
generate(body, options) {
return this._client.post("/images/generations", { body, ...options });
}
};
// node_modules/openai/resources/models.mjs
var Models = class extends APIResource {
/**
* Retrieves a model instance, providing basic information about the model such as
* the owner and permissioning.
*/
retrieve(model, options) {
return this._client.get(`/models/${model}`, options);
}
/**
* Lists the currently available models, and provides basic information about each
* one such as the owner and availability.
*/
list(options) {
return this._client.getAPIList("/models", ModelsPage, options);
}
/**
* Delete a fine-tuned model. You must have the Owner role in your organization to
* delete a model.
*/
del(model, options) {
return this._client.delete(`/models/${model}`, options);
}
};
var ModelsPage = class extends Page {
};
Models.ModelsPage = ModelsPage;
// node_modules/openai/resources/moderations.mjs
var Moderations = class extends APIResource {
/**
* Classifies if text and/or image inputs are potentially harmful. Learn more in
* the [moderation guide](https://platform.openai.com/docs/guides/moderation).
*/
create(body, options) {
return this._client.post("/moderations", { body, ...options });
}
};
// node_modules/openai/resources/uploads/parts.mjs
var Parts = class extends APIResource {
/**
* Adds a
* [Part](https://platform.openai.com/docs/api-reference/uploads/part-object) to an
* [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object.
* A Part represents a chunk of bytes from the file you are trying to upload.
*
* Each Part can be at most 64 MB, and you can add Parts until you hit the Upload
* maximum of 8 GB.
*
* It is possible to add multiple Parts in parallel. You can decide the intended
* order of the Parts when you
* [complete the Upload](https://platform.openai.com/docs/api-reference/uploads/complete).
*/
create(uploadId, body, options) {
return this._client.post(`/uploads/${uploadId}/parts`, multipartFormRequestOptions({ body, ...options }));
}
};
// node_modules/openai/resources/uploads/uploads.mjs
var Uploads = class extends APIResource {
constructor() {
super(...arguments);
this.parts = new Parts(this._client);
}
/**
* Creates an intermediate
* [Upload](https://platform.openai.com/docs/api-reference/uploads/object) object
* that you can add
* [Parts](https://platform.openai.com/docs/api-reference/uploads/part-object) to.
* Currently, an Upload can accept at most 8 GB in total and expires after an hour
* after you create it.
*
* Once you complete the Upload, we will create a
* [File](https://platform.openai.com/docs/api-reference/files/object) object that
* contains all the parts you uploaded. This File is usable in the rest of our
* platform as a regular File object.
*
* For certain `purpose`s, the correct `mime_type` must be specified. Please refer
* to documentation for the supported MIME types for your use case:
*
* - [Assistants](https://platform.openai.com/docs/assistants/tools/file-search#supported-files)
*
* For guidance on the proper filename extensions for each purpose, please follow
* the documentation on
* [creating a File](https://platform.openai.com/docs/api-reference/files/create).
*/
create(body, options) {
return this._client.post("/uploads", { body, ...options });
}
/**
* Cancels the Upload. No Parts may be added after an Upload is cancelled.
*/
cancel(uploadId, options) {
return this._client.post(`/uploads/${uploadId}/cancel`, options);
}
/**
* Completes the
* [Upload](https://platform.openai.com/docs/api-reference/uploads/object).
*
* Within the returned Upload object, there is a nested
* [File](https://platform.openai.com/docs/api-reference/files/object) object that
* is ready to use in the rest of the platform.
*
* You can specify the order of the Parts by passing in an ordered list of the Part
* IDs.
*
* The number of bytes uploaded upon completion must match the number of bytes
* initially specified when creating the Upload object. No Parts may be added after
* an Upload is completed.
*/
complete(uploadId, body, options) {
return this._client.post(`/uploads/${uploadId}/complete`, { body, ...options });
}
};
Uploads.Parts = Parts;
// node_modules/openai/index.mjs
var _a;
var OpenAI = class extends APIClient {
/**
* API Client for interfacing with the OpenAI API.
*
* @param {string | undefined} [opts.apiKey=process.env['OPENAI_API_KEY'] ?? undefined]
* @param {string | null | undefined} [opts.organization=process.env['OPENAI_ORG_ID'] ?? null]
* @param {string | null | undefined} [opts.project=process.env['OPENAI_PROJECT_ID'] ?? null]
* @param {string} [opts.baseURL=process.env['OPENAI_BASE_URL'] ?? https://api.openai.com/v1] - Override the default base URL for the API.
* @param {number} [opts.timeout=10 minutes] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
* @param {number} [opts.httpAgent] - An HTTP agent used to manage HTTP(s) connections.
* @param {Core.Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
* @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
* @param {Core.Headers} opts.defaultHeaders - Default headers to include with every request to the API.
* @param {Core.DefaultQuery} opts.defaultQuery - Default query parameters to include with every request to the API.
* @param {boolean} [opts.dangerouslyAllowBrowser=false] - By default, client-side use of this library is not allowed, as it risks exposing your secret API credentials to attackers.
*/
constructor({ baseURL = readEnv("OPENAI_BASE_URL"), apiKey = readEnv("OPENAI_API_KEY"), organization = ((_a2) => (_a2 = readEnv("OPENAI_ORG_ID")) != null ? _a2 : null)(), project = ((_b) => (_b = readEnv("OPENAI_PROJECT_ID")) != null ? _b : null)(), ...opts } = {}) {
var _a3;
if (apiKey === void 0) {
throw new OpenAIError("The OPENAI_API_KEY environment variable is missing or empty; either provide it, or instantiate the OpenAI client with an apiKey option, like new OpenAI({ apiKey: 'My API Key' }).");
}
const options = {
apiKey,
organization,
project,
...opts,
baseURL: baseURL || `https://api.openai.com/v1`
};
if (!options.dangerouslyAllowBrowser && isRunningInBrowser()) {
throw new OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew OpenAI({ apiKey, dangerouslyAllowBrowser: true });\n\nhttps://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety\n");
}
super({
baseURL: options.baseURL,
timeout: (_a3 = options.timeout) != null ? _a3 : 6e5,
httpAgent: options.httpAgent,
maxRetries: options.maxRetries,
fetch: options.fetch
});
this.completions = new Completions3(this);
this.chat = new Chat(this);
this.embeddings = new Embeddings(this);
this.files = new Files2(this);
this.images = new Images(this);
this.audio = new Audio(this);
this.moderations = new Moderations(this);
this.models = new Models(this);
this.fineTuning = new FineTuning(this);
this.beta = new Beta(this);
this.batches = new Batches(this);
this.uploads = new Uploads(this);
this._options = options;
this.apiKey = apiKey;
this.organization = organization;
this.project = project;
}
defaultQuery() {
return this._options.defaultQuery;
}
defaultHeaders(opts) {
return {
...super.defaultHeaders(opts),
"OpenAI-Organization": this.organization,
"OpenAI-Project": this.project,
...this._options.defaultHeaders
};
}
authHeaders(opts) {
return { Authorization: `Bearer ${this.apiKey}` };
}
stringifyQuery(query) {
return stringify(query, { arrayFormat: "brackets" });
}
};
_a = OpenAI;
OpenAI.OpenAI = _a;
OpenAI.DEFAULT_TIMEOUT = 6e5;
OpenAI.OpenAIError = OpenAIError;
OpenAI.APIError = APIError;
OpenAI.APIConnectionError = APIConnectionError;
OpenAI.APIConnectionTimeoutError = APIConnectionTimeoutError;
OpenAI.APIUserAbortError = APIUserAbortError;
OpenAI.NotFoundError = NotFoundError;
OpenAI.ConflictError = ConflictError;
OpenAI.RateLimitError = RateLimitError;
OpenAI.BadRequestError = BadRequestError;
OpenAI.AuthenticationError = AuthenticationError;
OpenAI.InternalServerError = InternalServerError;
OpenAI.PermissionDeniedError = PermissionDeniedError;
OpenAI.UnprocessableEntityError = UnprocessableEntityError;
OpenAI.toFile = toFile;
OpenAI.fileFromPath = fileFromPath;
OpenAI.Completions = Completions3;
OpenAI.Chat = Chat;
OpenAI.Embeddings = Embeddings;
OpenAI.Files = Files2;
OpenAI.FileObjectsPage = FileObjectsPage;
OpenAI.Images = Images;
OpenAI.Audio = Audio;
OpenAI.Moderations = Moderations;
OpenAI.Models = Models;
OpenAI.ModelsPage = ModelsPage;
OpenAI.FineTuning = FineTuning;
OpenAI.Beta = Beta;
OpenAI.Batches = Batches;
OpenAI.BatchesPage = BatchesPage;
OpenAI.Uploads = Uploads;
var openai_default = OpenAI;
// src/services/ai-service.ts
var import_obsidian = require("obsidian");
// src/services/logger.ts
var _Logger = class _Logger {
constructor(context) {
this.prefix = `[${context}]`;
}
// 只在开发环境下输出调试信息
debug(...args) {
if (_Logger.isDevelopment) {
console.log(this.prefix, ...args);
}
}
// 警告信息,生产环境也会输出
warn(...args) {
console.warn(this.prefix, ...args);
}
// 错误信息,生产环境也会输出
error(...args) {
console.error(this.prefix, ...args);
}
};
_Logger.isDevelopment = false;
var Logger = _Logger;
// src/services/ai-service.ts
var GEMINI_MODELS = {
"Gemini 1.5 Flash": "gemini-1.5-flash",
"Gemini 1.5 Flash-8B": "gemini-1.5-flash-8b",
"Gemini 1.5 Pro": "gemini-1.5-pro",
"Gemini 1.0 Pro": "gemini-1.0-pro",
"Text Embedding": "text-embedding-004",
"AQA": "aqa",
"\u81EA\u5B9A\u4E49\u6A21\u578B": "custom"
// 新增:自定义模型选项
};
var OPENAI_MODELS = {
// GPT-4o 系列
"GPT-4o": "gpt-4o",
"GPT-4o (2024-11-20)": "gpt-4o-2024-11-20",
"GPT-4o Mini": "gpt-4o-mini",
"GPT-4o Mini (2024-07-18)": "gpt-4o-mini-2024-07-18",
"GPT-4o Realtime": "gpt-4o-realtime-preview",
"GPT-4o Realtime (2024-10-01)": "gpt-4o-realtime-preview-2024-10-01",
"ChatGPT-4o Latest": "chatgpt-4o-latest",
"\u81EA\u5B9A\u4E49\u6A21\u578B": "custom"
// 已添加
};
var OLLAMA_MODELS = {
"Llama 2": "llama2",
"Mistral": "mistral",
"Mixtral": "mixtral",
"CodeLlama": "codellama",
"Phi": "phi",
"Neural Chat": "neural-chat",
"\u81EA\u5B9A\u4E49\u6A21\u578B": "custom"
};
var MODEL_DESCRIPTIONS = {
// Gemini Models
"gemini-1.5-flash": "\u97F3\u9891\u3001\u56FE\u7247\u3001\u89C6\u9891\u548C\u6587\u672C",
"gemini-1.5-flash-8b": "\u97F3\u9891\u3001\u56FE\u7247\u3001\u89C6\u9891\u548C\u6587\u672C",
"gemini-1.5-pro": "\u97F3\u9891\u3001\u56FE\u7247\u3001\u89C6\u9891\u548C\u6587\u672C",
"gemini-1.0-pro": "\u6587\u672C (\u5C06\u4E8E 2025 \u5E74 2 \u6708 15 \u65E5\u5F03\u7528)",
"text-embedding-004": "\u6587\u672C",
"aqa": "\u6587\u672C",
"custom": "\u81EA\u5B9A\u4E49\u6A21\u578B",
// OpenAI Models
"gpt-4o": "\u6807\u51C6\u7248 GPT-4o\uFF0C\u5F3A\u5927\u7684\u63A8\u7406\u80FD\u529B",
"gpt-4o-2024-11-20": "11\u6708\u5FEB\u7167\u7248\u672C\uFF0C\u7A33\u5B9A\u53EF\u9760",
"gpt-4o-mini": "\u8F7B\u91CF\u7EA7\u7248\u672C\uFF0C\u6027\u4EF7\u6BD4\u9AD8",
"gpt-4o-mini-2024-07-18": "Mini \u6A21\u578B\u7684\u7A33\u5B9A\u5FEB\u7167\u7248\u672C",
"gpt-4o-realtime-preview": "\u5B9E\u65F6\u9884\u89C8\u7248\u672C\uFF0C\u652F\u6301\u6700\u65B0\u7279\u6027",
"gpt-4o-realtime-preview-2024-10-01": "\u5B9E\u65F6\u9884\u89C8\u7684\u7A33\u5B9A\u5FEB\u7167\u7248\u672C",
"chatgpt-4o-latest": "ChatGPT \u4F7F\u7528\u7684\u6700\u65B0\u7248\u672C\uFF0C\u6301\u7EED\u66F4\u65B0",
// Ollama Models
"llama2": "Llama 2 - \u901A\u7528\u5927\u8BED\u8A00\u6A21\u578B",
"mistral": "Mistral - \u9AD8\u6027\u80FD\u5F00\u6E90\u6A21\u578B",
"mixtral": "Mixtral - \u6DF7\u5408\u4E13\u5BB6\u6A21\u578B",
"codellama": "CodeLlama - \u4EE3\u7801\u751F\u6210\u4E13\u7528\u6A21\u578B",
"phi": "Phi - \u8F7B\u91CF\u7EA7\u6A21\u578B",
"neural-chat": "Neural Chat - \u5BF9\u8BDD\u4F18\u5316\u6A21\u578B"
};
var MAX_RETRIES = 3;
var RETRY_DELAY = 1e3;
async function sleep2(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function retryWithBackoff(operation, maxRetries = MAX_RETRIES, initialDelay = RETRY_DELAY) {
for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
if (error instanceof Error && error.message.includes("429")) {
const delay2 = initialDelay * 2 ** i;
await sleep2(delay2);
continue;
}
if (i === maxRetries - 1) {
throw error;
}
const delay = initialDelay * 2 ** i;
await sleep2(delay);
}
}
throw new Error("\u91CD\u8BD5\u6B21\u6570\u5DF2\u8FBE\u4E0A\u9650");
}
var GeminiService = class {
constructor(apiKey, modelName) {
const genAI = new GoogleGenerativeAI(apiKey);
this.model = genAI.getGenerativeModel({ model: modelName || GEMINI_MODELS["Gemini 1.5 Flash"] });
this.logger = new Logger("GeminiService");
}
async initialize(apiKey, modelName) {
this.logger.debug("Gemini \u670D\u52A1\u521D\u59CB\u5316\u6210\u529F\uFF0C\u4F7F\u7528\u6A21\u578B:", this.model);
}
async handleRateLimit(error, retryCount) {
const delay = Math.min(1e3 * 2 ** retryCount, 3e4);
this.logger.warn(`\u914D\u989D\u9650\u5236\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5...`);
return delay;
}
async handleError(error, retryCount) {
const delay = Math.min(1e3 * 2 ** retryCount, 3e4);
this.logger.error(`\u64CD\u4F5C\u5931\u8D25\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5...`, error);
return delay;
}
async generateSummary(content, language = "zh") {
const prompt = `\u8BF7\u7528${language === "zh" ? "\u4E2D\u6587" : "English"}\u603B\u7ED3\u4EE5\u4E0B\u5185\u5BB9\u7684\u8981\u70B9\uFF1A
${content}`;
return retryWithBackoff(async () => {
const result = await this.model.generateContent(prompt);
const response = await result.response;
return response.text().trim();
});
}
async generateTags(content) {
const prompt = `\u8BF7\u4E3A\u4EE5\u4E0B\u5185\u5BB9\u751F\u62103-5\u4E2A\u76F8\u5173\u6807\u7B7E\uFF08\u4E0D\u8981\u5E26#\u53F7\uFF09\uFF1A
${content}`;
return retryWithBackoff(async () => {
const result = await this.model.generateContent(prompt);
const response = await result.response;
return response.text().split(/[,\s]+/).filter(Boolean);
});
}
async generateWeeklyDigest(contents) {
const combinedContent = contents.join("\n---\n");
const prompt = `\u8BF7\u5BF9\u4E0B\u4E00\u5468\u7684\u5185\u5BB9\u8FDB\u884C\u603B\u7ED3\u548C\u5206\u6790\uFF0C\u751F\u6210\u4E00\u4EFD\u5468\u62A5\u3002\u91CD\u70B9\u5173\u6CE8\uFF1A
1. \u4E3B\u8981\u5DE5\u4F5C\u5185\u5BB9\u548C\u6210\u679C
2. \u91CD\u8981\u4E8B\u9879\u548C\u8FDB\u5C55
3. \u95EE\u9898\u548C\u89E3\u51B3\u65B9\u6848
4. \u4E0B\u5468\u8BA1\u5212\u548C\u5C55\u671B
\u5185\u5BB9\uFF1A
${combinedContent}`;
return retryWithBackoff(async () => {
const result = await this.model.generateContent(prompt);
const response = await result.response;
return response.text().trim();
});
}
};
var OpenAIService = class {
// 生成随机 IV
async generateIV() {
return crypto.getRandomValues(new Uint8Array(12));
}
// 生成加密密钥
async generateKey() {
return crypto.subtle.generateKey(
{
name: "AES-GCM",
length: 256
},
true,
["encrypt", "decrypt"]
);
}
// 加密 API 密钥
async encryptApiKey(apiKey) {
const iv = await this.generateIV();
const key = await this.generateKey();
const encodedText = new TextEncoder().encode(apiKey);
const encryptedData = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv
},
key,
encodedText
);
const encryptedArray = new Uint8Array(encryptedData);
return `${this.arrayBufferToBase64(iv)}:${this.arrayBufferToBase64(encryptedArray)}:${this.arrayBufferToBase64(await crypto.subtle.exportKey("raw", key))}`;
}
// 解密 API 密钥
async decryptApiKey(encryptedKey) {
const [ivStr, encryptedStr, keyStr] = encryptedKey.split(":");
const iv = this.base64ToArrayBuffer(ivStr);
const encryptedData = this.base64ToArrayBuffer(encryptedStr);
const keyData = this.base64ToArrayBuffer(keyStr);
const key = await crypto.subtle.importKey(
"raw",
keyData,
"AES-GCM",
true,
["decrypt"]
);
const decryptedData = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv
},
key,
encryptedData
);
return new TextDecoder().decode(decryptedData);
}
arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binary = "";
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
base64ToArrayBuffer(base64) {
const binaryString = window.atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}
constructor() {
this.encryptionKey = crypto.getRandomValues(new Uint8Array(32));
this.logger = new Logger("OpenAIService");
}
async initialize(apiKey, modelName, openaiBaseUrl) {
try {
if (!apiKey) {
throw new Error("API \u5BC6\u94A5\u4E0D\u80FD\u4E3A\u7A7A");
}
if (!apiKey.startsWith("sk-") || apiKey.length < 20) {
throw new Error("\u65E0\u6548\u7684 API \u5BC6\u94A5\u683C\u5F0F");
}
const encryptedKey = await this.encryptApiKey(apiKey);
this.client = new openai_default({
apiKey: await this.decryptApiKey(encryptedKey),
baseURL: openaiBaseUrl,
dangerouslyAllowBrowser: true
});
try {
await this.client.models.list();
} catch (error) {
throw new Error("API \u5BC6\u94A5\u9A8C\u8BC1\u5931\u8D25");
}
this.model = modelName || OPENAI_MODELS["GPT-4o"];
this.logger.debug("OpenAI \u670D\u52A1\u521D\u59CB\u5316\u6210\u529F\uFF0C\u4F7F\u7528\u6A21\u578B:", this.model);
new import_obsidian.Notice(`AI \u670D\u52A1\u521D\u59CB\u5316\u6210\u529F`);
} catch (error) {
this.logger.error("OpenAI \u670D\u52A1\u521D\u59CB\u5316\u5931\u8D25:", error);
new import_obsidian.Notice(`AI \u670D\u52A1\u521D\u59CB\u5316\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
async generateSummary(content, language = "zh") {
const prompt = `\u8BF7\u7528${language === "zh" ? "\u4E2D\u6587" : "English"}\u603B\u7ED3\u4EE5\u4E0B\u5185\u5BB9\u7684\u8981\u70B9\uFF1A
${content}`;
return retryWithBackoff(async () => {
var _a2, _b, _c;
const response = await this.client.chat.completions.create({
model: this.model,
messages: [{ role: "user", content: prompt }],
temperature: 0.7,
max_tokens: 500
});
return ((_c = (_b = (_a2 = response.choices[0]) == null ? void 0 : _a2.message) == null ? void 0 : _b.content) == null ? void 0 : _c.trim()) || "";
});
}
async generateTags(content) {
const prompt = `\u8BF7\u4E3A\u4EE5\u4E0B\u5185\u5BB9\u751F\u62103-5\u4E2A\u76F8\u5173\u6807\u7B7E\uFF08\u4E0D\u8981\u5E26#\u53F7\uFF09\uFF1A
${content}`;
return retryWithBackoff(async () => {
var _a2, _b;
const response = await this.client.chat.completions.create({
model: this.model,
messages: [{ role: "user", content: prompt }],
temperature: 0.7,
max_tokens: 100
});
const text = ((_b = (_a2 = response.choices[0]) == null ? void 0 : _a2.message) == null ? void 0 : _b.content) || "";
return text.split(/[,\s]+/).filter(Boolean);
});
}
async generateWeeklyDigest(contents) {
const combinedContent = contents.join("\n---\n");
const prompt = `\u8BF7\u5BF9\u4EE5\u4E0B\u4E00\u5468\u7684\u5185\u5BB9\u8FDB\u884C\u603B\u7ED3\u548C\u5206\u6790\uFF0C\u751F\u6210\u4E00\u4EFD\u5468\u62A5\u3002\u8981\u6C42\uFF1A
1. \u4E3B\u8981\u5DE5\u4F5C\u5185\u5BB9\u548C\u6210\u679C
2. \u91CD\u8981\u4E8B\u9879\u548C\u8FDB\u5C55
3. \u95EE\u9898\u548C\u89E3\u51B3\u65B9\u6848
4. \u4E0B\u5468\u8BA1\u5212\u548C\u5C55\u671B
\u5185\u5BB9\uFF1A
${combinedContent}`;
return retryWithBackoff(async () => {
var _a2, _b, _c;
const response = await this.client.chat.completions.create({
model: this.model,
messages: [{ role: "user", content: prompt }],
temperature: 0.7,
max_tokens: 1e3
});
return ((_c = (_b = (_a2 = response.choices[0]) == null ? void 0 : _a2.message) == null ? void 0 : _b.content) == null ? void 0 : _c.trim()) || "";
});
}
};
var OllamaService = class {
constructor(baseUrl = "http://localhost:11434", modelName) {
this.baseUrl = baseUrl;
this.model = modelName || OLLAMA_MODELS["Llama 2"];
this.logger = new Logger("OllamaService");
}
async initialize(apiKey, modelName) {
this.logger.debug("Ollama \u670D\u52A1\u521D\u59CB\u5316\u6210\u529F\uFF0C\u4F7F\u7528\u6A21\u578B:", this.model);
}
async handleRateLimit(error, retryCount) {
const delay = Math.min(1e3 * 2 ** retryCount, 3e4);
this.logger.warn(`\u914D\u989D\u9650\u5236\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5...`);
return delay;
}
async handleError(error, retryCount) {
const delay = Math.min(1e3 * 2 ** retryCount, 3e4);
this.logger.error(`\u64CD\u4F5C\u5931\u8D25\uFF0C\u7B49\u5F85 ${delay}ms \u540E\u91CD\u8BD5...`, error);
return delay;
}
async generateCompletion(prompt) {
try {
const response = await (0, import_obsidian.requestUrl)({
url: `${this.baseUrl}/api/generate`,
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
model: this.model,
prompt,
stream: false,
options: {
temperature: 0.7,
top_p: 0.9,
max_tokens: 1e3
}
})
});
if (response.status !== 200) {
throw new Error(`Ollama API error: ${response.status}`);
}
const data = response.json;
return data.response;
} catch (error) {
this.logger.error("Ollama API error:", error);
throw error;
}
}
async generateSummary(content, language = "zh") {
const prompt = `\u8BF7\u7528${language === "zh" ? "\u4E2D\u6587" : "English"}\u603B\u7ED3\u4EE5\u4E0B\u5185\u5BB9\u7684\u8981\u70B9\uFF1A
${content}`;
return retryWithBackoff(async () => {
const response = await this.generateCompletion(prompt);
return response.trim();
});
}
async generateTags(content) {
const prompt = `\u8BF7\u4E3A\u4EE5\u4E0B\u5185\u5BB9\u751F\u62103-5\u4E2A\u76F8\u5173\u6807\u7B7E\uFF08\u4E0D\u8981\u5E26#\u53F7\uFF09\uFF1A
${content}`;
return retryWithBackoff(async () => {
const response = await this.generateCompletion(prompt);
return response.split(/[,\s]+/).filter(Boolean);
});
}
async generateWeeklyDigest(contents) {
const combinedContent = contents.join("\n---\n");
const prompt = `\u8BF7\u5BF9\u4EE5\u4E0B\u4E00\u5468\u7684\u5185\u5BB9\u8FDB\u884C\u603B\u7ED3\u548C\u5206\u6790\uFF0C\u751F\u6210\u4E00\u4EFD\u5468\u62A5\u3002\u8981\u6C42\uFF1A
1. \u4E3B\u8981\u5DE5\u4F5C\u5185\u5BB9\u548C\u6210\u679C
2. \u91CD\u8981\u4E8B\u9879\u548C\u8FDB\u5C55
3. \u95EE\u9898\u548C\u89E3\u51B3\u65B9\u6848
4. \u4E0B\u5468\u8BA1\u5212\u548C\u5C55\u671B
\u5185\u5BB9\uFF1A
${combinedContent}`;
return retryWithBackoff(async () => {
const response = await this.generateCompletion(prompt);
return response.trim();
});
}
};
function createAIService(type, apiKey, modelName, openaiBaseUrl) {
const serviceType = type.toLowerCase();
switch (serviceType) {
case "gemini": {
const service = new GeminiService(apiKey, modelName);
void service.initialize(apiKey, modelName);
return service;
}
case "openai": {
const service = new OpenAIService();
void service.initialize(apiKey, modelName, openaiBaseUrl);
return service;
}
case "ollama": {
const service = new OllamaService(apiKey || "http://localhost:11434", modelName);
void service.initialize(apiKey, modelName);
return service;
}
default: {
const service = createDummyAIService();
void service.initialize("", "");
return service;
}
}
}
function createDummyAIService() {
const logger = new Logger("DummyAIService");
return {
async generateSummary() {
logger.debug("\u4F7F\u7528\u7A7A AI \u670D\u52A1");
return "";
},
async generateTags() {
logger.debug("\u4F7F\u7528\u7A7A AI \u670D\u52A1");
return [];
},
async generateWeeklyDigest() {
logger.debug("\u4F7F\u7528\u7A7A AI \u670D\u52A1");
return "";
},
async initialize() {
logger.debug("\u521D\u59CB\u5316\u7A7A AI \u670D\u52A1");
}
};
}
// src/ui/settings-tab.ts
var MemosSyncSettingTab = class extends import_obsidian2.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian2.Setting(containerEl).setName("Memos API URL").setDesc("\u60A8\u7684 Memos \u670D\u52A1\u5668 API \u5730\u5740,\u683C\u5F0F\u5982\uFF1Ahttps://memose.com/api/v1 ").addText((text) => text.setPlaceholder("https://x.com/api/v1").setValue(this.plugin.settings.memosApiUrl).onChange(async (value) => {
this.plugin.settings.memosApiUrl = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("\u8BBF\u95EE\u4EE4\u724C").setDesc("\u60A8\u7684 Memos API \u8BBF\u95EE\u4EE4\u724C").addText((text) => text.setPlaceholder("\u8F93\u5165\u8BBF\u95EE\u4EE4\u724C").setValue(this.plugin.settings.memosAccessToken).onChange(async (value) => {
this.plugin.settings.memosAccessToken = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("\u540C\u6B65\u76EE\u5F55").setDesc("Memos \u5185\u5BB9\u5728 Obsidian \u4E2D\u7684\u5B58\u50A8\u4F4D\u7F6E").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1Amemos").setValue(this.plugin.settings.syncDirectory).onChange(async (value) => {
this.plugin.settings.syncDirectory = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("\u540C\u6B65\u6A21\u5F0F").setDesc("\u9009\u62E9\u624B\u52A8\u540C\u6B65\u6216\u81EA\u52A8\u540C\u6B65").addDropdown((dropdown) => dropdown.addOption("manual", "\u624B\u52A8\u540C\u6B65").addOption("auto", "\u81EA\u52A8\u540C\u6B65").setValue(this.plugin.settings.syncFrequency).onChange(async (value) => {
this.plugin.settings.syncFrequency = value;
await this.plugin.saveSettings();
this.display();
}));
if (this.plugin.settings.syncFrequency === "auto") {
new import_obsidian2.Setting(containerEl).setName("\u540C\u6B65\u95F4\u9694").setDesc("\u81EA\u52A8\u540C\u6B65\u7684\u65F6\u95F4\u95F4\u9694\uFF08\u5206\u949F\uFF09").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1A30").setValue(String(this.plugin.settings.autoSyncInterval)).onChange(async (value) => {
const interval = Number.parseInt(value, 10);
if (Number.isFinite(interval) && interval > 0) {
this.plugin.settings.autoSyncInterval = interval;
await this.plugin.saveSettings();
}
}));
}
new import_obsidian2.Setting(containerEl).setName("\u540C\u6B65\u6761\u6570").setDesc("\u6BCF\u6B21\u540C\u6B65\u7684\u6700\u5927\u6761\u76EE\u6570").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1A100").setValue(String(this.plugin.settings.syncLimit)).onChange(async (value) => {
const limit2 = Number.parseInt(value, 10);
if (Number.isFinite(limit2) && limit2 > 0) {
this.plugin.settings.syncLimit = limit2;
await this.plugin.saveSettings();
}
}));
new import_obsidian2.Setting(containerEl).setName("\u542F\u7528 AI \u529F\u80FD").setDesc("\u5F00\u542F\u6216\u5173\u95ED AI \u589E\u5F3A\u529F\u80FD").addToggle((toggle) => toggle.setValue(this.plugin.settings.ai.enabled).onChange(async (value) => {
this.plugin.settings.ai.enabled = value;
await this.plugin.saveSettings();
this.display();
}));
if (this.plugin.settings.ai.enabled) {
new import_obsidian2.Setting(containerEl).setName("AI \u6A21\u578B").setDesc("\u9009\u62E9\u8981\u4F7F\u7528\u7684 AI \u6A21\u578B").addDropdown((dropdown) => dropdown.addOption("openai", "OpenAI").addOption("gemini", "Google Gemini").addOption("claude", "Anthropic Claude").addOption("ollama", "Ollama").setValue(this.plugin.settings.ai.modelType).onChange(async (value) => {
this.plugin.settings.ai.modelType = value;
await this.plugin.saveSettings();
this.display();
}));
if (this.plugin.settings.ai.modelType !== "ollama") {
new import_obsidian2.Setting(containerEl).setName("API \u5BC6\u94A5").setDesc("\u60A8\u7684 AI \u670D\u52A1 API \u5BC6\u94A5").addText((text) => text.setPlaceholder("\u8F93\u5165 API \u5BC6\u94A5").setValue(this.plugin.settings.ai.apiKey).onChange(async (value) => {
this.plugin.settings.ai.apiKey = value;
await this.plugin.saveSettings();
}));
}
this.displayModelOptions(containerEl);
new import_obsidian2.Setting(containerEl).setName("\u6BCF\u5468\u6C47\u603B").setDesc("\u81EA\u52A8\u751F\u6210\u6BCF\u5468\u5185\u5BB9\u6C47\u603B").addToggle((toggle) => toggle.setValue(this.plugin.settings.ai.weeklyDigest).onChange(async (value) => {
this.plugin.settings.ai.weeklyDigest = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("\u81EA\u52A8\u6807\u7B7E").setDesc("\u6839\u636E\u5185\u5BB9\u81EA\u52A8\u751F\u6210\u6807\u7B7E").addToggle((toggle) => toggle.setValue(this.plugin.settings.ai.autoTags).onChange(async (value) => {
this.plugin.settings.ai.autoTags = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("\u667A\u80FD\u6458\u8981").setDesc("\u81EA\u52A8\u751F\u6210\u5185\u5BB9\u6458\u8981").addToggle((toggle) => toggle.setValue(this.plugin.settings.ai.intelligentSummary).onChange(async (value) => {
this.plugin.settings.ai.intelligentSummary = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("\u6458\u8981\u8BED\u8A00").setDesc("\u9009\u62E9\u6458\u8981\u751F\u6210\u7684\u8BED\u8A00").addDropdown((dropdown) => dropdown.addOption("zh", "\u4E2D\u6587").addOption("en", "\u82F1\u6587").addOption("ja", "\u65E5\u6587").addOption("ko", "\u97E9\u6587").setValue(this.plugin.settings.ai.summaryLanguage).onChange(async (value) => {
this.plugin.settings.ai.summaryLanguage = value;
await this.plugin.saveSettings();
}));
}
}
displayModelOptions(containerEl) {
const modelType = this.plugin.settings.ai.modelType;
if (modelType === "gemini") {
new import_obsidian2.Setting(containerEl).setName("Gemini \u6A21\u578B").setDesc("\u9009\u62E9\u8981\u4F7F\u7528\u7684 Gemini \u6A21\u578B").addDropdown((dropdown) => {
for (const [displayName, modelId] of Object.entries(GEMINI_MODELS)) {
dropdown.addOption(modelId, `${displayName} - ${MODEL_DESCRIPTIONS[modelId]}`);
}
const currentModel = this.plugin.settings.ai.modelName || GEMINI_MODELS["Gemini 1.5 Flash"];
dropdown.setValue(currentModel);
dropdown.onChange(async (value) => {
this.plugin.settings.ai.modelName = value;
await this.plugin.saveSettings();
this.display();
});
});
if (this.plugin.settings.ai.modelName === "custom") {
new import_obsidian2.Setting(containerEl).setName("\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").setDesc("\u8F93\u5165\u8981\u4F7F\u7528\u7684\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1Agemini-pro-latest").setValue(this.plugin.settings.ai.customModelName).onChange(async (value) => {
this.plugin.settings.ai.customModelName = value;
await this.plugin.saveSettings();
}));
}
} else if (modelType === "openai") {
new import_obsidian2.Setting(containerEl).setName("OpenAI \u6A21\u578B").setDesc("\u9009\u62E9\u8981\u4F7F\u7528\u7684 OpenAI \u6A21\u578B").addDropdown((dropdown) => {
for (const [displayName, modelId] of Object.entries(OPENAI_MODELS)) {
dropdown.addOption(modelId, `${displayName} - ${MODEL_DESCRIPTIONS[modelId]}`);
}
const currentModel = this.plugin.settings.ai.modelName || OPENAI_MODELS["GPT-4o"];
dropdown.setValue(currentModel);
dropdown.onChange(async (value) => {
this.plugin.settings.ai.modelName = value;
await this.plugin.saveSettings();
this.display();
});
});
if (this.plugin.settings.ai.modelName === "custom") {
new import_obsidian2.Setting(containerEl).setName("\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").setDesc("\u8F93\u5165\u8981\u4F7F\u7528\u7684\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1Agpt-4-1106-preview").setValue(this.plugin.settings.ai.customModelName).onChange(async (value) => {
this.plugin.settings.ai.customModelName = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("OpenAI API \u57FA\u7840\u94FE\u63A5").setDesc("\u5982\u679C\u4F7F\u7528\u81EA\u5B9A\u4E49 API \u670D\u52A1\uFF0C\u8BF7\u8BBE\u7F6E\u5BF9\u5E94\u7684\u57FA\u7840\u94FE\u63A5").addText((text) => text.setPlaceholder("https://api.openai.com/v1").setValue(this.plugin.settings.ai.openaiBaseUrl || "https://api.openai.com/v1").onChange(async (value) => {
this.plugin.settings.ai.openaiBaseUrl = value;
await this.plugin.saveSettings();
}));
}
} else if (modelType === "claude") {
new import_obsidian2.Setting(containerEl).setName("Claude \u6A21\u578B").setDesc("\u9009\u62E9\u8981\u4F7F\u7528\u7684 Claude \u6A21\u578B").addDropdown((dropdown) => {
dropdown.addOption("claude-3-opus-20240229", "Claude 3 Opus").addOption("claude-3-sonnet-20240229", "Claude 3 Sonnet").addOption("claude-3-haiku-20240307", "Claude 3 Haiku").addOption("custom", "\u81EA\u5B9A\u4E49\u6A21\u578B - \u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0");
const currentModel = this.plugin.settings.ai.modelName || "claude-3-opus-20240229";
dropdown.setValue(currentModel);
dropdown.onChange(async (value) => {
this.plugin.settings.ai.modelName = value;
await this.plugin.saveSettings();
this.display();
});
});
if (this.plugin.settings.ai.modelName === "custom") {
new import_obsidian2.Setting(containerEl).setName("\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").setDesc("\u8F93\u5165\u8981\u4F7F\u7528\u7684\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1Aclaude-3-opus-next").setValue(this.plugin.settings.ai.customModelName).onChange(async (value) => {
this.plugin.settings.ai.customModelName = value;
await this.plugin.saveSettings();
}));
}
} else if (modelType === "ollama") {
new import_obsidian2.Setting(containerEl).setName("Ollama \u670D\u52A1\u5730\u5740").setDesc("\u8BBE\u7F6E Ollama \u670D\u52A1\u7684\u5730\u5740\uFF08\u9ED8\u8BA4\u4E3A http://localhost:11434\uFF09").addText((text) => text.setPlaceholder("http://localhost:11434").setValue(this.plugin.settings.ai.ollamaBaseUrl).onChange(async (value) => {
this.plugin.settings.ai.ollamaBaseUrl = value;
await this.plugin.saveSettings();
}));
new import_obsidian2.Setting(containerEl).setName("Ollama \u6A21\u578B").setDesc("\u9009\u62E9\u8981\u4F7F\u7528\u7684 Ollama \u6A21\u578B").addDropdown((dropdown) => {
for (const [displayName, modelId] of Object.entries(OLLAMA_MODELS)) {
if (typeof modelId === "string") {
dropdown.addOption(modelId, `${displayName} - ${MODEL_DESCRIPTIONS[modelId] || modelId}`);
}
}
const defaultModel = OLLAMA_MODELS["Llama 2"];
const currentModel = this.plugin.settings.ai.modelName || defaultModel;
dropdown.setValue(currentModel);
dropdown.onChange(async (value) => {
this.plugin.settings.ai.modelName = value;
await this.plugin.saveSettings();
this.display();
});
});
if (this.plugin.settings.ai.modelName === "custom") {
new import_obsidian2.Setting(containerEl).setName("\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").setDesc("\u8F93\u5165\u8981\u4F7F\u7528\u7684\u81EA\u5B9A\u4E49\u6A21\u578B\u540D\u79F0").addText((text) => text.setPlaceholder("\u4F8B\u5982\uFF1Allama2:13b").setValue(this.plugin.settings.ai.customModelName).onChange(async (value) => {
this.plugin.settings.ai.customModelName = value;
await this.plugin.saveSettings();
}));
}
}
}
};
// src/services/memos-service.ts
var import_obsidian3 = require("obsidian");
var MemosService = class {
constructor(apiUrl, accessToken, syncLimit) {
this.apiUrl = apiUrl;
this.accessToken = accessToken;
this.syncLimit = syncLimit;
this.logger = new Logger("MemosService");
}
async fetchAllMemos() {
try {
this.logger.debug("\u5F00\u59CB\u83B7\u53D6 memos\uFF0CAPI URL:", this.apiUrl);
this.logger.debug("Access Token:", this.accessToken ? "\u5DF2\u8BBE\u7F6E" : "\u672A\u8BBE\u7F6E");
this.logger.debug("\u540C\u6B65\u9650\u5236:", this.syncLimit, "\u6761");
const allMemos = [];
let pageToken;
const pageSize = Math.min(100, this.syncLimit);
if (!this.apiUrl.includes("/api/v1")) {
throw new Error("API URL \u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u786E\u4FDD\u5305\u542B /api/v1");
}
do {
const baseUrl = this.apiUrl;
const url = `${baseUrl}/memos`;
const params = new URLSearchParams({
"state": "NORMAL",
"pageSize": pageSize.toString()
});
if (pageToken) {
params.set("pageToken", pageToken);
}
const finalUrl = `${url}?${params.toString()}`;
this.logger.debug("\u8BF7\u6C42 URL:", finalUrl);
const response = await (0, import_obsidian3.requestUrl)({
url: finalUrl,
headers: {
"Authorization": `Bearer ${this.accessToken}`,
"Accept": "application/json"
}
});
if (response.status !== 200) {
throw new Error(`HTTP ${response.status}: \u8BF7\u6C42\u5931\u8D25
\u54CD\u5E94\u5185\u5BB9: ${response.text}`);
}
const responseData = response.json;
this.logger.debug("API \u54CD\u5E94\u6570\u636E:", responseData);
if (!responseData || !Array.isArray(responseData.memos)) {
throw new Error("\u54CD\u5E94\u683C\u5F0F\u65E0\u6548: \u8FD4\u56DE\u6570\u636E\u4E0D\u5305\u542B memos \u6570\u7EC4");
}
const memos = responseData.memos;
pageToken = responseData.nextPageToken;
if (memos.length === 0) {
break;
}
const remainingCount = this.syncLimit - allMemos.length;
const neededCount = Math.min(memos.length, remainingCount);
allMemos.push(...memos.slice(0, neededCount));
this.logger.debug(`\u672C\u6B21\u83B7\u53D6 ${neededCount} \u6761 memos\uFF0C\u603B\u8BA1: ${allMemos.length}/${this.syncLimit}`);
if (allMemos.length >= this.syncLimit || !pageToken) {
break;
}
} while (true);
this.logger.debug(`\u6700\u7EC8\u8FD4\u56DE ${allMemos.length} \u6761 memos`);
return allMemos.sort(
(a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime()
);
} catch (error) {
this.logger.error("\u83B7\u53D6 memos \u5931\u8D25:", error);
if (error instanceof TypeError && error.message === "Failed to fetch") {
throw new Error(`\u7F51\u7EDC\u9519\u8BEF: \u65E0\u6CD5\u8FDE\u63A5\u5230 ${this.apiUrl}\u3002\u8BF7\u68C0\u67E5 URL \u662F\u5426\u6B63\u786E\u4E14\u53EF\u8BBF\u95EE\u3002`);
}
throw error;
}
}
async downloadResource(resource) {
try {
const attachmentId = resource.name.split("/").pop() || resource.name;
const resourceUrl = `${this.apiUrl.replace("/api/v1", "")}/file/attachments/${attachmentId}/${encodeURIComponent(resource.filename)}`;
this.logger.debug(`\u6B63\u5728\u4E0B\u8F7D\u8D44\u6E90: ${resourceUrl}`);
const response = await (0, import_obsidian3.requestUrl)({
url: resourceUrl,
headers: {
"Authorization": `Bearer ${this.accessToken}`,
"Accept": "*/*"
},
method: "GET"
});
if (response.status !== 200) {
this.logger.error(`\u4E0B\u8F7D\u8D44\u6E90\u5931\u8D25: ${response.status}`);
this.logger.error(`\u54CD\u5E94\u5185\u5BB9: ${response.text}`);
return null;
}
if ("arrayBuffer" in response && response.arrayBuffer) {
this.logger.debug(`\u6210\u529F\u83B7\u53D6\u8D44\u6E90\uFF0C\u5927\u5C0F: ${response.arrayBuffer.byteLength} \u5B57\u8282`);
return response.arrayBuffer;
} else {
this.logger.warn("\u54CD\u5E94\u4E2D\u6CA1\u6709 arrayBuffer \u5C5E\u6027");
return null;
}
} catch (error) {
this.logger.error("\u4E0B\u8F7D\u8D44\u6E90\u65F6\u51FA\u9519:", error);
return null;
}
}
};
// src/services/file-service.ts
var import_obsidian4 = require("obsidian");
var FileService = class {
constructor(vault, syncDirectory, memosService) {
this.vault = vault;
this.syncDirectory = syncDirectory;
this.memosService = memosService;
this.logger = new Logger("FileService");
}
formatDateTime(date, format = "display") {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
if (format === "filename") {
return `${year}-${month}-${day} ${hours}-${minutes}`;
}
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
sanitizeFileName(fileName) {
let sanitized = fileName.replace(/^[\\/:*?"<>|#\s]+/, "");
sanitized = sanitized.replace(/\s+/g, " ").replace(/[\\/:*?"<>|#]/g, "").trim();
return sanitized || "untitled";
}
getRelativePath(fromPath, toPath) {
const fromParts = fromPath.split("/");
const toParts = toPath.split("/");
fromParts.pop();
let i = 0;
while (i < fromParts.length && i < toParts.length && fromParts[i] === toParts[i]) {
i++;
}
const goBack = fromParts.length - i;
const relativePath = [
...Array(goBack).fill(".."),
...toParts.slice(i)
].join("/");
return relativePath;
}
isImageFile(filename) {
const imageExtensions = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"];
const ext = filename.toLowerCase().split(".").pop();
return ext ? imageExtensions.includes(`.${ext}`) : false;
}
async ensureDirectoryExists(dirPath) {
if (!await this.vault.adapter.exists(dirPath)) {
await this.vault.adapter.mkdir(dirPath);
}
}
getContentPreview(content) {
let preview = content.replace(/^>\s*\[!.*?\].*$/gm, "").replace(/^>\s.*$/gm, "").replace(/^\s*#\s+/gm, "").replace(/[_*~`]|_{2,}|\*{2,}|~{2,}/g, "").replace(/\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/!\[([^\]]*)\]\([^)]*\)/g, "").replace(/\n+/g, " ").trim();
if (!preview) {
return "Untitled";
}
if (preview.length > 50) {
preview = `${preview.slice(0, 50)}...`;
}
return preview;
}
async getMemoFiles() {
const files = [];
const processDirectory = async (dirPath) => {
const items = await this.vault.adapter.list(dirPath);
for (const file of items.files) {
if (file.endsWith(".md")) {
files.push(file);
}
}
for (const dir of items.folders) {
await processDirectory(dir);
}
};
await processDirectory(this.syncDirectory);
return files;
}
async isMemoExists(memoId) {
try {
const files = await this.getMemoFiles();
for (const file of files) {
const content = await this.vault.adapter.read(file);
if (content.includes(`> - ID: ${memoId}`)) {
return true;
}
}
return false;
} catch (error) {
this.logger.error("\u68C0\u67E5 memo \u662F\u5426\u5B58\u5728\u65F6\u51FA\u9519:", error instanceof Error ? error.message : String(error));
return false;
}
}
async saveMemoToFile(memo) {
try {
const exists = await this.isMemoExists(memo.name);
if (exists) {
this.logger.debug(`Memo ${memo.name} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7`);
return;
}
const date = new Date(memo.createTime);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const yearDir = `${this.syncDirectory}/${year}`;
const monthDir = `${yearDir}/${month}`;
await this.ensureDirectoryExists(yearDir);
await this.ensureDirectoryExists(monthDir);
const contentPreview = memo.content ? this.getContentPreview(memo.content) : this.sanitizeFileName(memo.name.replace("memos/", ""));
const timeStr = this.formatDateTime(date, "filename");
const fileName = this.sanitizeFileName(`${contentPreview} (${timeStr}).md`);
const filePath = `${monthDir}/${fileName}`;
let content = memo.content || "";
content = content.replace(/\#([^\#\s]+)\#/g, "#$1");
let documentContent = content;
if (memo.attachments && memo.attachments.length > 0) {
const images = memo.attachments.filter((r) => this.isImageFile(r.filename));
const otherFiles = memo.attachments.filter((r) => !this.isImageFile(r.filename));
if (images.length > 0) {
documentContent += "\n\n";
for (const image of images) {
const resourceData = await this.memosService.downloadResource(image);
if (resourceData) {
const resourceDir = `${monthDir}/resources`;
await this.ensureDirectoryExists(resourceDir);
const localFilename = `${image.name.split("/").pop()}_${this.sanitizeFileName(image.filename)}`;
const localPath = `${resourceDir}/${localFilename}`;
await this.vault.adapter.writeBinary(localPath, resourceData);
const relativePath = this.getRelativePath(filePath, localPath);
documentContent += `![${image.filename}](${relativePath})
`;
}
}
}
if (otherFiles.length > 0) {
documentContent += "\n\n### Attachments\n";
for (const file of otherFiles) {
const resourceData = await this.memosService.downloadResource(file);
if (resourceData) {
const resourceDir = `${monthDir}/resources`;
await this.ensureDirectoryExists(resourceDir);
const localFilename = `${file.name.split("/").pop()}_${this.sanitizeFileName(file.filename)}`;
const localPath = `${resourceDir}/${localFilename}`;
await this.vault.adapter.writeBinary(localPath, resourceData);
const relativePath = this.getRelativePath(filePath, localPath);
documentContent += `- [${file.filename}](${relativePath})
`;
}
}
}
}
const tags = (memo.content || "").match(/\#([^\#\s]+)(?:\#|\s|$)/g) || [];
const cleanTags = tags.map((tag) => tag.replace(/^\#|\#$/g, "").trim());
documentContent += "\n\n---\n";
documentContent += "> [!note]- Memo Properties\n";
documentContent += `> - Created: ${this.formatDateTime(new Date(memo.createTime))}
`;
documentContent += `> - Updated: ${this.formatDateTime(new Date(memo.updateTime))}
`;
documentContent += "> - Type: memo\n";
if (cleanTags.length > 0) {
documentContent += `> - Tags: [${cleanTags.join(", ")}]
`;
}
documentContent += `> - ID: ${memo.name}
`;
documentContent += `> - Visibility: ${memo.visibility.toLowerCase()}
`;
try {
const exists2 = await this.vault.adapter.exists(filePath);
if (exists2) {
const abstractFile = this.vault.getAbstractFileByPath(filePath);
if (abstractFile instanceof import_obsidian4.TFile) {
await this.vault.modify(abstractFile, documentContent);
} else {
throw new Error("Invalid file type");
}
} else {
await this.vault.create(filePath, documentContent);
}
} catch (error) {
console.error(`Failed to save memo to file: ${filePath}`, error);
throw new Error(`Failed to save memo: ${error.message}`);
}
} catch (error) {
this.logger.error("\u4FDD\u5B58 memo \u5230\u6587\u4EF6\u65F6\u51FA\u9519:", error instanceof Error ? error.message : String(error));
throw new Error(`\u4FDD\u5B58 memo \u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
}
}
};
// src/services/content-service.ts
var ContentService = class {
constructor(aiService, aiEnabled, enableSummary, enableTags, summaryLanguage, vault, syncDirectory) {
this.aiService = aiService;
this.aiEnabled = aiEnabled;
this.enableSummary = enableSummary;
this.enableTags = enableTags;
this.summaryLanguage = summaryLanguage;
this.vault = vault;
this.syncDirectory = syncDirectory;
}
isContentSuitableForAI(content) {
const cleanContent = content.replace(/\[([^\]]*)\]\([^)]*\)/g, "").replace(/!\[([^\]]*)\]\([^)]*\)/g, "").replace(/```[\s\S]*?```/g, "").trim();
return cleanContent.length >= 10;
}
async processMemoContent(memo) {
const { content } = memo;
const title = this.extractTitle(content);
const mainContent = title ? content.slice(title.length).trim() : content;
let processedContent = title ? `# ${title}
` : "";
if (this.aiEnabled && this.isContentSuitableForAI(content)) {
if (this.enableSummary) {
const summary = await this.aiService.generateSummary(content, this.summaryLanguage);
if (summary == null ? void 0 : summary.trim()) {
processedContent += `> [!abstract]+ \u5185\u5BB9\u6458\u8981
> ${summary.replace(/\n/g, "\n> ")}
`;
}
}
if (this.enableTags) {
const tags = await this.aiService.generateTags(content);
if ((tags == null ? void 0 : tags.length) > 0) {
processedContent += `> [!info]- \u76F8\u5173\u6807\u7B7E
> ${tags.map((tag) => `#${tag}`).join(" ")}
`;
}
}
}
processedContent += mainContent;
return processedContent.trim();
}
extractTitle(content) {
const lines = content.split("\n");
const firstLine = lines[0].trim();
if (firstLine.startsWith("# ")) {
return firstLine.slice(2).trim();
}
return null;
}
async weeklyDigestExists(year, week) {
const weeklyDigestPath = this.getWeeklyDigestPath(year, week);
return await this.vault.adapter.exists(weeklyDigestPath);
}
getWeeklyDigestPath(year, week) {
const weeklyDigestDir = `${this.syncDirectory}/${year}/weekly`;
const fileName = `\u7B2C${week}\u5468\u603B\u7ED3.md`;
return `${weeklyDigestDir}/${fileName}`;
}
async ensureDirectoryExists(dirPath) {
if (!await this.vault.adapter.exists(dirPath)) {
await this.vault.adapter.mkdir(dirPath);
}
}
async generateWeeklyDigest(memos) {
if (!this.aiEnabled) {
return;
}
const suitableMemos = memos.filter((memo) => this.isContentSuitableForAI(memo.content));
if (suitableMemos.length === 0) {
return;
}
const weekGroups = this.groupMemosByWeek(suitableMemos);
for (const [weekKey, weekMemos] of Object.entries(weekGroups)) {
const [year, week] = weekKey.split("-W");
if (await this.weeklyDigestExists(year, week)) {
continue;
}
const weeklyDigestDir = `${this.syncDirectory}/${year}/weekly`;
await this.ensureDirectoryExists(weeklyDigestDir);
const contents = weekMemos.map((memo) => memo.content);
const digest = await this.aiService.generateWeeklyDigest(contents);
if (digest == null ? void 0 : digest.trim()) {
const weeklyContent = this.formatWeeklyDigest(digest, year, week, weekMemos.length);
const weeklyDigestPath = this.getWeeklyDigestPath(year, week);
try {
await this.vault.create(weeklyDigestPath, weeklyContent);
} catch (error) {
console.error(`\u751F\u6210\u7B2C ${week} \u5468\u603B\u7ED3\u5931\u8D25:`, error);
}
}
}
}
formatWeeklyDigest(digest, year, week, memoCount) {
const weekRange = this.getWeekDateRange(Number.parseInt(year, 10), Number.parseInt(week, 10));
return `# \u{1F4C5} \u7B2C ${week} \u5468\u56DE\u987E (${weekRange})
## \u{1F31F} \u672C\u5468\u4EAE\u70B9
${digest}
## \u{1F4CA} \u7EDF\u8BA1\u6570\u636E
- \u{1F4DD} \u8BB0\u5F55\u6570\u91CF\uFF1A${memoCount} \u6761
- \u{1F4C5} \u65F6\u95F4\u8303\u56F4\uFF1A${weekRange}
## \u{1F4AA} \u4E0B\u5468\u5C55\u671B
> [!quote] \u6FC0\u52B1\u8BED\u5F55
> \u6BCF\u4E00\u4E2A\u5F53\u4E0B\u90FD\u662F\u672A\u6765\u7684\u8D77\u70B9\uFF0C\u8BA9\u6211\u4EEC\u7EE7\u7EED\u524D\u884C\uFF0C\u521B\u9020\u66F4\u591A\u7CBE\u5F69\uFF01
---
*\u751F\u6210\u65F6\u95F4\uFF1A${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN", { hour12: false })}*
`;
}
getWeekDateRange(year, week) {
const firstDayOfYear = new Date(year, 0, 1);
const daysToFirstMonday = (8 - firstDayOfYear.getDay()) % 7;
const firstMonday = new Date(year, 0, 1 + daysToFirstMonday);
const weekStart = new Date(firstMonday);
weekStart.setDate(firstMonday.getDate() + (week - 1) * 7);
const weekEnd = new Date(weekStart);
weekEnd.setDate(weekStart.getDate() + 6);
const formatDate = (date) => {
return `${date.getMonth() + 1}\u6708${date.getDate()}\u65E5`;
};
return `${formatDate(weekStart)} - ${formatDate(weekEnd)}`;
}
groupMemosByWeek(memos) {
const groups = {};
for (const memo of memos) {
const date = new Date(memo.createTime);
const year = date.getFullYear();
const week = this.getWeekNumber(date);
const key = `${year}-W${week.toString().padStart(2, "0")}`;
if (!groups[key]) {
groups[key] = [];
}
groups[key].push(memo);
}
return groups;
}
getWeekNumber(date) {
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
const dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil(((d.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
}
};
// src/services/status-service.ts
var import_obsidian5 = require("obsidian");
var StatusService = class {
constructor(statusBarItem) {
this.currentStatus = "idle";
this.syncStartTime = 0;
this.progressCount = 0;
this.totalCount = 0;
this.statusBarItem = statusBarItem;
this.updateStatusBar();
}
updateStatusBar() {
let icon;
let text;
switch (this.currentStatus) {
case "syncing": {
icon = "sync";
const progress = this.totalCount ? ` ${this.progressCount}/${this.totalCount}` : "";
const elapsed = this.syncStartTime ? ` (${Math.round((Date.now() - this.syncStartTime) / 1e3)}s)` : "";
text = `\u540C\u6B65\u4E2D${progress}${elapsed}`;
break;
}
case "error": {
icon = "alert-circle";
text = "\u540C\u6B65\u5931\u8D25";
break;
}
case "success": {
icon = "check-circle";
text = "\u540C\u6B65\u5B8C\u6210";
break;
}
case "warning": {
icon = "alert-triangle";
text = "\u8B66\u544A";
break;
}
default: {
icon = "clock";
text = "\u7B49\u5F85\u540C\u6B65";
}
}
this.statusBarItem.innerHTML = "";
const iconSpan = document.createElement("span");
this.statusBarItem.appendChild(iconSpan);
(0, import_obsidian5.setIcon)(iconSpan, icon);
const textSpan = document.createElement("span");
textSpan.textContent = ` ${text}`;
this.statusBarItem.appendChild(textSpan);
}
startSync(totalItems) {
this.currentStatus = "syncing";
this.syncStartTime = Date.now();
this.progressCount = 0;
this.totalCount = totalItems;
this.updateStatusBar();
new import_obsidian5.Notice("\u5F00\u59CB\u540C\u6B65 Memos");
}
updateProgress(current, message) {
this.progressCount = current;
this.updateStatusBar();
if (message) {
new import_obsidian5.Notice(message);
}
}
setError(error) {
this.currentStatus = "error";
this.updateStatusBar();
new import_obsidian5.Notice(`\u540C\u6B65\u5931\u8D25: ${error}`, 5e3);
console.error("Sync failed:", error);
}
setSuccess(message) {
this.currentStatus = "success";
this.updateStatusBar();
new import_obsidian5.Notice(message);
setTimeout(() => {
this.currentStatus = "idle";
this.updateStatusBar();
}, 5e3);
}
setIdle() {
this.currentStatus = "idle";
this.updateStatusBar();
}
setWarning(message) {
this.currentStatus = "warning";
this.updateStatusBar();
new import_obsidian5.Notice(message, 5e3);
console.warn("Warning:", message);
setTimeout(() => {
this.currentStatus = "idle";
this.updateStatusBar();
}, 5e3);
}
};
// main.ts
var MemosSyncPlugin = class extends import_obsidian6.Plugin {
async onload() {
await this.loadSettings();
const statusBarItem = this.addStatusBarItem();
this.statusService = new StatusService(statusBarItem);
this.initializeServices();
this.addSettingTab(new MemosSyncSettingTab(this.app, this));
this.addRibbonIcon("sync", "Sync Memos", async () => {
await this.syncMemos();
});
if (this.settings.syncFrequency === "auto") {
this.initializeAutoSync();
}
}
initializeServices() {
this.memosService = new MemosService(
this.settings.memosApiUrl,
this.settings.memosAccessToken,
this.settings.syncLimit
);
let aiService = null;
if (this.settings.ai.enabled) {
try {
const modelName = this.settings.ai.modelName === "custom" ? this.settings.ai.customModelName : this.settings.ai.modelName;
const apiKey = this.settings.ai.modelType === "ollama" ? this.settings.ai.ollamaBaseUrl : this.settings.ai.apiKey;
if (this.settings.ai.modelType !== "ollama" && !apiKey) {
aiService = createDummyAIService();
this.statusService.setWarning("AI \u670D\u52A1\u9700\u8981\u914D\u7F6E API \u5BC6\u94A5\uFF0C\u8BF7\u5728\u8BBE\u7F6E\u4E2D\u5B8C\u6210\u914D\u7F6E");
} else {
aiService = createAIService(
this.settings.ai.modelType,
apiKey,
modelName,
this.settings.ai.openaiBaseUrl
);
}
} catch (error) {
console.error("Failed to initialize AI service:", error);
this.statusService.setWarning("AI \u670D\u52A1\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E");
aiService = createDummyAIService();
}
}
this.contentService = new ContentService(
aiService || createDummyAIService(),
this.settings.ai.enabled && aiService !== null,
this.settings.ai.intelligentSummary,
this.settings.ai.autoTags,
this.settings.ai.summaryLanguage,
this.app.vault,
this.settings.syncDirectory
);
this.fileService = new FileService(
this.app.vault,
this.settings.syncDirectory,
this.memosService
);
}
async syncMemos() {
try {
if (!this.settings.memosApiUrl) {
throw new Error("\u672A\u914D\u7F6E Memos API URL");
}
if (!this.settings.memosAccessToken) {
throw new Error("\u672A\u914D\u7F6E\u8BBF\u95EE\u4EE4\u724C");
}
this.statusService.startSync(0);
const memos = await this.memosService.fetchAllMemos();
this.statusService.startSync(memos.length);
let syncCount = 0;
for (const memo of memos) {
const processedContent = await this.contentService.processMemoContent(memo);
const processedMemo = { ...memo, content: processedContent };
await this.fileService.saveMemoToFile(processedMemo);
syncCount++;
this.statusService.updateProgress(syncCount);
}
if (this.settings.ai.enabled && this.settings.ai.weeklyDigest) {
this.statusService.updateProgress(syncCount, "\u6B63\u5728\u751F\u6210\u6BCF\u5468\u603B\u7ED3...");
await this.contentService.generateWeeklyDigest(memos);
}
this.statusService.setSuccess(`\u540C\u6B65\u5B8C\u6210\uFF0C\u5171\u540C\u6B65 ${syncCount} \u6761\u8BB0\u5F55`);
} catch (error) {
console.error("\u540C\u6B65\u5931\u8D25:", error);
this.statusService.setError(error.message);
}
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
this.initializeServices();
}
initializeAutoSync() {
const interval = this.settings.autoSyncInterval * 60 * 1e3;
setInterval(() => this.syncMemos(), interval);
}
};
/*! Bundled license information:
@google/generative-ai/dist/index.mjs:
(**
* @license
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*)
@google/generative-ai/dist/index.mjs:
(**
* @license
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*)
*/