Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions js/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import * as uuid from "uuid";
import type { OTELContext } from "./experimental/otel/types.js";
import {
Expand Down Expand Up @@ -227,6 +227,9 @@
treeFilter?: string;
/**
* The values to include in the response.
*
* Note: The 'child_run_ids' value is deprecated and will be removed in a future version.
* This field is no longer populated by the API.
*/
select?: string[];
}
Expand Down Expand Up @@ -414,7 +417,7 @@
max_start_time: string;
latency_p50: number;
latency_p99: number;
feedback_stats: any | null;

Check warning on line 420 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
group_key: string;
first_inputs: string;
last_outputs: string;
Expand Down Expand Up @@ -587,7 +590,7 @@
// If there is an item on the queue we were unable to pop,
// just return it as a single batch.
if (popped.length === 0 && this.items.length > 0) {
const item = this.items.shift()!;

Check warning on line 593 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Forbidden non-null assertion
popped.push(item);
poppedSizeBytes += item.size;
this.sizeBytes -= item.size;
Expand Down Expand Up @@ -1210,7 +1213,7 @@
if (this._serverInfo === undefined) {
try {
this._serverInfo = await this._getServerInfo();
} catch (e: any) {

Check warning on line 1216 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
console.warn(
`[LANGSMITH]: Failed to fetch info on supported operations. Falling back to batch operations and default limits. Info: ${
e.status ?? "Unspecified status code"
Expand Down Expand Up @@ -1392,7 +1395,7 @@
let batchItem = batchItems.pop();
while (batchItem !== undefined) {
// Type is wrong but this is a deprecated code path anyway
batchChunks[key].push(batchItem as any);

Check warning on line 1398 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
batchItem = batchItems.pop();
}
}
Expand Down Expand Up @@ -2141,6 +2144,12 @@
order,
};

if (body.select.includes("child_run_ids")) {
warnOnce(
"Deprecated: 'child_run_ids' in the listRuns select parameter is deprecated and will be removed in a future version."
);
}

let runsYielded = 0;
for await (const runs of this._getCursorPaginatedList<Run>(
"/runs/query",
Expand Down Expand Up @@ -2268,7 +2277,7 @@
treeFilter?: string;
isRoot?: boolean;
dataSourceType?: string;
}): Promise<any> {

Check warning on line 2280 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
let projectIds_ = projectIds || [];
if (projectNames) {
projectIds_ = [
Expand Down Expand Up @@ -2580,7 +2589,7 @@
`Failed to list shared examples: ${response.status} ${response.statusText}`
);
}
return result.map((example: any) => ({

Check warning on line 2592 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
...example,
_hostUrl: this.getHostUrl(),
}));
Expand Down Expand Up @@ -2709,7 +2718,7 @@
}
// projectId querying
return true;
} catch (e) {

Check warning on line 2721 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

'e' is defined but never used. Allowed unused args must match /^_/u
return false;
}
}
Expand Down Expand Up @@ -4315,7 +4324,7 @@
| EvaluationResult[]
| EvaluationResults,
run?: Run,
sourceInfo?: { [key: string]: any }

Check warning on line 4327 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
): Promise<[results: EvaluationResult[], feedbacks: Feedback[]]> {
const evalResults: Array<EvaluationResult> =
this._selectEvalResults(evaluatorResponse);
Expand Down Expand Up @@ -4357,7 +4366,7 @@
| EvaluationResult[]
| EvaluationResults,
run?: Run,
sourceInfo?: { [key: string]: any }

Check warning on line 4369 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
): Promise<EvaluationResult[]> {
const [results] = await this._logEvaluationFeedback(
evaluatorResponse,
Expand Down Expand Up @@ -4874,7 +4883,7 @@

public async createCommit(
promptIdentifier: string,
object: any,

Check warning on line 4886 in js/src/client.ts

View workflow job for this annotation

GitHub Actions / Check linting

Unexpected any. Specify a different type
options?: {
parentCommitHash?: string;
}
Expand Down
48 changes: 48 additions & 0 deletions js/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,4 +685,52 @@ describe("Client", () => {
});
});
});

describe("listRuns", () => {
it("should warn when child_run_ids is in select parameter", async () => {
const consoleWarnSpy = jest
.spyOn(console, "warn")
.mockImplementation(() => {});

// Create mock fetch function
const mockFetch = jest.fn().mockImplementation(async () => ({
ok: true,
status: 200,
statusText: "OK",
json: async () => ({ runs: [] }),
}));

const client = new Client({
apiKey: "org-scoped-key",
fetchImplementation: mockFetch as any,
});

// Test that warning is issued when child_run_ids is in select
const runs = [];
for await (const run of client.listRuns({
projectId: "00000000-0000-0000-0000-000000000000",
select: ["id", "name", "child_run_ids"],
})) {
runs.push(run);
}

expect(consoleWarnSpy).toHaveBeenCalledWith(
expect.stringMatching(
"Deprecated: 'child_run_ids' in the listRuns select parameter is deprecated and will be removed in a future version."
)
);
consoleWarnSpy.mockClear();

// Test that no warning is issued when child_run_ids is not in select
for await (const run of client.listRuns({
projectId: "00000000-0000-0000-0000-000000000000",
select: ["id", "name"],
})) {
runs.push(run);
}

expect(consoleWarnSpy).not.toHaveBeenCalled();
consoleWarnSpy.mockRestore();
});
});
});
7 changes: 7 additions & 0 deletions python/langsmith/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datetime
import json
import uuid
import warnings
from collections.abc import AsyncGenerator, AsyncIterator, Mapping, Sequence
from typing import (
Any,
Expand Down Expand Up @@ -412,6 +413,12 @@ async def list_runs(
)
project_ids.extend([project.id for project in projects])

if select and "child_run_ids" in select:
warnings.warn(
"The child_run_ids field is deprecated and will be removed in following versions",
DeprecationWarning,
)

body_query: dict[str, Any] = {
"session": project_ids if project_ids else None,
"run_type": run_type,
Expand Down
8 changes: 8 additions & 0 deletions python/langsmith/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2887,7 +2887,15 @@ def list_runs(
"total_tokens",
"trace_id",
]

select = select or default_select

if "child_run_ids" in select:
warnings.warn(
"The child_run_ids field is deprecated and will be removed in following versions",
DeprecationWarning,
)

body_query: dict[str, Any] = {
"session": project_ids if project_ids else None,
"run_type": run_type,
Expand Down
2 changes: 1 addition & 1 deletion python/langsmith/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ class Run(RunBase):
session_id: Optional[UUID] = None
"""The project ID this run belongs to."""
child_run_ids: Optional[list[UUID]] = None
"""The child run IDs of this run."""
"""Deprecated: The child run IDs of this run."""
child_runs: Optional[list[Run]] = None
"""The child runs of this run, if instructed to load using the client
These are not populated by default, as it is a heavier query to make."""
Expand Down
41 changes: 41 additions & 0 deletions python/tests/unit_tests/test_async_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Test the AsyncClient."""

import warnings
from unittest import mock
from uuid import uuid4

import pytest

from langsmith import AsyncClient


@mock.patch("langsmith.async_client.httpx.AsyncClient")
@pytest.mark.asyncio
async def test_list_runs_child_run_ids_deprecation_warning(
mock_client_cls: mock.Mock,
) -> None:
mock_httpx_client = mock.AsyncMock()
mock_client_cls.return_value = mock_httpx_client

# Mock the response for list_runs
mock_response = mock.Mock()
mock_response.json.return_value = {"runs": []}
mock_response.status_code = 200
mock_response.raise_for_status = mock.Mock()
mock_httpx_client.request.return_value = mock_response

client = AsyncClient()

# Test that deprecation warning is raised when child_run_ids is in select
with pytest.warns(DeprecationWarning, match="child_run_ids field is deprecated"):
async for _ in client.list_runs(
project_id=uuid4(),
select=["id", "name", "child_run_ids"],
):
pass

# Test that no warning is raised when child_run_ids is not in select
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
async for _ in client.list_runs(project_id=uuid4(), select=["id", "name"]):
pass
27 changes: 27 additions & 0 deletions python/tests/unit_tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4326,3 +4326,30 @@ def track_processing(runs):
file_obj.close()
except Exception:
pass


@mock.patch("langsmith.client.requests.Session")
def test_list_runs_child_run_ids_deprecation_warning(
mock_session_cls: mock.Mock,
) -> None:
"""Test that using child_run_ids in select parameter raises a deprecation warning."""

mock_session = mock.Mock()
mock_session_cls.return_value = mock_session
mock_session.request.return_value.json.return_value = {"runs": []}

client = Client()

# Test that deprecation warning is raised when child_run_ids is in select
with pytest.warns(DeprecationWarning, match="child_run_ids field is deprecated"):
list(
client.list_runs(
project_id=uuid.uuid4(),
select=["id", "name", "child_run_ids"],
)
)

# Test that no warning is raised when child_run_ids is not in select
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
list(client.list_runs(project_id=uuid.uuid4(), select=["id", "name"]))
Loading