From f785c781ea82b656405cab2070a71e571ca17206 Mon Sep 17 00:00:00 2001 From: CrazyJasonwell Date: Mon, 14 Jul 2025 18:49:14 +0800 Subject: [PATCH] vault backup: 2025-07-14 18:49:14 --- .obsidian/community-plugins.json | 3 +- .obsidian/plugins/memos-ai-sync/data.json | 21 + .obsidian/plugins/memos-ai-sync/main.js | 7449 +++++++++++++++++ .obsidian/plugins/memos-ai-sync/manifest.json | 10 + .obsidian/plugins/memos-ai-sync/styles.css | 1 + .obsidian/plugins/memos-sync/data.json | 2 +- .obsidian/workspace.json | 13 +- 03-学习笔记/Memos.md | 1 + 8 files changed, 7491 insertions(+), 9 deletions(-) create mode 100644 .obsidian/plugins/memos-ai-sync/data.json create mode 100644 .obsidian/plugins/memos-ai-sync/main.js create mode 100644 .obsidian/plugins/memos-ai-sync/manifest.json create mode 100644 .obsidian/plugins/memos-ai-sync/styles.css diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index 68f1b49d..c1dc9440 100644 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -25,6 +25,5 @@ "editing-toolbar", "rss-reader", "obsidian-memos", - "memos-sync", - "periodic-para" + "memos-ai-sync" ] \ No newline at end of file diff --git a/.obsidian/plugins/memos-ai-sync/data.json b/.obsidian/plugins/memos-ai-sync/data.json new file mode 100644 index 00000000..0e23d3fe --- /dev/null +++ b/.obsidian/plugins/memos-ai-sync/data.json @@ -0,0 +1,21 @@ +{ + "memosApiUrl": "http://himan.picp.net:5230/api/v1", + "memosAccessToken": "eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIxIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImV4cCI6MTc1Mjg5NTA2OSwiaWF0IjoxNzUyMjkwMjY5fQ.Z8k5_lHqzPtytWhiho1HqzgCtimFlCxyWkkZXLIjsrA ", + "syncDirectory": "memos", + "syncFrequency": "manual", + "autoSyncInterval": 30, + "syncLimit": 1000, + "ai": { + "enabled": true, + "modelType": "ollama", + "apiKey": "", + "modelName": "gpt-4o", + "customModelName": "", + "openaiBaseUrl": "https://api.openai.com/v1", + "ollamaBaseUrl": "http://192.168.1.108:11434", + "weeklyDigest": true, + "autoTags": true, + "intelligentSummary": true, + "summaryLanguage": "zh" + } +} \ No newline at end of file diff --git a/.obsidian/plugins/memos-ai-sync/main.js b/.obsidian/plugins/memos-ai-sync/main.js new file mode 100644 index 00000000..e6f65020 --- /dev/null +++ b/.obsidian/plugins/memos-ai-sync/main.js @@ -0,0 +1,7449 @@ +/* +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({ + "rowStatus": "NORMAL", + "limit": 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 resourceId = resource.name.split("/").pop() || resource.name; + const resourceUrl = `${this.apiUrl.replace("/api/v1", "")}/file/resources/${resourceId}/${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}` + } + }); + if (response.status !== 200) { + this.logger.error(`\u4E0B\u8F7D\u8D44\u6E90\u5931\u8D25: ${response.status}`); + return null; + } + return response.arrayBuffer; + } 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.resources && memo.resources.length > 0) { + const images = memo.resources.filter((r) => this.isImageFile(r.filename)); + const otherFiles = memo.resources.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.empty(); + (0, import_obsidian5.setIcon)(this.statusBarItem.createSpan(), icon); + this.statusBarItem.createSpan({ text: ` ${text}` }); + } + 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. + *) +*/ + +/* nosourcemap */ \ No newline at end of file diff --git a/.obsidian/plugins/memos-ai-sync/manifest.json b/.obsidian/plugins/memos-ai-sync/manifest.json new file mode 100644 index 00000000..a2ed4b10 --- /dev/null +++ b/.obsidian/plugins/memos-ai-sync/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "memos-ai-sync", + "name": "Memos AI Sync", + "version": "1.0.4", + "minAppVersion": "1.4.0", + "description": "Sync Memos content with AI enhancement", + "author": "leoleelxh", + "authorUrl": "https://github.com/leoleelxh", + "isDesktopOnly": false +} diff --git a/.obsidian/plugins/memos-ai-sync/styles.css b/.obsidian/plugins/memos-ai-sync/styles.css new file mode 100644 index 00000000..80e684e8 --- /dev/null +++ b/.obsidian/plugins/memos-ai-sync/styles.css @@ -0,0 +1 @@ +/* 插件样式 */ \ No newline at end of file diff --git a/.obsidian/plugins/memos-sync/data.json b/.obsidian/plugins/memos-sync/data.json index 527d7610..dbc3dfbf 100644 --- a/.obsidian/plugins/memos-sync/data.json +++ b/.obsidian/plugins/memos-sync/data.json @@ -1,7 +1,7 @@ { "dailyMemosHeader": "Memos", "memosAPIVersion": "v0.24.0", - "memosAPIURL": "http://himan.picp.net:5230", + "memosAPIURL": "http://himan.picp.net:5230/api/v1", "memosAPIToken": "eyJhbGciOiJIUzI1NiIsImtpZCI6InYxIiwidHlwIjoiSldUIn0.eyJuYW1lIjoiIiwiaXNzIjoibWVtb3MiLCJzdWIiOiIxIiwiYXVkIjpbInVzZXIuYWNjZXNzLXRva2VuIl0sImV4cCI6MTc1Mjg5NTA2OSwiaWF0IjoxNzUyMjkwMjY5fQ.Z8k5_lHqzPtytWhiho1HqzgCtimFlCxyWkkZXLIjsrA ", "attachmentFolder": "Attachments" } \ No newline at end of file diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 85cec8ed..d0fbfb9f 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -44,7 +44,7 @@ { "id": "40fe3c4d6bdf609d", "type": "tabs", - "dimension": 67.09486166007905, + "dimension": 67.05276705276705, "children": [ { "id": "472183c37fecefe7", @@ -91,7 +91,7 @@ { "id": "94be401a6e7f4b2e", "type": "tabs", - "dimension": 32.905138339920946, + "dimension": 32.94723294723295, "children": [ { "id": "d6059cc1a4b1cbf5", @@ -294,19 +294,21 @@ "copilot:Open Copilot Chat": false, "DEVONlink-obsidian:DEVONlink": false, "periodic-notes:Open today": false, - "obsidian-memos:Thino": false + "obsidian-memos:Thino": false, + "periodic-para:LifeOS 创建": false, + "memos-ai-sync:Sync Memos": false } }, "active": "87127109fa0ee27e", "lastOpenFiles": [ + "Attachments/6cb2VU3rkihszQLFDerqA2-2_20250712120414.png", + "03-学习笔记/Memos.md", "01-工作日记/2025-07-14.md", "01-工作日记/2025-07-12.md", - "03-学习笔记/Memos.md", "03-学习笔记/微信公众号RSS.md", "03-学习笔记/微信机器人.md", "03-学习笔记/OB插件.md", "01-工作日记/2025-07-11.md", - "Attachments/6cb2VU3rkihszQLFDerqA2-2_20250712120414.png", "README.md", "Attachments/kyhNGvh5iFc9eYXy2YuYWx-FDF8C04E-22D3-4D4C-9ED0-F52A326B9801.jpg", "80-笔记归档/README-归档.md", @@ -335,7 +337,6 @@ "40-Podcast/podnotes", "40-Podcast", "01-工作日记/2025-07-07.md", - "01-工作日记/2025-07-04.md", "screenshot 1.png", "screenshot.png", "工作日记", diff --git a/03-学习笔记/Memos.md b/03-学习笔记/Memos.md index a8c3e940..d1d39768 100644 --- a/03-学习笔记/Memos.md +++ b/03-学习笔记/Memos.md @@ -104,5 +104,6 @@ https://github.com/quanru/obsidian-lifeos#daily-record > [!很不错] > https://www.edony.ink/self-hosting-personal-memos-services/ > https://github.com/edonyzpc/memos +> https://github.com/leoleelxh/obsidian-memos-ai-sync >