UNPKG

langsmith

Version:

Client library to connect to the LangSmith Observability and Evaluation Platform.

196 lines (195 loc) 7.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConflictingEndpointsError = exports.LangSmithNotFoundError = exports.LangSmithConflictError = void 0; exports.getInvalidPromptIdentifierMsg = getInvalidPromptIdentifierMsg; exports.printErrorStackTrace = printErrorStackTrace; exports.isLangSmithNotFoundError = isLangSmithNotFoundError; exports.raiseForStatus = raiseForStatus; exports.isConflictingEndpointsError = isConflictingEndpointsError; /** * Get the error message for an invalid prompt identifier. * Used consistently across the codebase when parsing prompt identifiers fails. * * @param identifier - The invalid identifier that was provided * @returns A formatted error message explaining the valid formats */ function getInvalidPromptIdentifierMsg(identifier) { return (`Invalid prompt identifier format: "${identifier}". ` + `Expected one of:\n` + ` - "prompt-name" (for private prompts)\n` + ` - "owner/prompt-name" (for prompts with explicit owner)\n` + ` - "prompt-name:commit-hash" (with commit reference)\n` + ` - "owner/prompt-name:commit-hash" (with owner and commit)`); } function getErrorStackTrace(e) { if (typeof e !== "object" || e == null) return undefined; if (!("stack" in e) || typeof e.stack !== "string") return undefined; let stack = e.stack; const prevLine = `${e}`; if (stack.startsWith(prevLine)) { stack = stack.slice(prevLine.length); } if (stack.startsWith("\n")) { stack = stack.slice(1); } return stack; } function printErrorStackTrace(e) { const stack = getErrorStackTrace(e); if (stack == null) return; console.error(stack); } /** * LangSmithConflictError * * Represents an error that occurs when there's a conflict during an operation, * typically corresponding to HTTP 409 status code responses. * * This error is thrown when an attempt to create or modify a resource conflicts * with the current state of the resource on the server. Common scenarios include: * - Attempting to create a resource that already exists * - Trying to update a resource that has been modified by another process * - Violating a uniqueness constraint in the data * * @extends Error * * @example * try { * await createProject("existingProject"); * } catch (error) { * if (error instanceof ConflictError) { * console.log("A conflict occurred:", error.message); * // Handle the conflict, e.g., by suggesting a different project name * } else { * // Handle other types of errors * } * } * * @property {string} name - Always set to 'ConflictError' for easy identification * @property {string} message - Detailed error message including server response * * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409 */ class LangSmithConflictError extends Error { constructor(message) { super(message); Object.defineProperty(this, "status", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.name = "LangSmithConflictError"; this.status = 409; } } exports.LangSmithConflictError = LangSmithConflictError; /** * LangSmithNotFoundError * * Represents an error that occurs when a requested resource is not found, * typically corresponding to HTTP 404 status code responses. * * @extends Error */ class LangSmithNotFoundError extends Error { constructor(message) { super(message); Object.defineProperty(this, "status", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.name = "LangSmithNotFoundError"; this.status = 404; } } exports.LangSmithNotFoundError = LangSmithNotFoundError; function isLangSmithNotFoundError(error) { return (error != null && typeof error === "object" && "name" in error && error?.name === "LangSmithNotFoundError"); } /** * Throws an appropriate error based on the response status and body. * * @param response - The fetch Response object * @param context - Additional context to include in the error message (e.g., operation being performed) * @throws {LangSmithConflictError} When the response status is 409 * @throws {Error} For all other non-ok responses */ async function raiseForStatus(response, context, consumeOnSuccess) { let errorBody; if (response.ok) { // consume the response body to release the connection // https://undici.nodejs.org/#/?id=garbage-collection if (consumeOnSuccess) { errorBody = await response.text(); } return; } if (response.status === 403) { try { const errorData = await response.json(); const errorCode = errorData?.error; if (errorCode === "org_scoped_key_requires_workspace") { errorBody = "This API key is org-scoped and requires workspace specification. " + "Please provide 'workspaceId' parameter, " + "or set LANGSMITH_WORKSPACE_ID environment variable."; } // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e) { const errorWithStatus = new Error(`${response.status} ${response.statusText}`); // eslint-disable-next-line @typescript-eslint/no-explicit-any errorWithStatus.status = response?.status; throw errorWithStatus; } } if (errorBody === undefined) { try { errorBody = await response.text(); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (e) { errorBody = ""; } } const fullMessage = `Failed to ${context}. Received status [${response.status}]: ${response.statusText}. Message: ${errorBody}`; if (response.status === 404) { throw new LangSmithNotFoundError(fullMessage); } if (response.status === 409) { throw new LangSmithConflictError(fullMessage); } const err = new Error(fullMessage); // eslint-disable-next-line @typescript-eslint/no-explicit-any err.status = response.status; throw err; } const ERR_CONFLICTING_ENDPOINTS = "ERR_CONFLICTING_ENDPOINTS"; class ConflictingEndpointsError extends Error { constructor() { super("You cannot provide both LANGSMITH_ENDPOINT / LANGCHAIN_ENDPOINT " + "and LANGSMITH_RUNS_ENDPOINTS."); Object.defineProperty(this, "code", { enumerable: true, configurable: true, writable: true, value: ERR_CONFLICTING_ENDPOINTS }); this.name = "ConflictingEndpointsError"; // helpful in logs } } exports.ConflictingEndpointsError = ConflictingEndpointsError; function isConflictingEndpointsError(err) { return (typeof err === "object" && err !== null && err.code === ERR_CONFLICTING_ENDPOINTS); }