Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): Make dispatchCustomEvent not throw if used with no callbacks #7513

Merged
merged 1 commit into from
Jan 13, 2025
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
16 changes: 7 additions & 9 deletions langchain-core/src/callbacks/dispatch/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,11 @@ export async function dispatchCustomEvent(
payload: any,
config?: RunnableConfig
) {
const callbackManager = await getCallbackManagerForConfig(config);
const parentRunId = callbackManager?.getParentRunId();
// We want to get the callback manager for the parent run.
// This is a work-around for now to be able to dispatch adhoc events from
// within a tool or a lambda and have the metadata events associated
// with the parent run rather than have a new run id generated for each.
if (callbackManager === undefined || parentRunId === undefined) {
if (config === undefined) {
throw new Error(
[
"Unable to dispatch a custom event without a parent run id.",
"This function can only be called from within an existing run (e.g.,",
`"dispatchCustomEvent" can only be called from within an existing run (e.g.,`,
"inside a tool or a RunnableLambda).",
`\n\nIf you continue to see this error, please import from "@langchain/core/callbacks/dispatch/web"`,
"and explicitly pass in a config parameter.",
Expand All @@ -60,7 +54,11 @@ export async function dispatchCustomEvent(
].join(" ")
);
}
const callbackManager = await getCallbackManagerForConfig(config);
const parentRunId = callbackManager?.getParentRunId();
// We pass parent id as the current run id here intentionally since events dispatch
// from within things like RunnableLambda
await callbackManager.handleCustomEvent?.(name, payload, parentRunId);
if (callbackManager !== undefined && parentRunId !== undefined) {
await callbackManager.handleCustomEvent?.(name, payload, parentRunId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1950,14 +1950,17 @@ test("Runnable streamEvents method with simple tools", async () => {
]);
});

test("Runnable streamEvents method with a custom event", async () => {
test("Runnable methods with a custom event", async () => {
const lambda = RunnableLambda.from(
async (params: { x: number; y: string }, config) => {
await dispatchCustomEvent("testEvent", { someval: "test" }, config);
await dispatchCustomEvent("testEvent", { someval: "test2" }, config);
return JSON.stringify({ x: params.x, y: params.y });
}
);
// Invoke shouldn't fail
const res = await lambda.invoke({ x: 1, y: "2" });
expect(res).toEqual(JSON.stringify({ x: 1, y: "2" }));
const events = [];
const eventStream = await lambda.streamEvents(
{ x: 1, y: "2" },
Expand Down
Loading