langsmith
Advanced tools
Comparing version 0.0.70-rc.1 to 0.0.70
@@ -16,4 +16,5 @@ import { AsyncCallerParams } from "./utils/async_caller.js"; | ||
interface ListRunsParams { | ||
projectId?: string; | ||
projectName?: string; | ||
projectId?: string | string[]; | ||
projectName?: string | string[]; | ||
traceId?: string; | ||
executionOrder?: number; | ||
@@ -69,8 +70,2 @@ parentRunId?: string; | ||
}; | ||
export declare class Queue<T> { | ||
items: [T, () => void][]; | ||
get size(): number; | ||
push(item: T): Promise<void>; | ||
pop(upToN: number): [T[], () => void]; | ||
} | ||
export declare class Client { | ||
@@ -89,3 +84,3 @@ private apiKey?; | ||
private batchEndpointSupported?; | ||
private autoBatchQueue; | ||
private pendingAutoBatchedRuns; | ||
private pendingAutoBatchedRunLimit; | ||
@@ -115,3 +110,3 @@ private autoBatchTimeout; | ||
private triggerAutoBatchSend; | ||
private processRunOperation; | ||
private appendRunCreateToAutoBatchQueue; | ||
protected batchEndpointIsSupported(): Promise<boolean>; | ||
@@ -137,3 +132,3 @@ createRun(run: CreateRunParams): Promise<void>; | ||
private _loadChildRuns; | ||
listRuns({ projectId, projectName, parentRunId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }: ListRunsParams): AsyncIterable<Run>; | ||
listRuns({ projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }: ListRunsParams): AsyncIterable<Run>; | ||
shareRun(runId: string, { shareId }?: { | ||
@@ -166,2 +161,6 @@ shareId?: string; | ||
}): Promise<TracerSession>; | ||
hasProject({ projectId, projectName, }: { | ||
projectId?: string; | ||
projectName?: string; | ||
}): Promise<boolean>; | ||
readProject({ projectId, projectName, includeStats, }: { | ||
@@ -168,0 +167,0 @@ projectId?: string; |
@@ -75,36 +75,2 @@ import * as uuid from "uuid"; | ||
} | ||
export class Queue { | ||
constructor() { | ||
Object.defineProperty(this, "items", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: [] | ||
}); | ||
} | ||
get size() { | ||
return this.items.length; | ||
} | ||
push(item) { | ||
return new Promise((resolve) => { | ||
this.items.push([item, resolve]); | ||
}); | ||
} | ||
pop(upToN) { | ||
if (upToN < 1) { | ||
throw new Error("Number of items to pop off may not be less than 1."); | ||
} | ||
const popped = []; | ||
while (popped.length < upToN && this.items.length) { | ||
const item = this.items.shift(); | ||
if (item) { | ||
popped.push(item); | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
return [popped.map((it) => it[0]), () => popped.forEach((it) => it[1]())]; | ||
} | ||
} | ||
export class Client { | ||
@@ -184,7 +150,7 @@ constructor(config = {}) { | ||
}); | ||
Object.defineProperty(this, "autoBatchQueue", { | ||
Object.defineProperty(this, "pendingAutoBatchedRuns", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: new Queue() | ||
value: [] | ||
}); | ||
@@ -397,42 +363,41 @@ Object.defineProperty(this, "pendingAutoBatchedRunLimit", { | ||
} | ||
async triggerAutoBatchSend() { | ||
const [batch, done] = this.autoBatchQueue.pop(this.pendingAutoBatchedRunLimit); | ||
if (!batch.length) { | ||
done(); | ||
return; | ||
async triggerAutoBatchSend(runs) { | ||
let batch = runs; | ||
if (batch === undefined) { | ||
batch = this.pendingAutoBatchedRuns.slice(0, this.pendingAutoBatchedRunLimit); | ||
this.pendingAutoBatchedRuns = this.pendingAutoBatchedRuns.slice(this.pendingAutoBatchedRunLimit); | ||
} | ||
try { | ||
await this.batchIngestRuns({ | ||
runCreates: batch | ||
.filter((item) => item.action === "create") | ||
.map((item) => item.item), | ||
runUpdates: batch | ||
.filter((item) => item.action === "update") | ||
.map((item) => item.item), | ||
}); | ||
} | ||
finally { | ||
done(); | ||
} | ||
await this.batchIngestRuns({ | ||
runCreates: batch | ||
.filter((item) => item.action === "create") | ||
.map((item) => item.item), | ||
runUpdates: batch | ||
.filter((item) => item.action === "update") | ||
.map((item) => item.item), | ||
}); | ||
} | ||
async processRunOperation(item, immediatelyTriggerBatch) { | ||
appendRunCreateToAutoBatchQueue(item) { | ||
const oldTimeout = this.autoBatchTimeout; | ||
clearTimeout(this.autoBatchTimeout); | ||
this.autoBatchTimeout = undefined; | ||
const itemPromise = this.autoBatchQueue.push(item); | ||
if (immediatelyTriggerBatch) { | ||
await this.triggerAutoBatchSend(); | ||
this.pendingAutoBatchedRuns.push(item); | ||
while (this.pendingAutoBatchedRuns.length >= this.pendingAutoBatchedRunLimit) { | ||
const batch = this.pendingAutoBatchedRuns.slice(0, this.pendingAutoBatchedRunLimit); | ||
this.pendingAutoBatchedRuns = this.pendingAutoBatchedRuns.slice(this.pendingAutoBatchedRunLimit); | ||
void this.triggerAutoBatchSend(batch); | ||
} | ||
while (this.autoBatchQueue.size >= this.pendingAutoBatchedRunLimit) { | ||
await this.triggerAutoBatchSend(); | ||
if (this.pendingAutoBatchedRuns.length > 0) { | ||
if (!oldTimeout) { | ||
this.autoBatchTimeout = setTimeout(() => { | ||
this.autoBatchTimeout = undefined; | ||
void this.triggerAutoBatchSend(); | ||
}, this.autoBatchInitialDelayMs); | ||
} | ||
else { | ||
this.autoBatchTimeout = setTimeout(() => { | ||
this.autoBatchTimeout = undefined; | ||
void this.triggerAutoBatchSend(); | ||
}, this.autoBatchAggregationDelayMs); | ||
} | ||
} | ||
if (this.autoBatchQueue.size > 0) { | ||
this.autoBatchTimeout = setTimeout(() => { | ||
this.autoBatchTimeout = undefined; | ||
void this.triggerAutoBatchSend(); | ||
}, oldTimeout | ||
? this.autoBatchAggregationDelayMs | ||
: this.autoBatchInitialDelayMs); | ||
} | ||
return itemPromise; | ||
} | ||
@@ -468,3 +433,3 @@ async batchEndpointIsSupported() { | ||
runCreate.dotted_order !== undefined) { | ||
void this.processRunOperation({ | ||
this.appendRunCreateToAutoBatchQueue({ | ||
action: "create", | ||
@@ -571,11 +536,3 @@ item: runCreate, | ||
data.dotted_order !== undefined) { | ||
if (run.end_time !== undefined && data.parent_run_id === undefined) { | ||
// Trigger a batch as soon as a root trace ends and block to ensure trace finishes | ||
// in serverless environments. | ||
await this.processRunOperation({ action: "update", item: data }, true); | ||
return; | ||
} | ||
else { | ||
void this.processRunOperation({ action: "update", item: data }); | ||
} | ||
this.appendRunCreateToAutoBatchQueue({ action: "update", item: data }); | ||
return; | ||
@@ -658,12 +615,16 @@ } | ||
} | ||
async *listRuns({ projectId, projectName, parentRunId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }) { | ||
let projectId_ = projectId; | ||
async *listRuns({ projectId, projectName, parentRunId, traceId, referenceExampleId, startTime, executionOrder, runType, error, id, query, filter, limit, }) { | ||
let projectIds = []; | ||
if (projectId) { | ||
projectIds = Array.isArray(projectId) ? projectId : [projectId]; | ||
} | ||
if (projectName) { | ||
if (projectId) { | ||
throw new Error("Only one of projectId or projectName may be given"); | ||
} | ||
projectId_ = (await this.readProject({ projectName })).id; | ||
const projectNames = Array.isArray(projectName) | ||
? projectName | ||
: [projectName]; | ||
const projectIds_ = await Promise.all(projectNames.map((name) => this.readProject({ projectName: name }).then((project) => project.id))); | ||
projectIds.push(...projectIds_); | ||
} | ||
const body = { | ||
session: projectId_ ? [projectId_] : null, | ||
session: projectIds.length ? projectIds : null, | ||
run_type: runType, | ||
@@ -679,2 +640,3 @@ reference_example: referenceExampleId, | ||
limit, | ||
trace: traceId, | ||
}; | ||
@@ -853,2 +815,42 @@ for await (const runs of this._getCursorPaginatedList("/runs/query", body)) { | ||
} | ||
async hasProject({ projectId, projectName, }) { | ||
// TODO: Add a head request | ||
let path = "/sessions"; | ||
const params = new URLSearchParams(); | ||
if (projectId !== undefined && projectName !== undefined) { | ||
throw new Error("Must provide either projectName or projectId, not both"); | ||
} | ||
else if (projectId !== undefined) { | ||
assertUuid(projectId); | ||
path += `/${projectId}`; | ||
} | ||
else if (projectName !== undefined) { | ||
params.append("name", projectName); | ||
} | ||
else { | ||
throw new Error("Must provide projectName or projectId"); | ||
} | ||
const response = await this.caller.call(fetch, `${this.apiUrl}${path}?${params}`, { | ||
method: "GET", | ||
headers: this.headers, | ||
signal: AbortSignal.timeout(this.timeout_ms), | ||
}); | ||
// consume the response body to release the connection | ||
// https://undici.nodejs.org/#/?id=garbage-collection | ||
try { | ||
const result = await response.json(); | ||
if (!response.ok) { | ||
return false; | ||
} | ||
// If it's OK and we're querying by name, need to check the list is not empty | ||
if (Array.isArray(result)) { | ||
return result.length > 0; | ||
} | ||
// projectId querying | ||
return true; | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
} | ||
async readProject({ projectId, projectName, includeStats, }) { | ||
@@ -855,0 +857,0 @@ let path = "/sessions"; |
export { Client } from "./client.js"; | ||
export { Dataset, Example, TracerSession, Run, Feedback } from "./schemas.js"; | ||
export { RunTree, RunTreeConfig } from "./run_trees.js"; | ||
export declare const __version__ = "0.0.69"; | ||
export declare const __version__ = "0.0.70"; |
export { Client } from "./client.js"; | ||
export { RunTree } from "./run_trees.js"; | ||
// Update using yarn bump-version | ||
export const __version__ = "0.0.69"; | ||
export const __version__ = "0.0.70"; |
@@ -86,6 +86,6 @@ import pRetry from "p-retry"; | ||
}, | ||
// If needed we can change some of the defaults here, | ||
// but they're quite sensible. | ||
retries: this.maxRetries, | ||
randomize: true, | ||
// If needed we can change some of the defaults here, | ||
// but they're quite sensible. | ||
}), { throwOnTimeout: true }); | ||
@@ -92,0 +92,0 @@ } |
{ | ||
"name": "langsmith", | ||
"version": "0.0.70-rc.1", | ||
"version": "0.0.70", | ||
"description": "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.", | ||
@@ -34,2 +34,3 @@ "packageManager": "yarn@1.22.19", | ||
"check-version": "node scripts/check-version.js", | ||
"check-npm-version": "node scripts/check-npm-version.js", | ||
"clean": "rm -rf dist/ && node scripts/create-entrypoints.js clean", | ||
@@ -66,2 +67,3 @@ "build:esm": "tsc --outDir dist/ && rm -rf dist/tests dist/**/tests", | ||
"@jest/globals": "^29.5.0", | ||
"@langchain/core": "^0.1.28", | ||
"@tsconfig/recommended": "^1.0.2", | ||
@@ -80,3 +82,2 @@ "@types/jest": "^29.5.1", | ||
"jest": "^29.5.0", | ||
"langchain": "^0.0.147", | ||
"prettier": "^2.8.8", | ||
@@ -83,0 +84,0 @@ "ts-jest": "^29.1.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
225723
5578
64