-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add inference for RunnableMap RunOutput type (#3517)
* add RunnableMapLike to infer RunnableMap output * remove unneeded changes * fix linting * format * fix runnable_stream_log.test * upgrade typescript version * clean types * fix structured_output_runnables.int.test * ts version ~5.1.6 * remove unused eslint-disable-next-line * remove another disable no-explicit-any * remove another no-explicit-any * move eslint * Format * Default runnable maps to any type in case inference is not possible * Add tests --------- Co-authored-by: David Illing <dilling123@gmail.com> Co-authored-by: jacoblee93 <jacoblee93@gmail.com>
- Loading branch information
1 parent
b455950
commit 7b574ff
Showing
4 changed files
with
133 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
langchain-core/src/runnables/tests/runnable_map.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* eslint-disable no-promise-executor-return */ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import { StringOutputParser } from "../../output_parsers/string.js"; | ||
import { | ||
ChatPromptTemplate, | ||
SystemMessagePromptTemplate, | ||
HumanMessagePromptTemplate, | ||
} from "../../prompts/chat.js"; | ||
import { | ||
FakeLLM, | ||
FakeChatModel, | ||
FakeRetriever, | ||
} from "../../utils/testing/index.js"; | ||
import { RunnableSequence, RunnableMap } from "../base.js"; | ||
import { RunnablePassthrough } from "../passthrough.js"; | ||
|
||
test("Create a runnable sequence with a runnable map", async () => { | ||
const promptTemplate = ChatPromptTemplate.fromMessages<{ | ||
documents: string; | ||
question: string; | ||
}>([ | ||
SystemMessagePromptTemplate.fromTemplate(`You are a nice assistant.`), | ||
HumanMessagePromptTemplate.fromTemplate( | ||
`Context:\n{documents}\n\nQuestion:\n{question}` | ||
), | ||
]); | ||
const llm = new FakeChatModel({}); | ||
const inputs = { | ||
question: (input: string) => input, | ||
documents: RunnableSequence.from([ | ||
new FakeRetriever(), | ||
(docs: Document[]) => JSON.stringify(docs), | ||
]), | ||
extraField: new FakeLLM({}), | ||
}; | ||
const runnable = new RunnableMap({ steps: inputs }) | ||
.pipe(promptTemplate) | ||
.pipe(llm); | ||
const result = await runnable.invoke("Do you know the Muffin Man?"); | ||
console.log(result); | ||
expect(result.content).toEqual( | ||
`You are a nice assistant.\nContext:\n[{"pageContent":"foo","metadata":{}},{"pageContent":"bar","metadata":{}}]\n\nQuestion:\nDo you know the Muffin Man?` | ||
); | ||
}); | ||
|
||
test("Test map inference in a sequence", async () => { | ||
const prompt = ChatPromptTemplate.fromTemplate( | ||
"context: {context}, question: {question}" | ||
); | ||
const chain = RunnableSequence.from([ | ||
{ | ||
question: new RunnablePassthrough(), | ||
context: async () => "SOME STUFF", | ||
}, | ||
prompt, | ||
new FakeLLM({}), | ||
new StringOutputParser(), | ||
]); | ||
const response = await chain.invoke("Just passing through."); | ||
console.log(response); | ||
expect(response).toBe( | ||
`Human: context: SOME STUFF, question: Just passing through.` | ||
); | ||
}); | ||
|
||
test("Should not allow mismatched inputs", async () => { | ||
const prompt = ChatPromptTemplate.fromTemplate( | ||
"context: {context}, question: {question}" | ||
); | ||
const badChain = RunnableSequence.from([ | ||
{ | ||
// @ts-expect-error TS compiler should flag mismatched input types | ||
question: new FakeLLM({}), | ||
context: async (input: number) => input, | ||
}, | ||
prompt, | ||
new FakeLLM({}), | ||
new StringOutputParser(), | ||
]); | ||
console.log(badChain); | ||
}); | ||
|
||
test("Should not allow improper inputs into a map in a sequence", async () => { | ||
const prompt = ChatPromptTemplate.fromTemplate( | ||
"context: {context}, question: {question}" | ||
); | ||
const map = RunnableMap.from({ | ||
question: new FakeLLM({}), | ||
context: async (_input: string) => 9, | ||
}); | ||
// @ts-expect-error TS compiler should flag mismatched output types | ||
const runnable = prompt.pipe(map); | ||
console.log(runnable); | ||
}); | ||
|
||
test("Should not allow improper outputs from a map into the next item in a sequence", async () => { | ||
const map = RunnableMap.from({ | ||
question: new FakeLLM({}), | ||
context: async (_input: string) => 9, | ||
}); | ||
// @ts-expect-error TS compiler should flag mismatched output types | ||
const runnable = map.pipe(new FakeLLM({})); | ||
console.log(runnable); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7b574ff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
langchainjs-api-refs – ./docs/api_refs
langchainjs-api-docs.vercel.app
langchainjs-api-refs-git-main-langchain.vercel.app
api.js.langchain.com
langchainjs-api-refs-langchain.vercel.app