nestjs-langchain 1.0.2 → 2.0.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 (151) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +344 -254
  3. package/dist/agent.d.ts +63 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +189 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/constants.d.ts +5 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +14 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/decorators/index.d.ts +4 -2
  12. package/dist/decorators/index.d.ts.map +1 -0
  13. package/dist/decorators/index.js +3 -18
  14. package/dist/decorators/index.js.map +1 -0
  15. package/dist/decorators/inject-agent.decorator.d.ts +12 -0
  16. package/dist/decorators/inject-agent.decorator.d.ts.map +1 -0
  17. package/dist/decorators/inject-agent.decorator.js +15 -7
  18. package/dist/decorators/inject-agent.decorator.js.map +1 -0
  19. package/dist/decorators/tool.decorator.d.ts +54 -6
  20. package/dist/decorators/tool.decorator.d.ts.map +1 -0
  21. package/dist/decorators/tool.decorator.js +40 -16
  22. package/dist/decorators/tool.decorator.js.map +1 -0
  23. package/dist/errors/agent-run.error.d.ts +27 -0
  24. package/dist/errors/agent-run.error.d.ts.map +1 -0
  25. package/dist/errors/agent-run.error.js +26 -0
  26. package/dist/errors/agent-run.error.js.map +1 -0
  27. package/dist/errors/index.d.ts +3 -0
  28. package/dist/errors/index.d.ts.map +1 -0
  29. package/dist/errors/index.js +3 -0
  30. package/dist/errors/index.js.map +1 -0
  31. package/dist/errors/messages.d.ts +26 -0
  32. package/dist/errors/messages.d.ts.map +1 -0
  33. package/dist/errors/messages.js +67 -0
  34. package/dist/errors/messages.js.map +1 -0
  35. package/dist/errors/tool-configuration.error.d.ts +23 -0
  36. package/dist/errors/tool-configuration.error.d.ts.map +1 -0
  37. package/dist/errors/tool-configuration.error.js +27 -0
  38. package/dist/errors/tool-configuration.error.js.map +1 -0
  39. package/dist/index.d.ts +10 -3
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +8 -19
  42. package/dist/index.js.map +1 -0
  43. package/dist/interfaces/agent-observer.interface.d.ts +107 -0
  44. package/dist/interfaces/agent-observer.interface.d.ts.map +1 -0
  45. package/dist/interfaces/agent-observer.interface.js +2 -0
  46. package/dist/interfaces/agent-observer.interface.js.map +1 -0
  47. package/dist/interfaces/completed-run.interface.d.ts +14 -0
  48. package/dist/interfaces/completed-run.interface.d.ts.map +1 -0
  49. package/dist/interfaces/completed-run.interface.js +2 -0
  50. package/dist/interfaces/completed-run.interface.js.map +1 -0
  51. package/dist/interfaces/langchain-module-options.interface.d.ts +73 -5
  52. package/dist/interfaces/langchain-module-options.interface.d.ts.map +1 -0
  53. package/dist/interfaces/langchain-module-options.interface.js +2 -2
  54. package/dist/interfaces/langchain-module-options.interface.js.map +1 -0
  55. package/dist/langchain.module-definition.d.ts +26 -6
  56. package/dist/langchain.module-definition.d.ts.map +1 -0
  57. package/dist/langchain.module-definition.js +26 -13
  58. package/dist/langchain.module-definition.js.map +1 -0
  59. package/dist/langchain.module.d.ts +60 -3
  60. package/dist/langchain.module.d.ts.map +1 -0
  61. package/dist/langchain.module.js +87 -24
  62. package/dist/langchain.module.js.map +1 -0
  63. package/dist/logging/index.d.ts +3 -0
  64. package/dist/logging/index.d.ts.map +1 -0
  65. package/dist/logging/index.js +3 -0
  66. package/dist/logging/index.js.map +1 -0
  67. package/dist/logging/observe-tool-call.util.d.ts +13 -0
  68. package/dist/logging/observe-tool-call.util.d.ts.map +1 -0
  69. package/dist/logging/observe-tool-call.util.js +34 -0
  70. package/dist/logging/observe-tool-call.util.js.map +1 -0
  71. package/dist/logging/run-reporter.d.ts +26 -0
  72. package/dist/logging/run-reporter.d.ts.map +1 -0
  73. package/dist/logging/run-reporter.js +39 -0
  74. package/dist/logging/run-reporter.js.map +1 -0
  75. package/dist/run/index.d.ts +3 -0
  76. package/dist/run/index.d.ts.map +1 -0
  77. package/dist/run/index.js +2 -0
  78. package/dist/run/index.js.map +1 -0
  79. package/dist/run/run-summary.util.d.ts +31 -0
  80. package/dist/run/run-summary.util.d.ts.map +1 -0
  81. package/dist/run/run-summary.util.js +28 -0
  82. package/dist/run/run-summary.util.js.map +1 -0
  83. package/dist/tools/index.d.ts +3 -0
  84. package/dist/tools/index.d.ts.map +1 -0
  85. package/dist/tools/index.js +3 -0
  86. package/dist/tools/index.js.map +1 -0
  87. package/dist/tools/tool-discovery.service.d.ts +31 -0
  88. package/dist/tools/tool-discovery.service.d.ts.map +1 -0
  89. package/dist/tools/tool-discovery.service.js +132 -0
  90. package/dist/tools/tool-discovery.service.js.map +1 -0
  91. package/dist/tools/tool-errors.middleware.d.ts +21 -0
  92. package/dist/tools/tool-errors.middleware.d.ts.map +1 -0
  93. package/dist/tools/tool-errors.middleware.js +55 -0
  94. package/dist/tools/tool-errors.middleware.js.map +1 -0
  95. package/dist/tools/tool-method.util.d.ts +21 -0
  96. package/dist/tools/tool-method.util.d.ts.map +1 -0
  97. package/dist/tools/tool-method.util.js +39 -0
  98. package/dist/tools/tool-method.util.js.map +1 -0
  99. package/dist/tools/tool-modules.util.d.ts +14 -0
  100. package/dist/tools/tool-modules.util.d.ts.map +1 -0
  101. package/dist/tools/tool-modules.util.js +61 -0
  102. package/dist/tools/tool-modules.util.js.map +1 -0
  103. package/dist/tools/tool-name.util.d.ts +10 -0
  104. package/dist/tools/tool-name.util.d.ts.map +1 -0
  105. package/dist/tools/tool-name.util.js +35 -0
  106. package/dist/tools/tool-name.util.js.map +1 -0
  107. package/dist/tools/tool-schema.factory.d.ts +4 -0
  108. package/dist/tools/tool-schema.factory.d.ts.map +1 -0
  109. package/dist/tools/tool-schema.factory.js +87 -0
  110. package/dist/tools/tool-schema.factory.js.map +1 -0
  111. package/dist/tools/tool.factory.d.ts +9 -0
  112. package/dist/tools/tool.factory.d.ts.map +1 -0
  113. package/dist/tools/tool.factory.js +34 -0
  114. package/dist/tools/tool.factory.js.map +1 -0
  115. package/lib/agent.ts +257 -0
  116. package/lib/constants.ts +15 -0
  117. package/lib/decorators/index.ts +3 -0
  118. package/lib/decorators/inject-agent.decorator.ts +15 -0
  119. package/lib/decorators/tool.decorator.ts +86 -0
  120. package/lib/errors/agent-run.error.ts +29 -0
  121. package/lib/errors/index.ts +2 -0
  122. package/lib/errors/messages.ts +158 -0
  123. package/lib/errors/tool-configuration.error.ts +24 -0
  124. package/lib/index.ts +26 -0
  125. package/lib/interfaces/agent-observer.interface.ts +113 -0
  126. package/lib/interfaces/completed-run.interface.ts +14 -0
  127. package/lib/interfaces/langchain-module-options.interface.ts +91 -0
  128. package/lib/langchain.module-definition.ts +36 -0
  129. package/lib/langchain.module.ts +138 -0
  130. package/lib/logging/index.ts +2 -0
  131. package/lib/logging/observe-tool-call.util.ts +59 -0
  132. package/lib/logging/run-reporter.ts +56 -0
  133. package/lib/run/index.ts +2 -0
  134. package/lib/run/run-summary.util.ts +51 -0
  135. package/lib/tools/index.ts +2 -0
  136. package/lib/tools/tool-discovery.service.ts +191 -0
  137. package/lib/tools/tool-errors.middleware.ts +68 -0
  138. package/lib/tools/tool-method.util.ts +81 -0
  139. package/lib/tools/tool-modules.util.ts +104 -0
  140. package/lib/tools/tool-name.util.ts +57 -0
  141. package/lib/tools/tool-schema.factory.ts +142 -0
  142. package/lib/tools/tool.factory.ts +56 -0
  143. package/package.json +112 -91
  144. package/dist/factories/message.factory.d.ts +0 -7
  145. package/dist/factories/message.factory.js +0 -28
  146. package/dist/langchain.service.d.ts +0 -18
  147. package/dist/langchain.service.js +0 -69
  148. package/dist/tool-discovery.service.d.ts +0 -11
  149. package/dist/tool-discovery.service.js +0 -79
  150. package/dist/types/message.d.ts +0 -69
  151. package/dist/types/message.js +0 -104
