import * as uuid from "uuid"; import { getEnvironmentVariable, getRuntimeEnvironment } from "./utils/env.js"; import { Client } from "./client.js"; const warnedMessages = {}; function warnOnce(message) { if (!warnedMessages[message]) { console.warn(message); warnedMessages[message] = true; } } export class RunTree { constructor(config) { Object.defineProperty(this, "id", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "run_type", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "project_name", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "parent_run", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "child_runs", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "execution_order", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "child_execution_order", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "start_time", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "end_time", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "extra", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "error", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "serialized", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "inputs", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "outputs", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "reference_example_id", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "client", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "events", { enumerable: true, configurable: true, writable: true, value: void 0 }); const defaultConfig = RunTree.getDefaultConfig(); Object.assign(this, { ...defaultConfig, ...config }); } static getDefaultConfig() { return { id: uuid.v4(), project_name: getEnvironmentVariable("LANGCHAIN_PROJECT") ?? getEnvironmentVariable("LANGCHAIN_SESSION") ?? // TODO: Deprecate "default", child_runs: [], execution_order: 1, child_execution_order: 1, api_url: getEnvironmentVariable("LANGCHAIN_ENDPOINT") ?? "http://localhost:1984", api_key: getEnvironmentVariable("LANGCHAIN_API_KEY"), caller_options: {}, start_time: Date.now(), serialized: {}, inputs: {}, extra: {}, client: new Client({}), }; } async createChild(config) { const child = new RunTree({ ...config, parent_run: this, project_name: this.project_name, client: this.client, execution_order: this.child_execution_order + 1, child_execution_order: this.child_execution_order + 1, }); this.child_runs.push(child); return child; } async end(outputs, error, endTime = Date.now()) { this.outputs = outputs; this.error = error; this.end_time = endTime; if (this.parent_run) { this.parent_run.child_execution_order = Math.max(this.parent_run.child_execution_order, this.child_execution_order); } } async _convertToCreate(run, excludeChildRuns = true) { const runExtra = run.extra ?? {}; if (!runExtra.runtime) { runExtra.runtime = {}; } const runtimeEnv = await getRuntimeEnvironment(); for (const [k, v] of Object.entries(runtimeEnv)) { if (!runExtra.runtime[k]) { runExtra.runtime[k] = v; } } let child_runs; let parent_run_id; if (!excludeChildRuns) { child_runs = await Promise.all(run.child_runs.map((child_run) => this._convertToCreate(child_run, excludeChildRuns))); parent_run_id = undefined; } else { parent_run_id = run.parent_run?.id; child_runs = []; } const persistedRun = { id: run.id, name: run.name, start_time: run.start_time, end_time: run.end_time, run_type: run.run_type, reference_example_id: run.reference_example_id, extra: runExtra, execution_order: run.execution_order, serialized: run.serialized, error: run.error, inputs: run.inputs, outputs: run.outputs, session_name: run.project_name, child_runs: child_runs, parent_run_id: parent_run_id, }; return persistedRun; } async postRun(excludeChildRuns = true) { const runCreate = await this._convertToCreate(this, true); await this.client.createRun(runCreate); if (!excludeChildRuns) { warnOnce("Posting with excludeChildRuns=false is deprecated and will be removed in a future version."); for (const childRun of this.child_runs) { await childRun.postRun(false); } } } async patchRun() { const runUpdate = { end_time: this.end_time, error: this.error, outputs: this.outputs, parent_run_id: this.parent_run?.id, reference_example_id: this.reference_example_id, extra: this.extra, events: this.events, }; await this.client.updateRun(this.id, runUpdate); } }