Skip to content

Commit bb6311f

Browse files
committed
chore(langchain/v1): patch changes
* #9131 * #9093 * #9081 * #9069 * #9059 * #9057 * #9028 * #8978 * #8974 * #8966 * #8938 * #8932 * #8442 * #8863 * #8887 * #8849 * #8696 * #8850 * #8837 * #8719 * #8695 * #8634
1 parent a94c928 commit bb6311f

File tree

8 files changed

+637
-92
lines changed

8 files changed

+637
-92
lines changed

libs/langchain-classic/src/chains/openai_functions/openapi.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,10 @@ export function convertOpenAPISchemaToJSONSchema(
189189
);
190190
}
191191
if (schema.type === "array") {
192+
const openAPIItems = spec.getSchema(schema.items ?? {});
192193
return {
193194
type: "array",
194-
items: convertOpenAPISchemaToJSONSchema(schema.items ?? {}, spec),
195+
items: convertOpenAPISchemaToJSONSchema(openAPIItems, spec),
195196
minItems: schema.minItems,
196197
maxItems: schema.maxItems,
197198
} as JsonSchema7ArrayType;

libs/langchain-classic/src/chains/openai_functions/tests/openapi.test.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { test, expect } from "vitest";
1+
import { test, expect } from "@jest/globals";
22

33
import { OpenAPIV3, OpenAPIV3_1 } from "openapi-types";
44
import {
@@ -69,6 +69,21 @@ test("Test convert OpenAPI params to JSON Schema", async () => {
6969
},
7070
},
7171
},
72+
{
73+
name: "refParam",
74+
in: "query",
75+
schema: {
76+
$ref: "#/components/schemas/RefObject",
77+
},
78+
},
79+
{
80+
name: "refArrayParam",
81+
in: "query",
82+
schema: {
83+
type: "array",
84+
items: { $ref: "#/components/schemas/RefObject" },
85+
},
86+
},
7287
{
7388
name: "nestedObjectInArrayParam",
7489
in: "query",
@@ -147,6 +162,21 @@ test("Test convert OpenAPI params to JSON Schema", async () => {
147162
},
148163
},
149164
},
165+
components: {
166+
schemas: {
167+
RefObject: {
168+
type: "object",
169+
properties: {
170+
foo: {
171+
type: "string",
172+
},
173+
bar: {
174+
type: "number",
175+
},
176+
},
177+
},
178+
},
179+
},
150180
});
151181