@@ -1,47 +1,110 @@
1
- "use strict";
2
1
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
2
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
3
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
4
  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
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
6
  };
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.LangChainModule = void 0;
10
- const common_1 = require("@nestjs/common");
11
- const langchain_module_definition_1 = require("./langchain.module-definition");
12
- const langchain_service_1 = require("./langchain.service");
13
- const tool_discovery_service_1 = require("./tool-discovery.service");
14
- const metadata_scanner_1 = require("@nestjs/core/metadata-scanner");
15
- const core_1 = require("@nestjs/core");
16
- let LangChainModule = class LangChainModule extends langchain_module_definition_1.ConfigurableModuleClass {
7
+ import { Module } from '@nestjs/common';
8
+ import { AGENT_NAME_TOKEN, ConfigurableModuleClass, getAgentToken, UNNAMED_AGENT, } from './langchain.module-definition.js';
9
+ import { Agent } from './agent.js';
10
+ import { ToolDiscoveryService } from './tools/index.js';
11
+ import { reservedAgentName } from './errors/messages.js';
12
+ import { DiscoveryModule } from '@nestjs/core';
13
+ /**
14
+ * Registers agents as Nest providers: each `register` or `registerAsync`
15
+ * adds one. Give each a `name` when there are several.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * imports: [
20
+ * MathModule,
21
+ * LangChainModule.register({
22
+ * model: { model: 'openai:gpt-5-mini' },
23
+ * tools: [MathModule],
24
+ * }),
25
+ * ],
26
+ * ```
27
+ */
28
+ let LangChainModule = class LangChainModule extends ConfigurableModuleClass {
29
+ /**
30
+ * Registers an agent from its options.
31
+ *
32
+ * @param options The agent's options, with its `name` when there are several.
33
+ * @returns The module providing the agent.
34
+ * @example
35
+ * ```ts
36
+ * LangChainModule.register({
37
+ * name: 'MATH_AGENT',
38
+ * model: { model: 'openai:gpt-5-mini' },
39
+ * tools: [MathModule],
40
+ * });
41
+ * ```
42
+ */
17
43
  static register(options) {
18
44
  const dynamicModule = super.register(options);
19
45
  return this.addDynamicAgentProvider(dynamicModule, options.name);
20
46
  }
47
+ /**
48
+ * Registers an agent whose options other providers build, through
49
+ * `useFactory`, `useClass` or `useExisting`. `name` stays outside the
50
+ * factory: it names the token `@InjectAgent()` resolves.
51
+ *
52
+ * @param options How to build the agent's options, and its `name`.
53
+ * @returns The module providing the agent.
54
+ * @example
55
+ * ```ts
56
+ * LangChainModule.registerAsync({
57
+ * name: 'MATH_AGENT',
58
+ * imports: [ConfigModule],
59
+ * inject: [ConfigService],
60
+ * useFactory: (config: ConfigService) => ({
61
+ * model: {
62
+ * model: 'openai:gpt-5-mini',
63
+ * apiKey: config.getOrThrow<string>('OPENAI_API_KEY'),
64
+ * },
65
+ * }),
66
+ * });
67
+ * ```
68
+ */
21
69
  static registerAsync(options) {
22
70
  const dynamicModule = super.registerAsync(options);
23
71
  return this.addDynamicAgentProvider(dynamicModule, options.name);
24
72
  }
25
73
  static addDynamicAgentProvider(dynamicModule, name) {
26
- if (!name)
27
- return dynamicModule;
28
- const agentToken = (0, langchain_module_definition_1.getAgentToken)(name);
29
- const agentProvider = {
30
- provide: agentToken,
31
- useExisting: langchain_service_1.LangChainService,
74
+ if (name === '' || name === UNNAMED_AGENT) {
75
+ throw new Error(reservedAgentName(name));
76
+ }
77
+ const nameProvider = {
78
+ provide: AGENT_NAME_TOKEN,
79
+ useValue: name ?? UNNAMED_AGENT,
32
80
  };
81
+ // The class token belongs to the unnamed agent alone, in every module, so
82
+ // `overrideProvider(Agent)` and `get(Agent)` never reach a named one.
83
+ // See #128 and #170.
84
+ if (!name) {
85
+ return {
86
+ ...dynamicModule,
87
+ providers: [...(dynamicModule.providers ?? []), nameProvider, Agent],
88
+ exports: [...(dynamicModule.exports ?? []), Agent],
89
+ };
90
+ }
91
+ const agentToken = getAgentToken(name);
33
92
  return {
34
93
  ...dynamicModule,
35
- providers: [...(dynamicModule.providers || []), agentProvider],
36
- exports: [agentToken],
94
+ providers: [
95
+ ...(dynamicModule.providers ?? []),
96
+ nameProvider,
97
+ { provide: agentToken, useClass: Agent },
98
+ ],
99
+ exports: [...(dynamicModule.exports ?? []), agentToken],
37
100
  };
38
101
  }
39
102
  };
40
- exports.LangChainModule = LangChainModule;
41
- exports.LangChainModule = LangChainModule = __decorate([
42
- (0, common_1.Module)({
43
- imports: [core_1.DiscoveryModule],
44
- providers: [langchain_service_1.LangChainService, tool_discovery_service_1.ToolDiscoveryService, metadata_scanner_1.MetadataScanner],
45
- exports: [langchain_service_1.LangChainService],
103
+ LangChainModule = __decorate([
104
+ Module({
105
+ imports: [DiscoveryModule],
106
+ providers: [ToolDiscoveryService],
46
107
  })
47
108
  ], LangChainModule);
109
+ export { LangChainModule };
110
+ //# sourceMappingURL=langchain.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"langchain.module.js","sourceRoot":"","sources":["../lib/langchain.module.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAiB,MAAM,EAAkB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACL,gBAAgB,EAEhB,uBAAuB,EACvB,aAAa,EAEb,aAAa,GACd,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;;;;;;;;;;;GAcG;AAKI,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,uBAAuB;IAC1D;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,QAAQ,CAAC,OAA4B;QAC1C,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,aAAa,CAMlB,OAUC;QAED,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,uBAAuB,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAEO,MAAM,CAAC,uBAAuB,CACpC,aAA4B,EAC5B,IAAwB;QAExB,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,YAAY,GAAa;YAC7B,OAAO,EAAE,gBAAgB;YACzB,QAAQ,EAAE,IAAI,IAAI,aAAa;SAChC,CAAC;QAEF,0EAA0E;QAC1E,sEAAsE;QACtE,qBAAqB;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,GAAG,aAAa;gBAChB,SAAS,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC;gBACpE,OAAO,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC;aACnD,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEvC,OAAO;YACL,GAAG,aAAa;YAChB,SAAS,EAAE;gBACT,GAAG,CAAC,aAAa,CAAC,SAAS,IAAI,EAAE,CAAC;gBAClC,YAAY;gBACZ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;aACzC;YACD,OAAO,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC;SACxD,CAAC;IACJ,CAAC;CACF,CAAA;AApGY,eAAe;IAJ3B,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,eAAe,CAAC;QAC1B,SAAS,EAAE,CAAC,oBAAoB,CAAC;KAClC,CAAC;GACW,eAAe,CAoG3B"}
@@ -0,0 +1,3 @@
1
+ export { observeToolCall, reportToolError } from './observe-tool-call.util.js';
2
+ export { LOG_CONTEXT, messageOf, RunReporter } from './run-reporter.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { observeToolCall, reportToolError } from './observe-tool-call.util.js';
2
+ export { LOG_CONTEXT, messageOf, RunReporter } from './run-reporter.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/logging/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { ToolErrorEvent } from '../interfaces/agent-observer.interface.js';
2
+ import { RunReporter } from './run-reporter.js';
3
+ interface ToolCall {
4
+ tool: string;
5
+ callId: string;
6
+ args: Record<string, unknown>;
7
+ }
8
+ /** Logs a failed tool call and hands it to the observer. */
9
+ export declare const reportToolError: (reporter: RunReporter, event: Omit<ToolErrorEvent, "agent">) => void;
10
+ /** Runs one tool call, reporting its start, then its end or its failure. */
11
+ export declare const observeToolCall: (reporter: RunReporter, { tool, callId, args }: ToolCall, call: () => unknown) => Promise<unknown>;
12
+ export {};
13
+ //# sourceMappingURL=observe-tool-call.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe-tool-call.util.d.ts","sourceRoot":"","sources":["../../lib/logging/observe-tool-call.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE3D,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,4DAA4D;AAC5D,eAAO,MAAM,eAAe,GAC1B,UAAU,WAAW,EACrB,OAAO,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,KACnC,IAKF,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,eAAe,GAC1B,UAAU,WAAW,EACrB,wBAAwB,QAAQ,EAChC,MAAM,MAAM,OAAO,KAClB,OAAO,CAAC,OAAO,CAiCjB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { messageOf } from './run-reporter.js';
2
+ /** Logs a failed tool call and hands it to the observer. */
3
+ export const reportToolError = (reporter, event) => {
4
+ reporter.logError(`${event.tool} failed: ${messageOf(event.error)}`);
5
+ reporter.notify((observer) => observer.onToolError?.({ agent: reporter.agent, ...event }));
6
+ };
7
+ /** Runs one tool call, reporting its start, then its end or its failure. */
8
+ export const observeToolCall = async (reporter, { tool, callId, args }, call) => {
9
+ const { agent } = reporter;
10
+ const startedAt = Date.now();
11
+ reporter.notify((observer) => observer.onToolStart?.({ agent, tool, callId, args }));
12
+ try {
13
+ const output = await call();
14
+ reporter.notify((observer) => observer.onToolEnd?.({
15
+ agent,
16
+ tool,
17
+ callId,
18
+ output,
19
+ durationMs: Date.now() - startedAt,
20
+ }));
21
+ return output;
22
+ }
23
+ catch (error) {
24
+ reportToolError(reporter, {
25
+ tool,
26
+ callId,
27
+ reason: 'threw',
28
+ error,
29
+ durationMs: Date.now() - startedAt,
30
+ });
31
+ throw error;
32
+ }
33
+ };
34
+ //# sourceMappingURL=observe-tool-call.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe-tool-call.util.js","sourceRoot":"","sources":["../../lib/logging/observe-tool-call.util.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAe,MAAM,mBAAmB,CAAC;AAQ3D,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,QAAqB,EACrB,KAAoC,EAC9B,EAAE;IACR,QAAQ,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,YAAY,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrE,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC3B,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC,CAC5D,CAAC;AACJ,CAAC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,QAAqB,EACrB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAY,EAChC,IAAmB,EACD,EAAE;IACpB,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC3B,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CACtD,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAE5B,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC3B,QAAQ,CAAC,SAAS,EAAE,CAAC;YACnB,KAAK;YACL,IAAI;YACJ,MAAM;YACN,MAAM;YACN,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACnC,CAAC,CACH,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAe,CAAC,QAAQ,EAAE;YACxB,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,OAAO;YACf,KAAK;YACL,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACnC,CAAC,CAAC;QAEH,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { LoggerService } from '@nestjs/common';
2
+ import { AgentObserver } from '../interfaces/agent-observer.interface.js';
3
+ export declare const LOG_CONTEXT = "LangChainAgent";
4
+ interface RunReporterInput {
5
+ logger: LoggerService;
6
+ agent: string;
7
+ /** Empty for the unnamed agent, `'MATH '` otherwise. */
8
+ prefix: string;
9
+ observer?: AgentObserver;
10
+ }
11
+ export declare const messageOf: (error: unknown) => string;
12
+ /** One agent's error log lines and its observer. */
13
+ export declare class RunReporter {
14
+ private readonly input;
15
+ constructor(input: RunReporterInput);
16
+ get agent(): string;
17
+ /** One line per error, whatever the message holds. */
18
+ logError(message: string): void;
19
+ /**
20
+ * Hands an event to the observer, if any. Never awaited: a throw or a
21
+ * rejection is logged and swallowed, never propagated into the run.
22
+ */
23
+ notify(call: (observer: AgentObserver) => void | Promise<void>): void;
24
+ }
25
+ export {};
26
+ //# sourceMappingURL=run-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-reporter.d.ts","sourceRoot":"","sources":["../../lib/logging/run-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAE1E,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAE5C,UAAU,gBAAgB;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,eAAO,MAAM,SAAS,GAAI,OAAO,OAAO,KAAG,MACa,CAAC;AAEzD,oDAAoD;AACpD,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,gBAAgB;IAEpD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAU/B;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CAgBtE"}
@@ -0,0 +1,39 @@
1
+ export const LOG_CONTEXT = 'LangChainAgent';
2
+ export const messageOf = (error) => error instanceof Error ? error.message : String(error);
3
+ /** One agent's error log lines and its observer. */
4
+ export class RunReporter {
5
+ input;
6
+ constructor(input) {
7
+ this.input = input;
8
+ }
9
+ get agent() {
10
+ return this.input.agent;
11
+ }
12
+ /** One line per error, whatever the message holds. */
13
+ logError(message) {
14
+ const line = message
15
+ .split('\n')
16
+ .map((part) => part.trim())
17
+ .filter(Boolean)
18
+ .join(' ');
19
+ this.input.logger.error(`${this.input.prefix}${line}`, LOG_CONTEXT);
20
+ }
21
+ /**
22
+ * Hands an event to the observer, if any. Never awaited: a throw or a
23
+ * rejection is logged and swallowed, never propagated into the run.
24
+ */
25
+ notify(call) {
26
+ const { observer } = this.input;
27
+ if (!observer) {
28
+ return;
29
+ }
30
+ const onFailure = (error) => this.logError(`the observer failed: ${messageOf(error)}`);
31
+ try {
32
+ void Promise.resolve(call(observer)).catch(onFailure);
33
+ }
34
+ catch (error) {
35
+ onFailure(error);
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=run-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-reporter.js","sourceRoot":"","sources":["../../lib/logging/run-reporter.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAU5C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAc,EAAU,EAAE,CAClD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,oDAAoD;AACpD,MAAM,OAAO,WAAW;IACO;IAA7B,YAA6B,KAAuB;QAAvB,UAAK,GAAL,KAAK,CAAkB;IAAG,CAAC;IAExD,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,sDAAsD;IACtD,QAAQ,CAAC,OAAe;QACtB,MAAM,IAAI,GAAG,OAAO;aACjB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QAEb,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAuD;QAC5D,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAEhC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE,CACnC,IAAI,CAAC,QAAQ,CAAC,wBAAwB,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC;YACH,KAAK,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { summariseRun } from './run-summary.util.js';
2
+ export type { RunSummary } from './run-summary.util.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/run/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { summariseRun } from './run-summary.util.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/run/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { UsageMetadata } from '@langchain/core/messages';
2
+ interface MessageLike {
3
+ usage_metadata?: UsageMetadata;
4
+ tool_calls?: {
5
+ name: string;
6
+ }[];
7
+ }
8
+ /** What a run did and cost. */
9
+ export interface RunSummary {
10
+ /** Every tool call the model made, failed and unknown ones included. */
11
+ tools: string[];
12
+ /**
13
+ * Summed over the run's model calls; absent when the provider reports no
14
+ * usage.
15
+ */
16
+ tokens?: {
17
+ input: number;
18
+ output: number;
19
+ total: number;
20
+ };
21
+ }
22
+ /**
23
+ * What a finished run cost, read off the messages it returned.
24
+ *
25
+ * @internal
26
+ * @param messages The messages of the finished run.
27
+ * @returns The tool calls the model made, and the tokens if reported.
28
+ */
29
+ export declare const summariseRun: (messages: readonly MessageLike[]) => RunSummary;
30
+ export {};
31
+ //# sourceMappingURL=run-summary.util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-summary.util.d.ts","sourceRoot":"","sources":["../../lib/run/run-summary.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAG7E,UAAU,WAAW;IACnB,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjC;AAED,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,SAAS,WAAW,EAAE,KAAG,UAwB/D,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { mergeUsageMetadata } from '@langchain/core/messages';
2
+ /**
3
+ * What a finished run cost, read off the messages it returned.
4
+ *
5
+ * @internal
6
+ * @param messages The messages of the finished run.
7
+ * @returns The tool calls the model made, and the tokens if reported.
8
+ */
9
+ export const summariseRun = (messages) => {
10
+ const tools = messages.flatMap((message) => (message.tool_calls ?? []).map((call) => call.name));
11
+ const reported = messages
12
+ .map((message) => message.usage_metadata)
13
+ .filter((usage) => usage !== undefined);
14
+ if (reported.length === 0) {
15
+ return { tools };
16
+ }
17
+ // Seeded with zeros, so a field a provider left out counts as zero.
18
+ const usage = reported.reduce(mergeUsageMetadata, mergeUsageMetadata());
19
+ return {
20
+ tools,
21
+ tokens: {
22
+ input: usage.input_tokens,
23
+ output: usage.output_tokens,
24
+ total: usage.total_tokens,
25
+ },
26
+ };
27
+ };
28
+ //# sourceMappingURL=run-summary.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-summary.util.js","sourceRoot":"","sources":["../../lib/run/run-summary.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAiB,MAAM,0BAA0B,CAAC;AAmB7E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAgC,EAAc,EAAE;IAC3E,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CACzC,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CACpD,CAAC;IAEF,MAAM,QAAQ,GAAG,QAAQ;SACtB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC;SACxC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAE1C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC;IAED,oEAAoE;IACpE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAExE,OAAO;QACL,KAAK;QACL,MAAM,EAAE;YACN,KAAK,EAAE,KAAK,CAAC,YAAY;YACzB,MAAM,EAAE,KAAK,CAAC,aAAa;YAC3B,KAAK,EAAE,KAAK,CAAC,YAAY;SAC1B;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ToolDiscoveryService } from './tool-discovery.service.js';
2
+ export { toolErrors, unknownTools } from './tool-errors.middleware.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ToolDiscoveryService } from './tool-discovery.service.js';
2
+ export { toolErrors, unknownTools } from './tool-errors.middleware.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { DynamicStructuredTool } from 'langchain';
2
+ import { DiscoveryService, MetadataScanner, ModulesContainer } from '@nestjs/core';
3
+ import { ToolModule } from '../interfaces/langchain-module-options.interface.js';
4
+ import { RunReporter } from '../logging/index.js';
5
+ /** Finds the `@Tool()` methods of an agent's tool modules and builds their tools. */
6
+ export declare class ToolDiscoveryService {
7
+ private readonly discoveryService;
8
+ private readonly metadataScanner;
9
+ private readonly modulesContainer;
10
+ constructor(discoveryService: DiscoveryService, metadataScanner: MetadataScanner, modulesContainer: ModulesContainer);
11
+ private modulesInContext;
12
+ /**
13
+ * Every `@Tool()` method of the providers that `modules` host. Adds to
14
+ * `declaring` each module declaring one, accepted or not.
15
+ */
16
+ private toolMethods;
17
+ /** One tool per method, each reporting its calls to `reporter`. */
18
+ private buildTools;
19
+ /**
20
+ * The tools of the modules listed in an agent's `tools` option, each one
21
+ * reporting its calls to `reporter`. Throws a `ToolConfigurationError`
22
+ * listing every problem found: a module that is not imported, imported
23
+ * several times or declaring no tool, a name or a schema that is invalid,
24
+ * two tools sharing a name.
25
+ *
26
+ * Async because an entry may be a `Promise<DynamicModule>`, which Nest's
27
+ * own `imports` accepts.
28
+ */
29
+ getToolsFromModules(entries: ToolModule[], reporter: RunReporter): Promise<DynamicStructuredTool[]>;
30
+ }
31
+ //# sourceMappingURL=tool-discovery.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-discovery.service.d.ts","sourceRoot":"","sources":["../../lib/tools/tool-discovery.service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAMtB,OAAO,EAAE,UAAU,EAAE,MAAM,qDAAqD,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgDlD,qFAAqF;AACrF,qBACa,oBAAoB;IAE7B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAFhB,gBAAgB,EAAE,gBAAgB,EAClC,eAAe,EAAE,eAAe,EAChC,gBAAgB,EAAE,gBAAgB;IAGrD,OAAO,CAAC,gBAAgB;IAUxB;;;OAGG;IACH,OAAO,CAAC,WAAW;IA+CnB,mEAAmE;IACnE,OAAO,CAAC,UAAU;IAYlB;;;;;;;;;OASG;IACG,mBAAmB,CACvB,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,qBAAqB,EAAE,CAAC;CA+BpC"}
@@ -0,0 +1,132 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, Scope } from '@nestjs/common';
11
+ import { DiscoveryService, MetadataScanner, ModulesContainer, } from '@nestjs/core';
12
+ import { ToolConfigurationError } from '../errors/index.js';
13
+ import { toolModuleWithoutTools, toolOnNonSingleton, } from '../errors/messages.js';
14
+ import { buildTool } from './tool.factory.js';
15
+ import { readToolMethod } from './tool-method.util.js';
16
+ import { findDuplicateToolNames } from './tool-name.util.js';
17
+ import { resolveToolModules } from './tool-modules.util.js';
18
+ /**
19
+ * Maps each item, skipping `undefined`. An item that throws adds its message
20
+ * to `problems` rather than stopping the others, so one bad tool does not hide
21
+ * the next.
22
+ */
23
+ const collect = (items, map, problems) => items.flatMap((item) => {
24
+ try {
25
+ const result = map(item);
26
+ return result === undefined ? [] : [result];
27
+ }
28
+ catch (error) {
29
+ problems.push(error instanceof Error ? error.message : String(error));
30
+ return [];
31
+ }
32
+ });
33
+ /**
34
+ * Why a provider is not a singleton, or `undefined` when it is. An agent is
35
+ * one, and a provider built per request or per consumer leaves only an
36
+ * unconstructed placeholder in `instance`. See #127.
37
+ */
38
+ const nonSingletonScope = (wrapper) => {
39
+ // `TRANSIENT` reports a static dependency tree.
40
+ if (wrapper.isTransient) {
41
+ return 'transient';
42
+ }
43
+ if (wrapper.isDependencyTreeStatic()) {
44
+ return undefined;
45
+ }
46
+ return wrapper.scope === Scope.REQUEST ? 'request' : 'request-dependency';
47
+ };
48
+ /** Finds the `@Tool()` methods of an agent's tool modules and builds their tools. */
49
+ let ToolDiscoveryService = class ToolDiscoveryService {
50
+ discoveryService;
51
+ metadataScanner;
52
+ modulesContainer;
53
+ constructor(discoveryService, metadataScanner, modulesContainer) {
54
+ this.discoveryService = discoveryService;
55
+ this.metadataScanner = metadataScanner;
56
+ this.modulesContainer = modulesContainer;
57
+ }
58
+ modulesInContext() {
59
+ const modules = new Map();
60
+ this.modulesContainer.forEach(({ metatype }) => modules.set(metatype, (modules.get(metatype) ?? 0) + 1));
61
+ return modules;
62
+ }
63
+ /**
64
+ * Every `@Tool()` method of the providers that `modules` host. Adds to
65
+ * `declaring` each module declaring one, accepted or not.
66
+ */
67
+ toolMethods(modules, declaring, problems) {
68
+ return this.discoveryService.getProviders().flatMap((wrapper) => {
69
+ const { instance, host } = wrapper;
70
+ // A `useValue` primitive carries no decorator, nor metadata to read.
71
+ if (typeof instance !== 'object' ||
72
+ !instance ||
73
+ !host ||
74
+ !modules.has(host.metatype)) {
75
+ return [];
76
+ }
77
+ const reported = problems.length;
78
+ const methods = collect(this.metadataScanner.getAllMethodNames(Object.getPrototypeOf(instance)), (method) => readToolMethod(instance, method), problems);
79
+ // A method already reported as a problem is one this module declares.
80
+ if (methods.length > 0 || problems.length > reported) {
81
+ declaring.add(host.metatype);
82
+ }
83
+ const scope = nonSingletonScope(wrapper);
84
+ if (scope && methods.length > 0) {
85
+ problems.push(toolOnNonSingleton(instance.constructor.name, scope, methods.map(({ method }) => method)));
86
+ return [];
87
+ }
88
+ return methods;
89
+ });
90
+ }
91
+ /** One tool per method, each reporting its calls to `reporter`. */
92
+ buildTools(methods, reporter, problems) {
93
+ return collect(methods, (method) => ({ tool: buildTool(method, reporter), where: method.where }), problems);
94
+ }
95
+ /**
96
+ * The tools of the modules listed in an agent's `tools` option, each one
97
+ * reporting its calls to `reporter`. Throws a `ToolConfigurationError`
98
+ * listing every problem found: a module that is not imported, imported
99
+ * several times or declaring no tool, a name or a schema that is invalid,
100
+ * two tools sharing a name.
101
+ *
102
+ * Async because an entry may be a `Promise<DynamicModule>`, which Nest's
103
+ * own `imports` accepts.
104
+ */
105
+ async getToolsFromModules(entries, reporter) {
106
+ // By constructor, not `host.name`: two modules may share a class name.
107
+ // See #58.
108
+ const { modules, problems } = await resolveToolModules(entries, this.modulesInContext());
109
+ const declaring = new Set();
110
+ const methods = this.toolMethods(modules, declaring, problems);
111
+ modules.forEach((module) => {
112
+ if (!declaring.has(module)) {
113
+ problems.push(toolModuleWithoutTools(module.name));
114
+ }
115
+ });
116
+ const built = this.buildTools(methods, reporter, problems);
117
+ // Per agent: the same name in two agents is legitimate.
118
+ problems.push(...findDuplicateToolNames(built.map(({ tool, where }) => ({ name: tool.name, where }))));
119
+ if (problems.length > 0) {
120
+ throw new ToolConfigurationError(problems, reporter.agent);
121
+ }
122
+ return built.map(({ tool }) => tool);
123
+ }
124
+ };
125
+ ToolDiscoveryService = __decorate([
126
+ Injectable(),
127
+ __metadata("design:paramtypes", [DiscoveryService,
128
+ MetadataScanner,
129
+ ModulesContainer])
130
+ ], ToolDiscoveryService);
131
+ export { ToolDiscoveryService };
132
+ //# sourceMappingURL=tool-discovery.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-discovery.service.js","sourceRoot":"","sources":["../../lib/tools/tool-discovery.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAQ,MAAM,gBAAgB,CAAC;AAIzD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAc,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;;;GAIG;AACH,MAAM,OAAO,GAAG,CACd,KAAU,EACV,GAA+B,EAC/B,QAAkB,EACb,EAAE,CACP,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,QAAQ,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC,CAAC;AAIL;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,CACxB,OAAwB,EACoC,EAAE;IAC9D,gDAAgD;IAChD,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC;AAC5E,CAAC,CAAC;AAEF,qFAAqF;AAE9E,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ;IACA;IACA;IAHnB,YACmB,gBAAkC,EAClC,eAAgC,EAChC,gBAAkC;QAFlC,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,oBAAe,GAAf,eAAe,CAAiB;QAChC,qBAAgB,GAAhB,gBAAgB,CAAkB;IAClD,CAAC;IAEI,gBAAgB;QACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgB,CAAC;QAExC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAC7C,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CACxD,CAAC;QAEF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,WAAW,CACjB,OAAkB,EAClB,SAAoB,EACpB,QAAkB;QAElB,OAAO,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC9D,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;YAEnC,qEAAqE;YACrE,IACE,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,CAAC,QAAQ;gBACT,CAAC,IAAI;gBACL,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAC3B,CAAC;gBACD,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;YACjC,MAAM,OAAO,GAAG,OAAO,CACrB,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,EACvE,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,EAC5C,QAAQ,CACT,CAAC;YAEF,sEAAsE;YACtE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;gBACrD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAEzC,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChC,QAAQ,CAAC,IAAI,CACX,kBAAkB,CAChB,QAAQ,CAAC,WAAW,CAAC,IAAI,EACzB,KAAK,EACL,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CACpC,CACF,CAAC;gBACF,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,mEAAmE;IAC3D,UAAU,CAChB,OAAqB,EACrB,QAAqB,EACrB,QAAkB;QAElB,OAAO,OAAO,CACZ,OAAO,EACP,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EACxE,QAAQ,CACT,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,mBAAmB,CACvB,OAAqB,EACrB,QAAqB;QAErB,uEAAuE;QACvE,WAAW;QACX,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,kBAAkB,CACpD,OAAO,EACP,IAAI,CAAC,gBAAgB,EAAE,CACxB,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAQ,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAE/D,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACzB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,QAAQ,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACrD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC3D,wDAAwD;QACxD,QAAQ,CAAC,IAAI,CACX,GAAG,sBAAsB,CACvB,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAC7D,CACF,CAAC;QAEF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;CACF,CAAA;AA7HY,oBAAoB;IADhC,UAAU,EAAE;qCAG0B,gBAAgB;QACjB,eAAe;QACd,gBAAgB;GAJ1C,oBAAoB,CA6HhC"}
@@ -0,0 +1,21 @@
1
+ import { RunReporter } from '../logging/index.js';
2
+ /**
3
+ * Turns a failed tool call into the text the model receives, LangChain's own,
4
+ * without the stack (and its server paths) LangChain puts in a schema failure.
5
+ * Every error is answered: past a middleware, LangChain's tool node rethrows
6
+ * any error left unhandled and fails the run. See #176.
7
+ *
8
+ * Also the only place that sees arguments the schema rejects, which never
9
+ * reach the `@Tool` wrapper: they are reported here. See #177.
10
+ *
11
+ * Once langchain-ai/langchainjs#11830 ships, LangChain's own text has no stack
12
+ * and `tool-errors.middleware.spec.ts` fails: the schema text can be left to
13
+ * LangChain, the reporting stays.
14
+ */
15
+ export declare const toolErrors: (reporter: RunReporter) => import("langchain").AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
16
+ /**
17
+ * Reports a call to a tool the agent does not have. LangChain's tool node
18
+ * answers the model itself, without throwing, so `toolErrors` never sees it.
19
+ */
20
+ export declare const unknownTools: (reporter: RunReporter) => import("langchain").AgentMiddleware<undefined, undefined, unknown, readonly (import("@langchain/core/tools").ServerTool | import("@langchain/core/tools").ClientTool)[], readonly []>;
21
+ //# sourceMappingURL=tool-errors.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-errors.middleware.d.ts","sourceRoot":"","sources":["../../lib/tools/tool-errors.middleware.ts"],"names":[],"mappings":"AAMA,OAAO,EAAmB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU,GAAI,UAAU,WAAW,0LAwB5C,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,UAAU,WAAW,0LAgB9C,CAAC"}