@eggjs/langchain-plugin 0.0.0 → 4.0.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js +10 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js +7 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateParam.js +9 -0
  5. package/dist/app.d.ts +12 -0
  6. package/dist/app.js +42 -0
  7. package/dist/index.d.ts +11 -0
  8. package/dist/index.js +12 -0
  9. package/dist/lib/ChatModelHelper.d.ts +9 -0
  10. package/dist/lib/ChatModelHelper.js +14 -0
  11. package/dist/lib/ChatOpenAI.d.ts +11 -0
  12. package/dist/lib/ChatOpenAI.js +47 -0
  13. package/dist/lib/boundModel/BoundModelObjectHook.d.ts +9 -0
  14. package/dist/lib/boundModel/BoundModelObjectHook.js +76 -0
  15. package/dist/lib/config/QualifierUtil.d.ts +8 -0
  16. package/dist/lib/config/QualifierUtil.js +14 -0
  17. package/dist/lib/graph/CompiledStateGraphObject.d.ts +34 -0
  18. package/dist/lib/graph/CompiledStateGraphObject.js +109 -0
  19. package/dist/lib/graph/CompiledStateGraphProto.d.ts +26 -0
  20. package/dist/lib/graph/CompiledStateGraphProto.js +39 -0
  21. package/dist/lib/graph/GraphBuildHook.d.ts +6 -0
  22. package/dist/lib/graph/GraphBuildHook.js +13 -0
  23. package/dist/lib/graph/GraphLoadUnitHook.d.ts +18 -0
  24. package/dist/lib/graph/GraphLoadUnitHook.js +92 -0
  25. package/dist/lib/graph/GraphObjectHook.d.ts +9 -0
  26. package/dist/lib/graph/GraphObjectHook.js +95 -0
  27. package/dist/lib/graph/GraphPrototypeHook.d.ts +24 -0
  28. package/dist/lib/graph/GraphPrototypeHook.js +175 -0
  29. package/dist/lib/tracing/LangGraphTracer.d.ts +12 -0
  30. package/dist/lib/tracing/LangGraphTracer.js +22 -0
  31. package/dist/lib/util.d.ts +8 -0
  32. package/dist/lib/util.js +19 -0
  33. package/package.json +78 -10
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ //#region \0@oxc-project+runtime@0.103.0/helpers/decorate.js
2
+ function __decorate(decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ }
8
+
9
+ //#endregion
10
+ export { __decorate };
@@ -0,0 +1,7 @@
1
+ //#region \0@oxc-project+runtime@0.103.0/helpers/decorateMetadata.js
2
+ function __decorateMetadata(k, v) {
3
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
4
+ }
5
+
6
+ //#endregion
7
+ export { __decorateMetadata };
@@ -0,0 +1,9 @@
1
+ //#region \0@oxc-project+runtime@0.103.0/helpers/decorateParam.js
2
+ function __decorateParam(paramIndex, decorator) {
3
+ return function(target, key) {
4
+ decorator(target, key, paramIndex);
5
+ };
6
+ }
7
+
8
+ //#endregion
9
+ export { __decorateParam };
package/dist/app.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { Application, IBoot } from "egg";
2
+
3
+ //#region src/app.d.ts
4
+ declare class ModuleLangChainHook implements IBoot {
5
+ #private;
6
+ constructor(app: Application);
7
+ configWillLoad(): void;
8
+ configDidLoad(): void;
9
+ beforeClose(): Promise<void>;
10
+ }
11
+ //#endregion
12
+ export { ModuleLangChainHook as default };
package/dist/app.js ADDED
@@ -0,0 +1,42 @@
1
+ import { BoundModelObjectHook } from "./lib/boundModel/BoundModelObjectHook.js";
2
+ import { CompiledStateGraphProto } from "./lib/graph/CompiledStateGraphProto.js";
3
+ import { CompiledStateGraphObject } from "./lib/graph/CompiledStateGraphObject.js";
4
+ import { GraphBuildHook } from "./lib/graph/GraphBuildHook.js";
5
+ import { GraphLoadUnitHook } from "./lib/graph/GraphLoadUnitHook.js";
6
+ import { GraphObjectHook } from "./lib/graph/GraphObjectHook.js";
7
+ import { GraphPrototypeHook } from "./lib/graph/GraphPrototypeHook.js";
8
+
9
+ //#region src/app.ts
10
+ var ModuleLangChainHook = class {
11
+ #app;
12
+ #graphObjectHook;
13
+ #graphLoadUnitHook;
14
+ #boundModelObjectHook;
15
+ #graphPrototypeHook;
16
+ constructor(app) {
17
+ this.#app = app;
18
+ this.#graphObjectHook = new GraphObjectHook();
19
+ this.#graphLoadUnitHook = new GraphLoadUnitHook(this.#app.eggPrototypeFactory);
20
+ this.#boundModelObjectHook = new BoundModelObjectHook();
21
+ this.#graphPrototypeHook = new GraphPrototypeHook();
22
+ this.#app.loadUnitLifecycleUtil.registerLifecycle(this.#graphLoadUnitHook);
23
+ }
24
+ configWillLoad() {
25
+ this.#app.eggObjectLifecycleUtil.registerLifecycle(this.#graphObjectHook);
26
+ this.#app.eggObjectLifecycleUtil.registerLifecycle(this.#boundModelObjectHook);
27
+ this.#app.eggObjectFactory.registerEggObjectCreateMethod(CompiledStateGraphProto, CompiledStateGraphObject.createObject);
28
+ this.#app.eggPrototypeLifecycleUtil.registerLifecycle(this.#graphPrototypeHook);
29
+ }
30
+ configDidLoad() {
31
+ this.#app.moduleHandler.registerGlobalGraphBuildHook(GraphBuildHook);
32
+ }
33
+ async beforeClose() {
34
+ this.#app.eggObjectLifecycleUtil.deleteLifecycle(this.#graphObjectHook);
35
+ this.#app.eggObjectLifecycleUtil.deleteLifecycle(this.#boundModelObjectHook);
36
+ this.#app.loadUnitLifecycleUtil.deleteLifecycle(this.#graphLoadUnitHook);
37
+ this.#app.eggPrototypeLifecycleUtil.deleteLifecycle(this.#graphPrototypeHook);
38
+ }
39
+ };
40
+
41
+ //#endregion
42
+ export { ModuleLangChainHook as default };
@@ -0,0 +1,11 @@
1
+ import { ChatOpenAIModel } from "./lib/ChatOpenAI.js";
2
+ import { BoundModelObjectHook } from "./lib/boundModel/BoundModelObjectHook.js";
3
+ import { QualifierUtil } from "./lib/config/QualifierUtil.js";
4
+ import { CompiledStateGraphProto } from "./lib/graph/CompiledStateGraphProto.js";
5
+ import { CompiledStateGraphObject } from "./lib/graph/CompiledStateGraphObject.js";
6
+ import { GraphBuildHook } from "./lib/graph/GraphBuildHook.js";
7
+ import { GraphLoadUnitHook } from "./lib/graph/GraphLoadUnitHook.js";
8
+ import { GraphObjectHook } from "./lib/graph/GraphObjectHook.js";
9
+ import { GraphPrototypeHook } from "./lib/graph/GraphPrototypeHook.js";
10
+ import { LangGraphTracer } from "./lib/tracing/LangGraphTracer.js";
11
+ export { BoundModelObjectHook, ChatOpenAIModel, CompiledStateGraphObject, CompiledStateGraphProto, GraphBuildHook, GraphLoadUnitHook, GraphObjectHook, GraphPrototypeHook, LangGraphTracer, QualifierUtil };
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { BoundModelObjectHook } from "./lib/boundModel/BoundModelObjectHook.js";
2
+ import { LangGraphTracer } from "./lib/tracing/LangGraphTracer.js";
3
+ import { CompiledStateGraphProto } from "./lib/graph/CompiledStateGraphProto.js";
4
+ import { CompiledStateGraphObject } from "./lib/graph/CompiledStateGraphObject.js";
5
+ import { GraphBuildHook } from "./lib/graph/GraphBuildHook.js";
6
+ import { GraphLoadUnitHook } from "./lib/graph/GraphLoadUnitHook.js";
7
+ import { GraphObjectHook } from "./lib/graph/GraphObjectHook.js";
8
+ import { GraphPrototypeHook } from "./lib/graph/GraphPrototypeHook.js";
9
+ import { QualifierUtil } from "./lib/config/QualifierUtil.js";
10
+ import { ChatOpenAIModel } from "./lib/ChatOpenAI.js";
11
+
12
+ export { BoundModelObjectHook, ChatOpenAIModel, CompiledStateGraphObject, CompiledStateGraphProto, GraphBuildHook, GraphLoadUnitHook, GraphObjectHook, GraphPrototypeHook, LangGraphTracer, QualifierUtil };
@@ -0,0 +1,9 @@
1
+ //#region src/lib/ChatModelHelper.d.ts
2
+ declare class ChatModelHelper {
3
+ static getChatModelQualifier(clientName: string): Record<string, Array<{
4
+ attribute: symbol;
5
+ value: string;
6
+ }>>;
7
+ }
8
+ //#endregion
9
+ export { ChatModelHelper };
@@ -0,0 +1,14 @@
1
+ import { ChatModelInjectName, ChatModelQualifierAttribute } from "@eggjs/langchain-decorator";
2
+
3
+ //#region src/lib/ChatModelHelper.ts
4
+ var ChatModelHelper = class {
5
+ static getChatModelQualifier(clientName) {
6
+ return { [ChatModelInjectName]: [{
7
+ attribute: ChatModelQualifierAttribute,
8
+ value: clientName
9
+ }] };
10
+ }
11
+ };
12
+
13
+ //#endregion
14
+ export { ChatModelHelper };
@@ -0,0 +1,11 @@
1
+ import { ObjectInfo } from "@eggjs/tegg";
2
+ import { ModuleConfig as ModuleConfig$1 } from "@eggjs/tegg-common-util";
3
+ import { ChatOpenAI } from "@langchain/openai";
4
+
5
+ //#region src/lib/ChatOpenAI.d.ts
6
+ declare class ChatOpenAIModel extends ChatOpenAI {
7
+ readonly moduleConfig: ModuleConfig$1;
8
+ constructor(moduleConfig: ModuleConfig$1, objInfo: ObjectInfo);
9
+ }
10
+ //#endregion
11
+ export { ChatOpenAIModel };
@@ -0,0 +1,47 @@
1
+ import { __decorateMetadata } from "../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js";
2
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js";
3
+ import { ChatModelHelper } from "./ChatModelHelper.js";
4
+ import { QualifierUtil } from "./config/QualifierUtil.js";
5
+ import { getChatModelConfig, getClientNames } from "./util.js";
6
+ import { __decorateParam } from "../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateParam.js";
7
+ import { ChatModelInjectName, ChatModelQualifierAttribute } from "@eggjs/langchain-decorator";
8
+ import { AccessLevel, Inject, MultiInstanceInfo, MultiInstanceProto, ObjectInitType } from "@eggjs/tegg";
9
+ import { ModuleConfigUtil } from "@eggjs/tegg-common-util";
10
+ import { ChatOpenAI } from "@langchain/openai";
11
+ import { Agent, FetchFactory, fetch } from "urllib";
12
+
13
+ //#region src/lib/ChatOpenAI.ts
14
+ let ChatOpenAIModel = class ChatOpenAIModel$1 extends ChatOpenAI {
15
+ constructor(moduleConfig, objInfo) {
16
+ const chatConfig = getChatModelConfig(moduleConfig, objInfo);
17
+ chatConfig.configuration = chatConfig.configuration || {};
18
+ FetchFactory.setDispatcher(new Agent({ allowH2: true }));
19
+ chatConfig.configuration.fetch = fetch;
20
+ super(chatConfig);
21
+ }
22
+ };
23
+ ChatOpenAIModel = __decorate([
24
+ MultiInstanceProto({
25
+ accessLevel: AccessLevel.PUBLIC,
26
+ initType: ObjectInitType.SINGLETON,
27
+ getObjects(ctx) {
28
+ const config = ModuleConfigUtil.loadModuleConfigSync(ctx.unitPath);
29
+ const moduleName = ModuleConfigUtil.readModuleNameSync(ctx.unitPath);
30
+ return getClientNames(config, "ChatModel").filter((name) => {
31
+ return config.ChatModel.clients[name].type === "openai";
32
+ }).map((name) => {
33
+ return {
34
+ name: ChatModelInjectName,
35
+ qualifiers: ChatModelHelper.getChatModelQualifier(name)[ChatModelInjectName],
36
+ properQualifiers: { ...QualifierUtil.getModuleConfigQualifier(moduleName) }
37
+ };
38
+ });
39
+ }
40
+ }),
41
+ __decorateParam(0, Inject()),
42
+ __decorateParam(1, MultiInstanceInfo([ChatModelQualifierAttribute])),
43
+ __decorateMetadata("design:paramtypes", [Object, Object])
44
+ ], ChatOpenAIModel);
45
+
46
+ //#endregion
47
+ export { ChatOpenAIModel };
@@ -0,0 +1,9 @@
1
+ import { LifecycleHook } from "@eggjs/tegg";
2
+ import { EggObject, EggObjectLifeCycleContext } from "@eggjs/tegg-runtime";
3
+
4
+ //#region src/lib/boundModel/BoundModelObjectHook.d.ts
5
+ declare class BoundModelObjectHook implements LifecycleHook<EggObjectLifeCycleContext, EggObject> {
6
+ postCreate(_: EggObjectLifeCycleContext, eggObject: EggObject): Promise<void>;
7
+ }
8
+ //#endregion
9
+ export { BoundModelObjectHook };
@@ -0,0 +1,76 @@
1
+ import { BOUND_MODEL_METADATA, ChatModelInjectName, ChatModelQualifierAttribute, GraphToolInfoUtil } from "@eggjs/langchain-decorator";
2
+ import { MCPClientInjectName, MCPClientQualifierAttribute } from "@eggjs/mcp-client";
3
+ import { MCPInfoUtil } from "@eggjs/tegg";
4
+ import { EggContainerFactory } from "@eggjs/tegg-runtime";
5
+ import { loadMcpTools } from "@langchain/mcp-adapters";
6
+ import { DynamicStructuredTool } from "langchain";
7
+ import "langchain/chat_models/universal";
8
+ import * as z from "zod/v4";
9
+
10
+ //#region src/lib/boundModel/BoundModelObjectHook.ts
11
+ var BoundModelHandler = class {
12
+ boundModelMetadata;
13
+ eggObject;
14
+ constructor(nodeMetadata, eggObject) {
15
+ this.boundModelMetadata = nodeMetadata;
16
+ this.eggObject = eggObject;
17
+ }
18
+ async findGraphTools() {
19
+ const tools = this.boundModelMetadata.tools ?? [];
20
+ let dTools = [];
21
+ for (let i = 0; i < tools.length; i++) {
22
+ const toolsObj = await EggContainerFactory.getOrCreateEggObjectFromClazz(tools[i]);
23
+ const toolMetadata = GraphToolInfoUtil.getGraphToolMetadata(toolsObj.proto.clazz);
24
+ const ToolDetail = MCPInfoUtil.getMCPToolArgsIndex(toolsObj.proto.clazz, "execute");
25
+ if (toolMetadata && ToolDetail) {
26
+ const tool = new DynamicStructuredTool({
27
+ description: toolMetadata.description,
28
+ name: toolMetadata.toolName,
29
+ func: toolsObj.obj.execute.bind(toolsObj.obj),
30
+ schema: z.object(ToolDetail.argsSchema)
31
+ });
32
+ dTools = dTools.concat(tool);
33
+ }
34
+ }
35
+ return dTools;
36
+ }
37
+ async findMcpServerTools() {
38
+ const mcpServers = this.boundModelMetadata.mcpServers ?? [];
39
+ let sTools = [];
40
+ for (let i = 0; i < mcpServers.length; i++) {
41
+ const mcpClientObj = await EggContainerFactory.getOrCreateEggObjectFromName(MCPClientInjectName, [{
42
+ attribute: MCPClientQualifierAttribute,
43
+ value: mcpServers[i]
44
+ }]);
45
+ const tool = await loadMcpTools(mcpServers[i], mcpClientObj.obj, {
46
+ throwOnLoadError: true,
47
+ prefixToolNameWithServerName: false,
48
+ additionalToolNamePrefix: ""
49
+ });
50
+ sTools = sTools.concat(tool);
51
+ }
52
+ return sTools;
53
+ }
54
+ async boundTools() {
55
+ const nodeObj = this.eggObject.obj;
56
+ const dTools = await this.findGraphTools();
57
+ const sTools = await this.findMcpServerTools();
58
+ const boundChatModel = (await EggContainerFactory.getOrCreateEggObjectFromName(ChatModelInjectName, [{
59
+ attribute: ChatModelQualifierAttribute,
60
+ value: this.boundModelMetadata.modelName
61
+ }])).obj.bindTools([...dTools, ...sTools]);
62
+ Object.setPrototypeOf(Object.getPrototypeOf(nodeObj), boundChatModel);
63
+ }
64
+ };
65
+ var BoundModelObjectHook = class {
66
+ async postCreate(_, eggObject) {
67
+ const BoundModelMetadata = eggObject.proto.getMetaData(BOUND_MODEL_METADATA);
68
+ if (BoundModelMetadata) {
69
+ await new BoundModelHandler(BoundModelMetadata, eggObject).boundTools();
70
+ return;
71
+ }
72
+ }
73
+ };
74
+
75
+ //#endregion
76
+ export { BoundModelObjectHook };
@@ -0,0 +1,8 @@
1
+ import { QualifierInfo } from "@eggjs/tegg";
2
+
3
+ //#region src/lib/config/QualifierUtil.d.ts
4
+ declare class QualifierUtil {
5
+ static getModuleConfigQualifier(moduleName: string): Record<string, QualifierInfo[]>;
6
+ }
7
+ //#endregion
8
+ export { QualifierUtil };
@@ -0,0 +1,14 @@
1
+ import { ConfigSourceQualifierAttribute } from "@eggjs/tegg";
2
+
3
+ //#region src/lib/config/QualifierUtil.ts
4
+ var QualifierUtil = class {
5
+ static getModuleConfigQualifier(moduleName) {
6
+ return { moduleConfig: [{
7
+ attribute: ConfigSourceQualifierAttribute,
8
+ value: moduleName
9
+ }] };
10
+ }
11
+ };
12
+
13
+ //#endregion
14
+ export { QualifierUtil };
@@ -0,0 +1,34 @@
1
+ import { CompiledStateGraphProto } from "./CompiledStateGraphProto.js";
2
+ import { GraphMetadata } from "@eggjs/langchain-decorator";
3
+ import { EggObjectName, EggPrototypeName, Id } from "@eggjs/tegg";
4
+ import { EggContext, EggObject } from "@eggjs/tegg-runtime";
5
+ import { EggPrototype } from "@eggjs/metadata";
6
+
7
+ //#region src/lib/graph/CompiledStateGraphObject.d.ts
8
+ declare class CompiledStateGraphObject implements EggObject {
9
+ private status;
10
+ id: Id;
11
+ readonly name: EggPrototypeName;
12
+ readonly proto: CompiledStateGraphProto;
13
+ readonly ctx: EggContext;
14
+ readonly daoName: string;
15
+ private _obj;
16
+ readonly graphMetadata: GraphMetadata;
17
+ readonly graphName: string;
18
+ constructor(name: EggObjectName, proto: CompiledStateGraphProto);
19
+ init(): Promise<void>;
20
+ build(): Promise<any>;
21
+ boundNodes(stateGraph: EggObject): Promise<void>;
22
+ boundEdges(stateGraph: EggObject): Promise<void>;
23
+ /**
24
+ * 包装 graph 方法,添加 tracing
25
+ */
26
+ wrapGraphMethod(originalMethod: (input: any, config?: any) => Promise<any>, input: any, config?: any): Promise<any>;
27
+ getTracer(): Promise<any>;
28
+ injectProperty(): never;
29
+ get isReady(): boolean;
30
+ get obj(): object;
31
+ static createObject(name: EggObjectName, proto: EggPrototype): Promise<CompiledStateGraphObject>;
32
+ }
33
+ //#endregion
34
+ export { CompiledStateGraphObject };
@@ -0,0 +1,109 @@
1
+ import { LangGraphTracer } from "../tracing/LangGraphTracer.js";
2
+ import "./CompiledStateGraphProto.js";
3
+ import { ChatCheckpointSaverInjectName, ChatCheckpointSaverQualifierAttribute, GRAPH_EDGE_METADATA, GRAPH_NODE_METADATA, TeggToolNode } from "@eggjs/langchain-decorator";
4
+ import { IdenticalUtil } from "@eggjs/tegg";
5
+ import { ContextHandler, EggContainerFactory, EggObjectStatus } from "@eggjs/tegg-runtime";
6
+ import { EGG_CONTEXT } from "@eggjs/module-common";
7
+ import { BaseCheckpointSaver } from "@langchain/langgraph";
8
+
9
+ //#region src/lib/graph/CompiledStateGraphObject.ts
10
+ var CompiledStateGraphObject = class CompiledStateGraphObject {
11
+ status = EggObjectStatus.PENDING;
12
+ id;
13
+ name;
14
+ proto;
15
+ ctx;
16
+ daoName;
17
+ _obj;
18
+ graphMetadata;
19
+ graphName;
20
+ constructor(name, proto) {
21
+ this.name = name;
22
+ this.proto = proto;
23
+ this.ctx = ContextHandler.getContext();
24
+ this.id = IdenticalUtil.createObjectId(this.proto.id, this.ctx?.id);
25
+ this.graphMetadata = proto.graphMetadata;
26
+ this.graphName = proto.graphName;
27
+ }
28
+ async init() {
29
+ this._obj = await this.build();
30
+ const graph = this._obj;
31
+ const originalStream = graph.stream;
32
+ (await EggContainerFactory.getOrCreateEggObjectFromName("langGraphTracer")).obj.setName(this.graphName);
33
+ graph.stream = (input, config) => this.wrapGraphMethod(originalStream.bind(graph), input, config);
34
+ this.status = EggObjectStatus.READY;
35
+ }
36
+ async build() {
37
+ const stateGraph = await EggContainerFactory.getOrCreateEggObjectFromName(this.graphName);
38
+ await this.boundNodes(stateGraph);
39
+ await this.boundEdges(stateGraph);
40
+ const graphObj = stateGraph.obj;
41
+ const checkpoint = this.graphMetadata.checkpoint;
42
+ let compileGraph;
43
+ if (checkpoint) {
44
+ let checkpointObj;
45
+ if (typeof checkpoint !== "string") checkpointObj = await EggContainerFactory.getOrCreateEggObjectFromClazz(checkpoint);
46
+ else checkpointObj = await EggContainerFactory.getOrCreateEggObjectFromName(ChatCheckpointSaverInjectName, [{
47
+ attribute: ChatCheckpointSaverQualifierAttribute,
48
+ value: checkpoint
49
+ }]);
50
+ compileGraph = graphObj.compile({ checkpointer: checkpointObj.obj });
51
+ } else compileGraph = graphObj.compile();
52
+ return compileGraph;
53
+ }
54
+ async boundNodes(stateGraph) {
55
+ const graphObj = stateGraph.obj;
56
+ const nodes = this.graphMetadata.nodes ?? [];
57
+ for (let i = 0; i < nodes.length; i++) {
58
+ const node = await EggContainerFactory.getOrCreateEggObjectFromClazz(nodes[i]);
59
+ const nodeObj = node.obj;
60
+ const nodeMetadata = node.proto.getMetaData(GRAPH_NODE_METADATA);
61
+ if (nodeMetadata) if (TeggToolNode.prototype.isPrototypeOf(nodeObj)) graphObj.addNode(nodeMetadata.nodeName, nodeObj.toolNode);
62
+ else graphObj.addNode(nodeMetadata.nodeName, nodeObj.execute.bind(nodeObj), nodeObj.options);
63
+ }
64
+ }
65
+ async boundEdges(stateGraph) {
66
+ const graphObj = stateGraph.obj;
67
+ const edges = this.graphMetadata.edges ?? [];
68
+ for (let i = 0; i < edges.length; i++) {
69
+ const edge = await EggContainerFactory.getOrCreateEggObjectFromClazz(edges[i]);
70
+ const edgeObj = edge.obj;
71
+ const edgeMetadata = edge.proto.getMetaData(GRAPH_EDGE_METADATA);
72
+ if (edgeMetadata) if (edgeObj.execute) graphObj.addConditionalEdges(edgeMetadata.fromNodeName, edgeObj.execute.bind(edgeObj), edgeMetadata.toNodeNames);
73
+ else graphObj.addEdge(edgeMetadata.fromNodeName, edgeMetadata.toNodeNames[0]);
74
+ }
75
+ }
76
+ /**
77
+ * 包装 graph 方法,添加 tracing
78
+ */
79
+ async wrapGraphMethod(originalMethod, input, config) {
80
+ const finalConfig = config || {};
81
+ if (finalConfig.tags?.includes("trace-log")) {
82
+ const tracer = (await EggContainerFactory.getOrCreateEggObjectFromClazz(LangGraphTracer)).obj;
83
+ tracer.setName(this.graphName);
84
+ finalConfig.callbacks = [tracer, ...finalConfig.callbacks || []];
85
+ }
86
+ if (!finalConfig.runId) finalConfig.runId = (await this.getTracer())?.traceId;
87
+ return await originalMethod(input, finalConfig);
88
+ }
89
+ async getTracer() {
90
+ return ContextHandler.getContext().get(EGG_CONTEXT).tracer;
91
+ }
92
+ injectProperty() {
93
+ throw new Error("never call GraphObject#injectProperty");
94
+ }
95
+ get isReady() {
96
+ return this.status === EggObjectStatus.READY;
97
+ }
98
+ get obj() {
99
+ return this._obj;
100
+ }
101
+ static async createObject(name, proto) {
102
+ const compiledStateGraphObject = new CompiledStateGraphObject(name, proto);
103
+ await compiledStateGraphObject.init();
104
+ return compiledStateGraphObject;
105
+ }
106
+ };
107
+
108
+ //#endregion
109
+ export { CompiledStateGraphObject };
@@ -0,0 +1,26 @@
1
+ import { GraphMetadata } from "@eggjs/langchain-decorator";
2
+ import { AccessLevel, EggPrototypeName, Id, ObjectInitType, QualifierAttribute, QualifierInfo, QualifierValue } from "@eggjs/tegg";
3
+ import { EggPrototype, LoadUnit } from "@eggjs/metadata";
4
+ import { InjectObjectProto } from "@eggjs/tegg-types";
5
+
6
+ //#region src/lib/graph/CompiledStateGraphProto.d.ts
7
+ declare class CompiledStateGraphProto implements EggPrototype {
8
+ [key: symbol]: PropertyDescriptor;
9
+ private readonly qualifiers;
10
+ readonly accessLevel: AccessLevel;
11
+ id: Id;
12
+ readonly initType: ObjectInitType;
13
+ readonly injectObjects: InjectObjectProto[];
14
+ loadUnitId: string;
15
+ readonly name: EggPrototypeName;
16
+ readonly graphMetadata: GraphMetadata;
17
+ readonly graphName: string;
18
+ constructor(loadUnit: LoadUnit, protoName: string, graphName: string, graphMetadata: GraphMetadata);
19
+ constructEggObject(): object;
20
+ getMetaData<T>(_metadataKey?: any): T | undefined;
21
+ verifyQualifier(qualifier: QualifierInfo): boolean;
22
+ verifyQualifiers(qualifiers: QualifierInfo[]): boolean;
23
+ getQualifier(attribute: QualifierAttribute): QualifierValue | undefined;
24
+ }
25
+ //#endregion
26
+ export { CompiledStateGraphProto };
@@ -0,0 +1,39 @@
1
+ import { AccessLevel, IdenticalUtil, ObjectInitType } from "@eggjs/tegg";
2
+
3
+ //#region src/lib/graph/CompiledStateGraphProto.ts
4
+ var CompiledStateGraphProto = class {
5
+ qualifiers;
6
+ accessLevel = AccessLevel.PUBLIC;
7
+ id;
8
+ initType = ObjectInitType.SINGLETON;
9
+ injectObjects = [];
10
+ loadUnitId;
11
+ name;
12
+ graphMetadata;
13
+ graphName;
14
+ constructor(loadUnit, protoName, graphName, graphMetadata) {
15
+ this.loadUnitId = loadUnit.id;
16
+ this.qualifiers = [];
17
+ this.name = protoName;
18
+ this.graphMetadata = graphMetadata;
19
+ this.graphName = graphName;
20
+ this.id = IdenticalUtil.createProtoId(loadUnit.id, protoName);
21
+ }
22
+ constructEggObject() {
23
+ return {};
24
+ }
25
+ getMetaData(_metadataKey) {}
26
+ verifyQualifier(qualifier) {
27
+ return this.qualifiers.find((t) => t.attribute === qualifier.attribute)?.value === qualifier.value;
28
+ }
29
+ verifyQualifiers(qualifiers) {
30
+ for (const qualifier of qualifiers) if (!this.verifyQualifier(qualifier)) return false;
31
+ return true;
32
+ }
33
+ getQualifier(attribute) {
34
+ return this.qualifiers.find((t) => t.attribute === attribute)?.value;
35
+ }
36
+ };
37
+
38
+ //#endregion
39
+ export { CompiledStateGraphProto };
@@ -0,0 +1,6 @@
1
+ import { GlobalGraph } from "@eggjs/metadata";
2
+
3
+ //#region src/lib/graph/GraphBuildHook.d.ts
4
+ declare function GraphBuildHook(globalGraph: GlobalGraph): void;
5
+ //#endregion
6
+ export { GraphBuildHook };
@@ -0,0 +1,13 @@
1
+ import { LangGraphTracer } from "../tracing/LangGraphTracer.js";
2
+ import { AbstractStateGraph } from "@eggjs/langchain-decorator";
3
+ import { GlobalGraph } from "@eggjs/metadata";
4
+
5
+ //#region src/lib/graph/GraphBuildHook.ts
6
+ function GraphBuildHook(globalGraph) {
7
+ let langchainGraphTracerProtoNode;
8
+ for (const moduleNode of globalGraph.moduleGraph.nodes.values()) for (const protoNode of moduleNode.val.protos) if (protoNode.val.proto?.clazz && (LangGraphTracer.isPrototypeOf(protoNode.val.proto.clazz) || protoNode.val.proto.clazz === LangGraphTracer)) langchainGraphTracerProtoNode = protoNode;
9
+ for (const moduleNode of globalGraph.moduleGraph.nodes.values()) for (const protoNode of moduleNode.val.protos) if (protoNode.val.proto?.clazz && AbstractStateGraph.isPrototypeOf(protoNode.val.proto.clazz)) globalGraph.addInject(moduleNode, protoNode, langchainGraphTracerProtoNode, langchainGraphTracerProtoNode.val.proto.name);
10
+ }
11
+
12
+ //#endregion
13
+ export { GraphBuildHook };
@@ -0,0 +1,18 @@
1
+ import { CompiledStateGraphProto } from "./CompiledStateGraphProto.js";
2
+ import { IGraphMetadata, IGraphToolMetadata } from "@eggjs/langchain-decorator";
3
+ import { EggProtoImplClass, LifecycleHook } from "@eggjs/tegg";
4
+ import { EggPrototypeFactory, LoadUnit, LoadUnitLifecycleContext } from "@eggjs/metadata";
5
+
6
+ //#region src/lib/graph/GraphLoadUnitHook.d.ts
7
+ declare class GraphLoadUnitHook implements LifecycleHook<LoadUnitLifecycleContext, LoadUnit> {
8
+ private readonly eggPrototypeFactory;
9
+ clazzMap: Map<EggProtoImplClass, IGraphMetadata>;
10
+ graphCompiledNameMap: Map<string, CompiledStateGraphProto>;
11
+ tools: Map<EggProtoImplClass, IGraphToolMetadata>;
12
+ constructor(eggPrototypeFactory: EggPrototypeFactory);
13
+ preCreate(ctx: LoadUnitLifecycleContext, loadUnit: LoadUnit): Promise<void>;
14
+ createStructuredTool(clazz: EggProtoImplClass, toolMeta: IGraphToolMetadata): EggProtoImplClass;
15
+ postCreate(_ctx: LoadUnitLifecycleContext, obj: LoadUnit): Promise<void>;
16
+ }
17
+ //#endregion
18
+ export { GraphLoadUnitHook };
@@ -0,0 +1,92 @@
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js";
3
+ import { CompiledStateGraphProto } from "./CompiledStateGraphProto.js";
4
+ import { GraphInfoUtil, GraphToolInfoUtil } from "@eggjs/langchain-decorator";
5
+ import { AccessLevel, LifecyclePostInject, MCPInfoUtil, SingletonProto } from "@eggjs/tegg";
6
+ import { EggContainerFactory } from "@eggjs/tegg-runtime";
7
+ import { DynamicStructuredTool } from "langchain";
8
+ import * as z from "zod/v4";
9
+ import { EggPrototypeCreatorFactory, EggPrototypeFactory, ProtoDescriptorHelper } from "@eggjs/metadata";
10
+ import assert from "node:assert";
11
+
12
+ //#region src/lib/graph/GraphLoadUnitHook.ts
13
+ var GraphLoadUnitHook = class {
14
+ eggPrototypeFactory;
15
+ clazzMap;
16
+ graphCompiledNameMap = /* @__PURE__ */ new Map();
17
+ tools;
18
+ constructor(eggPrototypeFactory) {
19
+ this.eggPrototypeFactory = eggPrototypeFactory;
20
+ this.clazzMap = GraphInfoUtil.getAllGraphMetadata();
21
+ this.tools = GraphToolInfoUtil.getAllGraphToolMetadata();
22
+ }
23
+ async preCreate(ctx, loadUnit) {
24
+ const clazzList = await ctx.loader.load();
25
+ for (const clazz of clazzList) {
26
+ if (this.clazzMap.get(clazz)) {
27
+ const protoName = clazz.name[0].toLowerCase() + clazz.name.substring(1);
28
+ const graphMetadata = GraphInfoUtil.getGraphMetadata(clazz);
29
+ assert(graphMetadata, `${clazz.name} graphMetadata should not be null`);
30
+ const proto = new CompiledStateGraphProto(loadUnit, `compiled${protoName.replace(protoName[0], protoName[0].toUpperCase())}`, protoName, graphMetadata);
31
+ this.eggPrototypeFactory.registerPrototype(proto, loadUnit);
32
+ this.graphCompiledNameMap.set(protoName, proto);
33
+ }
34
+ const toolMeta = this.tools.get(clazz);
35
+ if (toolMeta) {
36
+ const StructuredTool = this.createStructuredTool(clazz, toolMeta);
37
+ const protoDescriptor = ProtoDescriptorHelper.createByInstanceClazz(StructuredTool, {
38
+ moduleName: loadUnit.name,
39
+ unitPath: loadUnit.unitPath
40
+ });
41
+ const proto = await EggPrototypeCreatorFactory.createProtoByDescriptor(protoDescriptor, loadUnit);
42
+ this.eggPrototypeFactory.registerPrototype(proto, loadUnit);
43
+ }
44
+ }
45
+ }
46
+ createStructuredTool(clazz, toolMeta) {
47
+ class StructuredTool {
48
+ async init() {
49
+ const toolsObj = await EggContainerFactory.getOrCreateEggObjectFromClazz(clazz);
50
+ const toolMetadata = GraphToolInfoUtil.getGraphToolMetadata(toolsObj.proto.clazz);
51
+ const ToolDetail = MCPInfoUtil.getMCPToolArgsIndex(toolsObj.proto.clazz, "execute");
52
+ if (toolMetadata && ToolDetail) {
53
+ const tool = new DynamicStructuredTool({
54
+ description: toolMetadata.description,
55
+ name: toolMetadata.toolName,
56
+ func: toolsObj.obj.execute.bind(toolsObj.obj),
57
+ schema: z.object(ToolDetail.argsSchema)
58
+ });
59
+ Object.setPrototypeOf(this, tool);
60
+ } else throw new Error(`graph tool ${toolMeta.name ?? clazz.name} not found`);
61
+ }
62
+ }
63
+ __decorate([
64
+ LifecyclePostInject(),
65
+ __decorateMetadata("design:type", Function),
66
+ __decorateMetadata("design:paramtypes", []),
67
+ __decorateMetadata("design:returntype", Promise)
68
+ ], StructuredTool.prototype, "init", null);
69
+ SingletonProto({
70
+ name: `structured${toolMeta.name ?? clazz.name}`,
71
+ accessLevel: AccessLevel.PUBLIC
72
+ })(StructuredTool);
73
+ return StructuredTool;
74
+ }
75
+ async postCreate(_ctx, obj) {
76
+ for (const graphName of this.graphCompiledNameMap.keys()) {
77
+ const graphProto = obj.getEggPrototype(graphName, [])[0];
78
+ if (graphProto) {
79
+ const compiledGraphProto = this.graphCompiledNameMap.get(graphName);
80
+ if (!compiledGraphProto.injectObjects.find((injectObject) => injectObject.objName === graphProto.name)) compiledGraphProto.injectObjects.push({
81
+ refName: "stateGraph",
82
+ objName: graphProto.name,
83
+ qualifiers: [],
84
+ proto: graphProto
85
+ });
86
+ }
87
+ }
88
+ }
89
+ };
90
+
91
+ //#endregion
92
+ export { GraphLoadUnitHook };
@@ -0,0 +1,9 @@
1
+ import { LifecycleHook } from "@eggjs/tegg";
2
+ import { EggObject, EggObjectLifeCycleContext } from "@eggjs/tegg/helper";
3
+
4
+ //#region src/lib/graph/GraphObjectHook.d.ts
5
+ declare class GraphObjectHook implements LifecycleHook<EggObjectLifeCycleContext, EggObject> {
6
+ postCreate(_: EggObjectLifeCycleContext, eggObject: EggObject): Promise<void>;
7
+ }
8
+ //#endregion
9
+ export { GraphObjectHook };
@@ -0,0 +1,95 @@
1
+ import { ChatModelInjectName, ChatModelQualifierAttribute, GRAPH_NODE_METADATA, GraphToolInfoUtil, TeggToolNode } from "@eggjs/langchain-decorator";
2
+ import { MCPClientInjectName, MCPClientQualifierAttribute } from "@eggjs/mcp-client";
3
+ import { MCPInfoUtil } from "@eggjs/tegg";
4
+ import { loadMcpTools } from "@langchain/mcp-adapters";
5
+ import { DynamicStructuredTool } from "langchain";
6
+ import "langchain/chat_models/universal";
7
+ import * as z from "zod/v4";
8
+ import { EggContainerFactory } from "@eggjs/tegg/helper";
9
+ import { ToolNode } from "@langchain/langgraph/prebuilt";
10
+
11
+ //#region src/lib/graph/GraphObjectHook.ts
12
+ var GraphNodeHandler = class {
13
+ nodeMetadata;
14
+ eggObject;
15
+ constructor(nodeMetadata, eggObject) {
16
+ this.nodeMetadata = nodeMetadata;
17
+ this.eggObject = eggObject;
18
+ }
19
+ async findGraphTools() {
20
+ const tools = this.nodeMetadata.tools ?? [];
21
+ let dTools = [];
22
+ for (let i = 0; i < tools.length; i++) {
23
+ const toolsObj = await EggContainerFactory.getOrCreateEggObjectFromClazz(tools[i]);
24
+ const toolMetadata = GraphToolInfoUtil.getGraphToolMetadata(toolsObj.proto.clazz);
25
+ const ToolDetail = MCPInfoUtil.getMCPToolArgsIndex(toolsObj.proto.clazz, "execute");
26
+ if (toolMetadata && ToolDetail) {
27
+ const tool = new DynamicStructuredTool({
28
+ description: toolMetadata.description,
29
+ name: toolMetadata.toolName,
30
+ func: toolsObj.obj.execute.bind(toolsObj.obj),
31
+ schema: z.object(ToolDetail.argsSchema)
32
+ });
33
+ dTools = dTools.concat(tool);
34
+ }
35
+ }
36
+ return dTools;
37
+ }
38
+ async findMcpServerTools() {
39
+ const mcpServers = this.nodeMetadata.mcpServers ?? [];
40
+ let sTools = [];
41
+ for (let i = 0; i < mcpServers.length; i++) {
42
+ const mcpClientObj = await EggContainerFactory.getOrCreateEggObjectFromName(MCPClientInjectName, [{
43
+ attribute: MCPClientQualifierAttribute,
44
+ value: mcpServers[i]
45
+ }]);
46
+ const tool = await loadMcpTools(mcpServers[i], mcpClientObj.obj, {
47
+ throwOnLoadError: true,
48
+ prefixToolNameWithServerName: false,
49
+ additionalToolNamePrefix: ""
50
+ });
51
+ sTools = sTools.concat(tool);
52
+ }
53
+ return sTools;
54
+ }
55
+ async boundTools() {
56
+ const nodeObj = this.eggObject.obj;
57
+ const dTools = await this.findGraphTools();
58
+ const sTools = await this.findMcpServerTools();
59
+ if (TeggToolNode.prototype.isPrototypeOf(nodeObj)) {
60
+ const toolNode = new ToolNode([...dTools, ...sTools]);
61
+ Object.defineProperty(nodeObj, "toolNode", { get: () => toolNode });
62
+ return;
63
+ }
64
+ if (nodeObj.build) nodeObj.build([...dTools, ...sTools]);
65
+ else {
66
+ const injectObjects = this.eggObject.proto.injectObjects;
67
+ for (let i = 0; i < injectObjects.length; i++) {
68
+ const injectObject = injectObjects[i];
69
+ const qualifiers = injectObject.qualifiers;
70
+ for (let j = 0; j < qualifiers.length; j++) {
71
+ const qualifier = qualifiers[j];
72
+ if (qualifier.attribute === ChatModelQualifierAttribute) {
73
+ const boundChatModel = (await EggContainerFactory.getOrCreateEggObjectFromName(ChatModelInjectName, [{
74
+ attribute: ChatModelQualifierAttribute,
75
+ value: qualifier.value
76
+ }])).obj.bindTools([...dTools, ...sTools]);
77
+ Object.defineProperty(nodeObj, injectObject.objName, { get: () => boundChatModel });
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ };
84
+ var GraphObjectHook = class {
85
+ async postCreate(_, eggObject) {
86
+ const nodeMetadata = eggObject.proto.getMetaData(GRAPH_NODE_METADATA);
87
+ if (nodeMetadata) {
88
+ await new GraphNodeHandler(nodeMetadata, eggObject).boundTools();
89
+ return;
90
+ }
91
+ }
92
+ };
93
+
94
+ //#endregion
95
+ export { GraphObjectHook };
@@ -0,0 +1,24 @@
1
+ import { EggProtoImplClass, LifecycleHook } from "@eggjs/tegg";
2
+ import { EggPrototype, EggPrototypeLifecycleContext } from "@eggjs/metadata";
3
+
4
+ //#region src/lib/graph/GraphPrototypeHook.d.ts
5
+ declare class GraphPrototypeHook implements LifecycleHook<EggPrototypeLifecycleContext, EggPrototype> {
6
+ toolProtoMap: Map<EggProtoImplClass, EggPrototype>;
7
+ nodeProtoMap: Map<EggPrototype, EggProtoImplClass[]>;
8
+ nodeMcpServerProtoMap: Map<EggPrototype, string[]>;
9
+ mcpServerProto: EggPrototype;
10
+ checkPointProto: EggPrototype;
11
+ checkPointList: EggProtoImplClass[];
12
+ checkPointProtoMap: Map<EggProtoImplClass, EggPrototype>;
13
+ checkPointGraphMap: Map<EggProtoImplClass, EggPrototype[]>;
14
+ graphCheckpointProtoMap: Map<EggPrototype, string>;
15
+ graphNodeProtoMap: Map<EggPrototype, EggProtoImplClass[]>;
16
+ nodeProto: Map<EggProtoImplClass, EggPrototype>;
17
+ graphEdgeProtoMap: Map<EggPrototype, EggProtoImplClass[]>;
18
+ edgeProto: Map<EggProtoImplClass, EggPrototype>;
19
+ postCreate(ctx: EggPrototypeLifecycleContext, proto: EggPrototype): Promise<void>;
20
+ makeNodeDependencies(ctx: EggPrototypeLifecycleContext, proto: EggPrototype): Promise<void>;
21
+ makeGraphDependencies(ctx: EggPrototypeLifecycleContext, proto: EggPrototype): Promise<void>;
22
+ }
23
+ //#endregion
24
+ export { GraphPrototypeHook };
@@ -0,0 +1,175 @@
1
+ import { ChatCheckpointSaverInjectName, ChatCheckpointSaverQualifierAttribute, GraphEdgeInfoUtil, GraphInfoUtil, GraphNodeInfoUtil, GraphToolInfoUtil } from "@eggjs/langchain-decorator";
2
+ import { MCPClientInjectName, MCPClientQualifierAttribute } from "@eggjs/mcp-client";
3
+ import { BaseCheckpointSaver } from "@langchain/langgraph";
4
+
5
+ //#region src/lib/graph/GraphPrototypeHook.ts
6
+ var GraphPrototypeHook = class {
7
+ toolProtoMap = /* @__PURE__ */ new Map();
8
+ nodeProtoMap = /* @__PURE__ */ new Map();
9
+ nodeMcpServerProtoMap = /* @__PURE__ */ new Map();
10
+ mcpServerProto;
11
+ checkPointProto;
12
+ checkPointList = [];
13
+ checkPointProtoMap = /* @__PURE__ */ new Map();
14
+ checkPointGraphMap = /* @__PURE__ */ new Map();
15
+ graphCheckpointProtoMap = /* @__PURE__ */ new Map();
16
+ graphNodeProtoMap = /* @__PURE__ */ new Map();
17
+ nodeProto = /* @__PURE__ */ new Map();
18
+ graphEdgeProtoMap = /* @__PURE__ */ new Map();
19
+ edgeProto = /* @__PURE__ */ new Map();
20
+ async postCreate(ctx, proto) {
21
+ await this.makeNodeDependencies(ctx, proto);
22
+ await this.makeGraphDependencies(ctx, proto);
23
+ }
24
+ async makeNodeDependencies(ctx, proto) {
25
+ const nodeMetadata = GraphNodeInfoUtil.getGraphNodeMetadata(ctx.clazz);
26
+ if (nodeMetadata) {
27
+ const tools = nodeMetadata.tools ?? [];
28
+ for (let i = 0; i < tools.length; i++) if (this.toolProtoMap.has(tools[i])) {
29
+ const toolProto = this.toolProtoMap.get(tools[i]);
30
+ proto.injectObjects.push({
31
+ refName: `__GRAPH_TOOL_${String(toolProto.name)}__`,
32
+ objName: toolProto.name,
33
+ qualifiers: [],
34
+ proto: toolProto
35
+ });
36
+ }
37
+ const mcpServers = nodeMetadata.mcpServers ?? [];
38
+ if (this.mcpServerProto) for (let i = 0; i < mcpServers.length; i++) proto.injectObjects.push({
39
+ refName: `__GRAPH_MCPSERVER_${String(mcpServers[i])}__`,
40
+ objName: MCPClientInjectName,
41
+ qualifiers: [{
42
+ attribute: MCPClientQualifierAttribute,
43
+ value: mcpServers[i]
44
+ }],
45
+ proto: this.mcpServerProto
46
+ });
47
+ this.nodeProtoMap.set(proto, tools);
48
+ this.nodeMcpServerProtoMap.set(proto, mcpServers);
49
+ }
50
+ if (GraphToolInfoUtil.getGraphToolMetadata(ctx.clazz)) {
51
+ for (const [nodeProto, toolClazzList] of this.nodeProtoMap.entries()) if (toolClazzList.includes(ctx.clazz)) nodeProto.injectObjects.push({
52
+ refName: `__GRAPH_TOOL_${String(proto.name)}__`,
53
+ objName: proto.name,
54
+ qualifiers: [],
55
+ proto
56
+ });
57
+ this.toolProtoMap.set(ctx.clazz, proto);
58
+ }
59
+ if (proto.name === MCPClientInjectName) {
60
+ this.mcpServerProto = proto;
61
+ for (const [nodeProto, mcpServers] of this.nodeMcpServerProtoMap.entries()) for (let i = 0; i < mcpServers.length; i++) nodeProto.injectObjects.push({
62
+ refName: `__GRAPH_MCPSERVER_${String(mcpServers[i])}__`,
63
+ objName: MCPClientInjectName,
64
+ qualifiers: [{
65
+ attribute: MCPClientQualifierAttribute,
66
+ value: mcpServers[i]
67
+ }],
68
+ proto
69
+ });
70
+ }
71
+ }
72
+ async makeGraphDependencies(ctx, proto) {
73
+ const graphMetadata = GraphInfoUtil.getGraphMetadata(ctx.clazz);
74
+ if (graphMetadata) {
75
+ if (graphMetadata.checkpoint) {
76
+ if (typeof graphMetadata.checkpoint === "string") {
77
+ if (this.checkPointProto) proto.injectObjects.push({
78
+ refName: "checkpoint",
79
+ objName: ChatCheckpointSaverInjectName,
80
+ qualifiers: [{
81
+ attribute: ChatCheckpointSaverQualifierAttribute,
82
+ value: graphMetadata.checkpoint
83
+ }],
84
+ proto: this.checkPointProto
85
+ });
86
+ this.graphCheckpointProtoMap.set(proto, graphMetadata.checkpoint);
87
+ } else {
88
+ if (this.checkPointProtoMap.has(graphMetadata.checkpoint)) {
89
+ const checkPointProto = this.checkPointProtoMap.get(graphMetadata.checkpoint);
90
+ proto.injectObjects.push({
91
+ refName: "checkpoint",
92
+ objName: checkPointProto.name,
93
+ qualifiers: [],
94
+ proto: checkPointProto
95
+ });
96
+ }
97
+ this.checkPointList.push(graphMetadata.checkpoint);
98
+ if (this.checkPointGraphMap.has(graphMetadata.checkpoint)) this.checkPointGraphMap.get(graphMetadata.checkpoint).push(proto);
99
+ else this.checkPointGraphMap.set(graphMetadata.checkpoint, [proto]);
100
+ }
101
+ this.graphNodeProtoMap.set(proto, []);
102
+ this.graphEdgeProtoMap.set(proto, []);
103
+ for (const nodeProto of graphMetadata.nodes ?? []) if (this.nodeProto.has(nodeProto)) proto.injectObjects.push({
104
+ refName: `__GRAPH_NODE_${String(nodeProto)}__`,
105
+ objName: nodeProto.name,
106
+ qualifiers: [],
107
+ proto: this.nodeProto.get(nodeProto)
108
+ });
109
+ else this.graphNodeProtoMap.get(proto).push(nodeProto);
110
+ for (const edgeProto of graphMetadata.edges ?? []) if (this.edgeProto.has(edgeProto)) proto.injectObjects.push({
111
+ refName: `__GRAPH_EDGE_${String(edgeProto)}__`,
112
+ objName: edgeProto.name,
113
+ qualifiers: [],
114
+ proto: this.edgeProto.get(edgeProto)
115
+ });
116
+ else this.graphEdgeProtoMap.get(proto).push(edgeProto);
117
+ }
118
+ }
119
+ if (proto.name === ChatCheckpointSaverInjectName) {
120
+ this.checkPointProto = proto;
121
+ for (const [graphProto, checkpoint] of this.graphCheckpointProtoMap.entries()) if (checkpoint === graphMetadata?.checkpoint) {
122
+ if (!graphProto.injectObjects.find((injectObject) => injectObject.refName === "checkpoint")) continue;
123
+ graphProto.injectObjects.push({
124
+ refName: "checkpoint",
125
+ objName: ChatCheckpointSaverInjectName,
126
+ qualifiers: [{
127
+ attribute: ChatCheckpointSaverQualifierAttribute,
128
+ value: checkpoint
129
+ }],
130
+ proto
131
+ });
132
+ }
133
+ }
134
+ if (BaseCheckpointSaver.isPrototypeOf(ctx.clazz)) {
135
+ const graphProto = this.checkPointGraphMap.get(ctx.clazz) ?? [];
136
+ for (let i = 0; i < graphProto.length; i++) {
137
+ if (!graphProto[i].injectObjects.find((injectObject) => injectObject.refName === "checkpoint")) continue;
138
+ graphProto[i].injectObjects.push({
139
+ refName: "checkpoint",
140
+ objName: proto.name,
141
+ qualifiers: [],
142
+ proto
143
+ });
144
+ }
145
+ this.checkPointProtoMap.set(ctx.clazz, proto);
146
+ }
147
+ if (GraphNodeInfoUtil.getGraphNodeMetadata(ctx.clazz)) {
148
+ this.nodeProto.set(ctx.clazz, proto);
149
+ for (const [graphProto, nodeProtos] of this.graphNodeProtoMap.entries()) if (nodeProtos.includes(ctx.clazz)) {
150
+ if (graphProto.injectObjects.find((injectObject) => injectObject.refName === `__GRAPH_NODE_${String(ctx.clazz)}__`)) continue;
151
+ graphProto.injectObjects.push({
152
+ refName: `__GRAPH_NODE_${String(ctx.clazz)}__`,
153
+ objName: proto.name,
154
+ qualifiers: [],
155
+ proto
156
+ });
157
+ }
158
+ }
159
+ if (GraphEdgeInfoUtil.getGraphEdgeMetadata(ctx.clazz)) {
160
+ this.edgeProto.set(ctx.clazz, proto);
161
+ for (const [graphProto, edgeProtos] of this.graphEdgeProtoMap.entries()) if (edgeProtos.includes(ctx.clazz)) {
162
+ if (graphProto.injectObjects.find((injectObject) => injectObject.refName === `__GRAPH_EDGE_${String(ctx.clazz)}__`)) continue;
163
+ graphProto.injectObjects.push({
164
+ refName: `__GRAPH_EDGE_${String(ctx.clazz)}__`,
165
+ objName: proto.name,
166
+ qualifiers: [],
167
+ proto
168
+ });
169
+ }
170
+ }
171
+ }
172
+ };
173
+
174
+ //#endregion
175
+ export { GraphPrototypeHook };
@@ -0,0 +1,12 @@
1
+ import { Logger } from "@eggjs/tegg";
2
+ import { BaseTracer, Run } from "@langchain/core/tracers/base";
3
+
4
+ //#region src/lib/tracing/LangGraphTracer.d.ts
5
+ declare class LangGraphTracer extends BaseTracer {
6
+ logger: Logger;
7
+ name: string;
8
+ setName(name: string): void;
9
+ protected persistRun(run: Run): Promise<void>;
10
+ }
11
+ //#endregion
12
+ export { LangGraphTracer };
@@ -0,0 +1,22 @@
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js";
3
+ import { AccessLevel, Inject, SingletonProto } from "@eggjs/tegg";
4
+ import { BaseTracer, Run } from "@langchain/core/tracers/base";
5
+
6
+ //#region src/lib/tracing/LangGraphTracer.ts
7
+ let LangGraphTracer = class LangGraphTracer$1 extends BaseTracer {
8
+ logger;
9
+ name = "LangGraphTracer";
10
+ setName(name) {
11
+ this.name = name;
12
+ }
13
+ persistRun(run) {
14
+ this.logger.info(`[agent_run][${this.name}]:traceId=${run.trace_id},run=${JSON.stringify(run)}`);
15
+ return Promise.resolve(void 0);
16
+ }
17
+ };
18
+ __decorate([Inject(), __decorateMetadata("design:type", Object)], LangGraphTracer.prototype, "logger", void 0);
19
+ LangGraphTracer = __decorate([SingletonProto({ accessLevel: AccessLevel.PUBLIC })], LangGraphTracer);
20
+
21
+ //#endregion
22
+ export { LangGraphTracer };
@@ -0,0 +1,8 @@
1
+ import { ModuleConfig, ObjectInfo } from "@eggjs/tegg";
2
+
3
+ //#region src/lib/util.d.ts
4
+ type ConfigTypeHelper = any;
5
+ declare function getClientNames(config: ModuleConfig | undefined, key: string): string[];
6
+ declare function getChatModelConfig(config: ModuleConfig, objectInfo: ObjectInfo): any;
7
+ //#endregion
8
+ export { ConfigTypeHelper, getChatModelConfig, getClientNames };
@@ -0,0 +1,19 @@
1
+ import { ChatModelQualifierAttribute } from "@eggjs/langchain-decorator";
2
+ import assert from "node:assert";
3
+
4
+ //#region src/lib/util.ts
5
+ function getClientNames(config, key) {
6
+ const clients = config?.[key]?.clients;
7
+ if (!clients) return [];
8
+ return Object.keys(clients);
9
+ }
10
+ function getChatModelConfig(config, objectInfo) {
11
+ const chatModelName = objectInfo.qualifiers.find((t) => t.attribute === ChatModelQualifierAttribute)?.value;
12
+ assert(chatModelName, "not found ChatModel name");
13
+ const chatModelConfig = config.ChatModel?.clients[chatModelName];
14
+ if (!chatModelConfig) throw new Error(`not found ChatModel config for ${chatModelName}`);
15
+ return chatModelConfig;
16
+ }
17
+
18
+ //#endregion
19
+ export { getChatModelConfig, getClientNames };
package/package.json CHANGED
@@ -1,31 +1,99 @@
1
1
  {
2
2
  "name": "@eggjs/langchain-plugin",
3
- "version": "0.0.0",
4
- "description": "egg logger",
3
+ "version": "4.0.2-beta.0",
4
+ "description": "langchain for egg",
5
5
  "keywords": [
6
6
  "egg",
7
- "logger"
7
+ "langchain",
8
+ "module",
9
+ "plugin",
10
+ "tegg",
11
+ "typescript"
8
12
  ],
9
- "homepage": "https://github.com/eggjs/egg/tree/next/packages/logger",
13
+ "homepage": "https://github.com/eggjs/egg/tree/next/tegg/plugin/langchain",
10
14
  "bugs": {
11
15
  "url": "https://github.com/eggjs/egg/issues"
12
16
  },
13
- "license": "MIT",
14
- "author": "fengmk2 <fengmk2@gmail.com> (https://github.com/fengmk2)",
15
17
  "repository": {
16
18
  "type": "git",
17
19
  "url": "git+https://github.com/eggjs/egg.git",
18
- "directory": "packages/logger"
20
+ "directory": "tegg/plugin/langchain"
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "type": "module",
26
+ "main": "./dist/index.js",
27
+ "module": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": "./dist/index.js",
31
+ "./app": "./dist/app.js",
32
+ "./lib/boundModel/BoundModelObjectHook": "./dist/lib/boundModel/BoundModelObjectHook.js",
33
+ "./lib/ChatModelHelper": "./dist/lib/ChatModelHelper.js",
34
+ "./lib/ChatOpenAI": "./dist/lib/ChatOpenAI.js",
35
+ "./lib/config/QualifierUtil": "./dist/lib/config/QualifierUtil.js",
36
+ "./lib/graph/CompiledStateGraphObject": "./dist/lib/graph/CompiledStateGraphObject.js",
37
+ "./lib/graph/CompiledStateGraphProto": "./dist/lib/graph/CompiledStateGraphProto.js",
38
+ "./lib/graph/GraphBuildHook": "./dist/lib/graph/GraphBuildHook.js",
39
+ "./lib/graph/GraphLoadUnitHook": "./dist/lib/graph/GraphLoadUnitHook.js",
40
+ "./lib/graph/GraphObjectHook": "./dist/lib/graph/GraphObjectHook.js",
41
+ "./lib/graph/GraphPrototypeHook": "./dist/lib/graph/GraphPrototypeHook.js",
42
+ "./lib/tracing/LangGraphTracer": "./dist/lib/tracing/LangGraphTracer.js",
43
+ "./lib/util": "./dist/lib/util.js",
44
+ "./package.json": "./package.json"
19
45
  },
20
46
  "publishConfig": {
21
47
  "access": "public"
22
48
  },
23
49
  "dependencies": {
50
+ "@langchain/core": "^1.1.1",
51
+ "@langchain/langgraph": "^1.0.2",
52
+ "@langchain/mcp-adapters": "^1.0.0",
53
+ "@langchain/openai": "^1.0.0",
54
+ "langchain": "^1.1.2",
55
+ "urllib": "^4.8.2",
56
+ "zod": "^4.0.0",
57
+ "@eggjs/langchain-decorator": "4.0.2-beta.0",
58
+ "@eggjs/mcp-client": "4.0.2-beta.0",
59
+ "@eggjs/metadata": "4.0.2-beta.0",
60
+ "@eggjs/module-common": "4.0.2-beta.0",
61
+ "@eggjs/tegg-common-util": "4.0.2-beta.0",
62
+ "@eggjs/tegg-types": "4.0.2-beta.0",
63
+ "@eggjs/tegg": "4.0.2-beta.0",
64
+ "@eggjs/tegg-runtime": "4.0.2-beta.0"
24
65
  },
25
66
  "devDependencies": {
67
+ "@modelcontextprotocol/sdk": "^1.23.0",
68
+ "@types/node": "^24.10.2",
69
+ "typescript": "^5.9.3",
70
+ "@eggjs/controller-plugin": "4.0.2-beta.0",
71
+ "@eggjs/mock": "7.0.2-beta.0",
72
+ "@eggjs/module-test-util": "4.0.0-beta.29",
73
+ "@eggjs/router": "4.0.2-beta.0",
74
+ "@eggjs/tegg-config": "4.0.2-beta.0",
75
+ "@eggjs/mcp-client-plugin": "4.0.2-beta.0",
76
+ "@eggjs/tegg-plugin": "4.0.2-beta.0",
77
+ "egg": "4.1.2-beta.0",
78
+ "@eggjs/tracer": "4.0.2-beta.0"
79
+ },
80
+ "peerDependencies": {
81
+ "@eggjs/tegg-plugin": "4.0.2-beta.0",
82
+ "egg": "4.1.2-beta.0"
26
83
  },
27
84
  "engines": {
28
- "node": ">= 22.18.0"
85
+ "node": ">=22.18.0"
86
+ },
87
+ "eggModule": {
88
+ "name": "teggLangChain"
89
+ },
90
+ "eggPlugin": {
91
+ "name": "teggLangChain",
92
+ "dependencies": [
93
+ "tegg"
94
+ ]
95
+ },
96
+ "scripts": {
97
+ "typecheck": "tsgo --noEmit"
29
98
  }
30
- }
31
-
99
+ }