diff --git a/langchain-core/src/callbacks/dispatch/web.ts b/langchain-core/src/callbacks/dispatch/web.ts index 35a4694e88e6..22bce061a01c 100644 --- a/langchain-core/src/callbacks/dispatch/web.ts +++ b/langchain-core/src/callbacks/dispatch/web.ts @@ -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.", @@ -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); + } } diff --git a/langchain-core/src/runnables/tests/runnable_stream_events_v2.test.ts b/langchain-core/src/runnables/tests/runnable_stream_events_v2.test.ts index e79f4765d20a..10c0e035c955 100644 --- a/langchain-core/src/runnables/tests/runnable_stream_events_v2.test.ts +++ b/langchain-core/src/runnables/tests/runnable_stream_events_v2.test.ts @@ -1950,7 +1950,7 @@ 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); @@ -1958,6 +1958,9 @@ test("Runnable streamEvents method with a custom event", async () => { 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" },