152182
const createWidget = spec.getOperation(
@@ -225,6 +255,26 @@ test("Test convert OpenAPI params to JSON Schema", async () => {
225255
expect(typedStringArrayParamSchema.items).not.toBeUndefined();
226256
expectType("string", typedStringArrayParamSchema.items);
227257

258+
const refParamSchema = convertOpenAPISchemaToJSONSchema(
259+
getParamSchema(createWidget, "refParam"),
260+
spec
261+
);
262+
const typedRefParamSchema = expectType("object", refParamSchema);
263+
expectType("string", typedRefParamSchema.properties.foo);
264+
expectType("number", typedRefParamSchema.properties.bar);
265+
266+
const refArrayParamSchema = convertOpenAPISchemaToJSONSchema(
267+
getParamSchema(createWidget, "refArrayParam"),
268+
spec
269+
);
270+
const typedRefArrayParamSchema = expectType("array", refArrayParamSchema);
271+
const typedRefArrayParamSchemaItems = expectType(
272+
"object",
273+
typedRefArrayParamSchema.items
274+
);
275+
expectType("string", typedRefArrayParamSchemaItems.properties.foo);
276+
expectType("number", typedRefArrayParamSchemaItems.properties.bar);
277+
228278
const nestedObjectInArrayParamSchema = convertOpenAPISchemaToJSONSchema(
229279
getParamSchema(createWidget, "nestedObjectInArrayParam"),
230280
spec

libs/langchain-core/src/callbacks/manager.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,12 +1251,18 @@ export class CallbackManager
12511251
if (tracingV2Enabled) {
12521252
const tracerV2 = new LangChainTracer();
12531253
callbackManager.addHandler(tracerV2, true);
1254-
1255-
// handoff between langchain and langsmith/traceable
1256-
// override the parent run ID
1257-
callbackManager._parentRunId =
1258-
LangChainTracer.getTraceableRunTree()?.id ??
1259-
callbackManager._parentRunId;
1254+
}
1255+
}
1256+
if (tracingV2Enabled) {
1257+
// handoff between langchain and langsmith/traceable
1258+
// override the parent run ID
1259+
const implicitRunTree = LangChainTracer.getTraceableRunTree();
1260+
if (implicitRunTree && callbackManager._parentRunId === undefined) {
1261+
callbackManager._parentRunId = implicitRunTree.id;
1262+
const tracerV2 = callbackManager.handlers.find(
1263+
(handler) => handler.name === "langchain_tracer"
1264+
) as LangChainTracer | undefined;
1265+
tracerV2?.updateFromRunTree(implicitRunTree);
12601266
}
12611267
}
12621268
}

libs/langchain-core/src/tracers/tests/langsmith_interop.int.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { traceable } from "langsmith/traceable";
44
import { RunnableLambda } from "../../runnables/base.js";
55
import { BaseMessage, HumanMessage } from "../../messages/index.js";
66
import { awaitAllCallbacks } from "../../singletons/callbacks.js";
7+
import { LangChainTracer } from "../tracer_langchain.js";
78

89
test("traceables double nested within runnables with batching", async () => {
910
const aiGreet = traceable(
@@ -27,3 +28,67 @@ test("traceables double nested within runnables with batching", async () => {
2728

2829
await awaitAllCallbacks();
2930
});
31+
32+
test("deep nesting with manual tracer passed", async () => {
33+
const aiGreet = traceable(
34+
async (msg: BaseMessage) => {
35+
const child = RunnableLambda.from(async () => {
36+
const grandchild = RunnableLambda.from(async () => {
37+
const greatGrandchild = traceable(
38+
async () => {
39+
const greatGreatGrandchild = RunnableLambda.from(async () => {
40+
return [
41+
new HumanMessage({ content: "From great great grandchild!" }),
42+
];
43+
}).withConfig({ runName: "greatGreatGrandchild" });
44+
return greatGreatGrandchild.invoke({});
45+
},
46+
{ name: "greatGrandchild", tracingEnabled: true }
47+
);
48+
return greatGrandchild({});
49+
}).withConfig({ runName: "grandchild" });
50+
return grandchild.invoke({});
51+
}).withConfig({ runName: "child" });
52+
return child.invoke([msg]);
53+
},
54+
{ name: "aiGreet", tracingEnabled: true }
55+
);
56+
57+
const parent = RunnableLambda.from(async () => {
58+
return aiGreet(new HumanMessage({ content: "Hello!" }));
59+
}).withConfig({ runName: "parent" });
60+
61+
await parent.invoke(
62+
{},
63+
{
64+
callbacks: [new LangChainTracer()],
65+
}
66+
);
67+
68+
await awaitAllCallbacks();
69+
});
70+
71+
test("runnable nested within a traceable with manual tracer passed", async () => {
72+
const child = RunnableLambda.from(async () => {
73+
const grandchild = RunnableLambda.from(async () => {
74+
return [new HumanMessage({ content: "From grandchild!" })];
75+
}).withConfig({ runName: "grandchild" });
76+
return grandchild.invoke({});
77+
}).withConfig({ runName: "child" });
78+
79+
const parent = traceable(
80+
async () => {
81+
return child.invoke(
82+
{},
83+
{
84+
callbacks: [new LangChainTracer()],
85+
}
86+
);
87+
},
88+
{ name: "parent", tracingEnabled: true }
89+
);
90+
91+
await parent();
92+
93+
await awaitAllCallbacks();
94+
});

0 commit comments

Comments
 (0)