Skip to content

Commit

Permalink
langchain[patch]: Allow headers to be passed in remote runnable reque…
Browse files Browse the repository at this point in the history
…sts, docs (langchain-ai#4107)

* Allow headers to be passed in remote runnable requests, docs

* Fix broken link
  • Loading branch information
jacoblee93 authored Jan 21, 2024
1 parent d84cfb3 commit 9ed1b27
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
40 changes: 40 additions & 0 deletions docs/core_docs/docs/ecosystem/langserve.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# LangServe

[LangServe](https://python.langchain.com/docs/langserve) is a Python framework that helps developers deploy LangChain [runnables and chains](/docs/expression_language/)
as REST APIs.

If you have a deployed LangServe route, you can use the [RemoteRunnable](https://api.js.langchain.com/classes/langchain_runnables_remote.RemoteRunnable.html) class to interact
with it as if it were a local chain. This allows you to more easily call hosted LangServe instances from JavaScript environments (like in the browser on the frontend).

You'll need to install or package LangChain into your frontend:

```bash npm2yarn
npm install langchain
```

## Usage

Then, you can use any of the [supported LCEL interface methods](/docs/expression_language/interface).
Here's an example of how this looks:

import CodeBlock from "@theme/CodeBlock";
import Example from "@examples/ecosystem/langsmith.ts";

<CodeBlock language="typescript">{Example}</CodeBlock>

[`streamLog`](/docs/expression_language/interface) is a lower level method for streaming chain intermediate steps as partial JSONPatch chunks.
This method allows for a few extra options as well to only include or exclude certain named steps.

`@langchain/core` also provides an `applyPatch` utility for aggregating these chunks into a full output:

import StreamLogExample from "@examples/ecosystem/langsmith_stream_log.ts";

<CodeBlock language="typescript">{StreamLogExample}</CodeBlock>

### Configuration

You can also pass in options for headers and timeouts into the constructor. These will be used when making incoming requests:

import OptionsExample from "@examples/ecosystem/langsmith_options.ts";

<CodeBlock language="typescript">{OptionsExample}</CodeBlock>
21 changes: 21 additions & 0 deletions examples/src/ecosystem/langsmith.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RemoteRunnable } from "langchain/runnables/remote";

const remoteChain = new RemoteRunnable({
url: "https://your_hostname.com/path",
});

const result = await remoteChain.invoke({
param1: "param1",
param2: "param2",
});

console.log(result);

const stream = await remoteChain.stream({
param1: "param1",
param2: "param2",
});

for await (const chunk of stream) {
console.log(chunk);
}
18 changes: 18 additions & 0 deletions examples/src/ecosystem/langsmith_options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { RemoteRunnable } from "langchain/runnables/remote";

const remoteChain = new RemoteRunnable({
url: "https://your_hostname.com/path",
options: {
timeout: 10000,
headers: {
Authorization: "Bearer YOUR_TOKEN",
},
},
});

const result = await remoteChain.invoke({
param1: "param1",
param2: "param2",
});

console.log(result);
40 changes: 40 additions & 0 deletions examples/src/ecosystem/langsmith_stream_log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { RemoteRunnable } from "langchain/runnables/remote";
import { applyPatch } from "@langchain/core/utils/json_patch";

const remoteChain = new RemoteRunnable({
url: "https://your_hostname.com/path",
});

const logStream = await remoteChain.streamLog(
{
param1: "param1",
param2: "param2",
},
// LangChain runnable config properties
{
configurable: {
llm: "some_property",
},
metadata: {
conversation_id: "other_metadata",
},
},
// Optional additional streamLog properties for filtering outputs
{
includeNames: [],
includeTags: [],
includeTypes: [],
excludeNames: [],
excludeTags: [],
excludeTypes: [],
}
);

let streamedResponse: Record<string, any> = {};

for await (const chunk of logStream) {
console.log(chunk);
streamedResponse = applyPatch(streamedResponse, chunk.ops).newDocument;
}

console.log(streamedResponse);
2 changes: 2 additions & 0 deletions langchain/src/runnables/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { IterableReadableStream } from "@langchain/core/utils/stream";

type RemoteRunnableOptions = {
timeout?: number;
headers?: Record<string, unknown>;
};

function isSuperset(set: Set<string>, subset: Set<string>) {
Expand Down Expand Up @@ -256,6 +257,7 @@ export class RemoteRunnable<
body: JSON.stringify(body),
headers: {
"Content-Type": "application/json",
...this.options?.headers,
},
signal: AbortSignal.timeout(this.options?.timeout ?? 60000),
});
Expand Down

0 comments on commit 9ed1b27

Please sign in to comment.