@datastax/langflow-client
Version:
A JavaScript client for the Langflow API
200 lines (176 loc) • 4.98 kB
text/typescript
// Copyright DataStax, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { FormData, Headers } from "undici";
import { LangflowClient } from "./index.js";
import { FlowResponse } from "./flow_response.js";
import { UploadResponse } from "./upload_response.js";
import type { FlowInputType, FlowOutputType } from "./consts.js";
import type { LangflowResponse } from "./flow_response.js";
import type { LangflowUploadResponse } from "./upload_response.js";
export class Flow {
client: LangflowClient;
id: string;
tweaks: Tweaks;
constructor(client: LangflowClient, flowId: string, tweaks: Tweaks = {}) {
this.client = client;
this.id = flowId;
this.tweaks = tweaks;
}
tweak(key: string, tweak: Tweak) {
const newTweaks = structuredClone(this.tweaks);
newTweaks[key] = tweak;
return new Flow(this.client, this.id, newTweaks);
}
async run(
input_value: string,
options: Partial<Omit<FlowRequestOptions, "input_value">> = {}
) {
const {
input_type = "chat",
output_type = "chat",
session_id,
signal,
} = options;
const tweaks = { ...this.tweaks, ...options.tweaks };
const body = JSON.stringify({
input_type,
output_type,
input_value,
tweaks,
session_id,
});
const headers = new Headers();
headers.set("Content-Type", "application/json");
headers.set("Accept", "application/json");
const result = (await this.client.request({
path: `/v1/run/${this.id}`,
method: "POST",
body,
headers,
signal,
})) as LangflowResponse;
return new FlowResponse(result);
}
async stream(
input_value: string,
options: Partial<Omit<FlowRequestOptions, "input_value">> = {}
) {
const {
input_type = "chat",
output_type = "chat",
session_id,
signal,
} = options;
const tweaks = { ...this.tweaks, ...options.tweaks };
const body = JSON.stringify({
input_type,
output_type,
input_value,
tweaks,
session_id,
});
const headers = new Headers();
headers.set("Content-Type", "application/json");
headers.set("Accept", "application/json");
const streamingResult = await this.client.stream<StreamEvent>({
path: `/v1/run/${this.id}`,
method: "POST",
body,
headers,
signal,
});
return streamingResult;
}
async uploadFile(file: File | Blob, options: { signal?: AbortSignal } = {}) {
const { signal } = options;
const form = new FormData();
form.append("file", file);
const headers = new Headers();
headers.set("Accept", "application/json");
const response = (await this.client.request({
path: `/v1/files/upload/${this.id}`,
method: "POST",
body: form,
headers,
signal,
})) as LangflowUploadResponse;
return new UploadResponse(response);
}
}
export interface FlowRequestOptions {
input_type: FlowInputType;
output_type: FlowOutputType;
input_value: string;
tweaks?: Tweaks;
session_id?: string;
signal?: AbortSignal;
}
export type Tweak = Record<string, string | number | null | boolean>;
export type Tweaks = Record<string, Tweak | string>;
export type TokenStreamEvent = {
event: "token";
data: TokenStreamEventData;
};
export type TokenStreamEventData = {
chunk: string;
id: string;
timestamp: string;
};
export type AddMessageStreamEvent = {
event: "add_message";
data: MessageStreamEventData;
};
export interface MessageStreamEventData {
timestamp: string;
sender: string;
sender_name: string;
session_id: string;
text: string;
files: unknown[];
error: boolean;
edit: boolean;
properties: MessageStreamEventDataProperties;
category: string;
content_blocks: unknown[];
id: string;
flow_id: string;
duration: unknown;
}
export interface MessageStreamEventDataProperties {
text_color: string;
background_color: string;
edited: boolean;
source: MessageStreamEventDataSource;
icon: string;
allow_markdown: boolean;
positive_feedback: unknown;
state: string;
targets: unknown[];
}
export interface MessageStreamEventDataSource {
id: unknown;
display_name: unknown;
source: unknown;
}
export type EndStreamEvent = {
event: "end";
data: EndStreamEventData;
};
export type EndStreamEventData = {
result: LangflowResponse;
};
export type StreamEvent =
| TokenStreamEvent
| AddMessageStreamEvent
| EndStreamEvent;