mirror of
https://github.com/langchain-ai/langgraphjs.git
synced 2026-07-21 16:45:24 -04:00
feat: AssistantSearchResponse (#1804)
Co-authored-by: David Duong <david@duong.cz>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@langchain/langgraph-sdk": patch
|
||||
---
|
||||
|
||||
feat(sdk): add `includePagination` property when searching from assistants
|
||||
+53
-15
@@ -4,6 +4,7 @@ import {
|
||||
AssistantSortBy,
|
||||
AssistantSelectField,
|
||||
AssistantVersion,
|
||||
AssistantsSearchResponse,
|
||||
CancelAction,
|
||||
Checkpoint,
|
||||
Config,
|
||||
@@ -616,8 +617,20 @@ export class AssistantsClient extends BaseClient {
|
||||
/**
|
||||
* List assistants.
|
||||
* @param query Query options.
|
||||
* @returns List of assistants.
|
||||
* @returns List of assistants or, when includePagination is true, a mapping with the assistants and next cursor.
|
||||
*/
|
||||
async search(query: {
|
||||
graphId?: string;
|
||||
name?: string;
|
||||
metadata?: Metadata;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
sortBy?: AssistantSortBy;
|
||||
sortOrder?: SortOrder;
|
||||
select?: AssistantSelectField[];
|
||||
includePagination: true;
|
||||
}): Promise<AssistantsSearchResponse>;
|
||||
|
||||
async search(query?: {
|
||||
graphId?: string;
|
||||
name?: string;
|
||||
@@ -627,20 +640,45 @@ export class AssistantsClient extends BaseClient {
|
||||
sortBy?: AssistantSortBy;
|
||||
sortOrder?: SortOrder;
|
||||
select?: AssistantSelectField[];
|
||||
}): Promise<Assistant[]> {
|
||||
return this.fetch<Assistant[]>("/assistants/search", {
|
||||
method: "POST",
|
||||
json: {
|
||||
graph_id: query?.graphId ?? undefined,
|
||||
name: query?.name ?? undefined,
|
||||
metadata: query?.metadata ?? undefined,
|
||||
limit: query?.limit ?? 10,
|
||||
offset: query?.offset ?? 0,
|
||||
sort_by: query?.sortBy ?? undefined,
|
||||
sort_order: query?.sortOrder ?? undefined,
|
||||
select: query?.select ?? undefined,
|
||||
},
|
||||
});
|
||||
includePagination?: false;
|
||||
}): Promise<Assistant[]>;
|
||||
|
||||
async search(query?: {
|
||||
graphId?: string;
|
||||
name?: string;
|
||||
metadata?: Metadata;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
sortBy?: AssistantSortBy;
|
||||
sortOrder?: SortOrder;
|
||||
select?: AssistantSelectField[];
|
||||
includePagination?: boolean;
|
||||
}): Promise<Assistant[] | AssistantsSearchResponse> {
|
||||
const json = {
|
||||
graph_id: query?.graphId ?? undefined,
|
||||
name: query?.name ?? undefined,
|
||||
metadata: query?.metadata ?? undefined,
|
||||
limit: query?.limit ?? 10,
|
||||
offset: query?.offset ?? 0,
|
||||
sort_by: query?.sortBy ?? undefined,
|
||||
sort_order: query?.sortOrder ?? undefined,
|
||||
select: query?.select ?? undefined,
|
||||
};
|
||||
const [assistants, response] = await this.fetch<Assistant[]>(
|
||||
"/assistants/search",
|
||||
{
|
||||
method: "POST",
|
||||
json,
|
||||
withResponse: true,
|
||||
}
|
||||
);
|
||||
|
||||
if (query?.includePagination) {
|
||||
const next = response.headers.get("X-Pagination-Next");
|
||||
return { assistants, next };
|
||||
}
|
||||
|
||||
return assistants;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@ export type {
|
||||
AssistantBase,
|
||||
AssistantGraph,
|
||||
AssistantVersion,
|
||||
AssistantsSearchResponse,
|
||||
Checkpoint,
|
||||
Config,
|
||||
Cron,
|
||||
|
||||
@@ -134,6 +134,13 @@ export interface Assistant extends AssistantBase {
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AssistantsSearchResponse {
|
||||
/** The assistants returned for the current search page. */
|
||||
assistants: Assistant[];
|
||||
/** Pagination cursor from the X-Pagination-Next response header. */
|
||||
next: string | null;
|
||||
}
|
||||
|
||||
export interface AssistantGraph {
|
||||
nodes: Array<{
|
||||
id: string | number;
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
||||
import { Client } from "../client.js";
|
||||
import { overrideFetchImplementation } from "../singletons/fetch.js";
|
||||
|
||||
function assistantPayload() {
|
||||
return {
|
||||
assistant_id: "asst_123",
|
||||
graph_id: "graph_123",
|
||||
config: { configurable: { foo: "bar" } },
|
||||
context: { foo: "bar" },
|
||||
created_at: "2024-01-01T00:00:00Z",
|
||||
metadata: { env: "test" },
|
||||
version: 1,
|
||||
name: "My Assistant",
|
||||
description: "Example",
|
||||
updated_at: "2024-01-02T00:00:00Z",
|
||||
};
|
||||
}
|
||||
|
||||
describe("assistants.search", () => {
|
||||
let fetchMock: ReturnType<typeof vi.fn>;
|
||||
|
||||
beforeEach(() => {
|
||||
fetchMock = vi.fn();
|
||||
overrideFetchImplementation(fetchMock);
|
||||
(globalThis as any).fetch = fetchMock;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("returns list by default", async () => {
|
||||
const assistant = assistantPayload();
|
||||
|
||||
fetchMock.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: () => Promise.resolve([assistant]),
|
||||
text: () => Promise.resolve(""),
|
||||
headers: new Headers({}),
|
||||
});
|
||||
|
||||
const client = new Client({ apiKey: "test-api-key" });
|
||||
const result = await client.assistants.search({ limit: 3 });
|
||||
|
||||
expect(result).toEqual([assistant]);
|
||||
});
|
||||
|
||||
it("can include pagination metadata", async () => {
|
||||
const assistant = assistantPayload();
|
||||
|
||||
fetchMock.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: () => Promise.resolve([assistant]),
|
||||
text: () => Promise.resolve(""),
|
||||
headers: new Headers({ "X-Pagination-Next": "42" }),
|
||||
});
|
||||
|
||||
const client = new Client({ apiKey: "test-api-key" });
|
||||
const result = await client.assistants.search({ includePagination: true });
|
||||
|
||||
expect(result).toEqual({ assistants: [assistant], next: "42" });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user