@typia/langchain 15.0.1 → 15.1.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.
- package/README.md +23 -14
- package/lib/index.d.cts +30 -21
- package/lib/index.d.mts +30 -21
- package/lib/index.d.ts +30 -21
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1 -0
- package/lib/index.mjs.map +1 -1
- package/lib/internal/LangChainParameterConverter.d.ts +22 -5
- package/lib/internal/LangChainParameterConverter.js +22 -5
- package/lib/internal/LangChainParameterConverter.js.map +1 -1
- package/lib/internal/LangChainParameterConverter.mjs.map +1 -1
- package/lib/internal/LangChainToolsRegistrar.d.ts +25 -0
- package/lib/internal/LangChainToolsRegistrar.js +28 -2
- package/lib/internal/LangChainToolsRegistrar.js.map +1 -1
- package/lib/internal/LangChainToolsRegistrar.mjs.map +1 -1
- package/package.json +6 -5
- package/src/index.ts +31 -21
- package/src/internal/LangChainParameterConverter.ts +22 -5
- package/src/internal/LangChainToolsRegistrar.ts +28 -2
package/README.md
CHANGED
|
@@ -25,32 +25,41 @@ npm install -D ttsc typescript@rc
|
|
|
25
25
|
|
|
26
26
|
### From TypeScript class
|
|
27
27
|
|
|
28
|
+
This example also uses LangChain's agent and OpenAI model packages:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install langchain @langchain/openai
|
|
32
|
+
```
|
|
33
|
+
|
|
28
34
|
```typescript
|
|
29
|
-
import { ChainValues, Runnable } from "@langchain/core";
|
|
30
|
-
import { ChatPromptTemplate } from "@langchain/core/prompts";
|
|
31
|
-
import { DynamicStructuredTool } from "@langchain/core/tools";
|
|
32
35
|
import { ChatOpenAI } from "@langchain/openai";
|
|
33
36
|
import { toLangChainTools } from "@typia/langchain";
|
|
34
|
-
import {
|
|
37
|
+
import { createAgent } from "langchain";
|
|
35
38
|
import typia from "typia";
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
class Calculator {
|
|
41
|
+
/** Add two numbers. */
|
|
42
|
+
add(input: { a: number; b: number }): { value: number } {
|
|
43
|
+
return { value: input.a + input.b };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const tools = toLangChainTools(
|
|
38
48
|
typia.llm.controller<Calculator>("Calculator", new Calculator()),
|
|
39
49
|
);
|
|
40
50
|
|
|
41
|
-
const agent
|
|
42
|
-
|
|
51
|
+
const agent = createAgent({
|
|
52
|
+
model: new ChatOpenAI({ model: "gpt-4o" }),
|
|
43
53
|
tools,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
]),
|
|
54
|
+
systemPrompt: "You are a helpful assistant.",
|
|
55
|
+
});
|
|
56
|
+
const result = await agent.invoke({
|
|
57
|
+
messages: [{ role: "user", content: "What is 10 + 5?" }],
|
|
49
58
|
});
|
|
50
|
-
const executor: AgentExecutor = new AgentExecutor({ agent, tools });
|
|
51
|
-
const result: ChainValues = await executor.invoke({ input: "What is 10 + 5?" });
|
|
52
59
|
```
|
|
53
60
|
|
|
61
|
+
Set `OPENAI_API_KEY` before running the example.
|
|
62
|
+
|
|
54
63
|
### From OpenAPI document
|
|
55
64
|
|
|
56
65
|
```typescript
|
package/lib/index.d.cts
CHANGED
|
@@ -29,38 +29,47 @@ interface ILangChainToolsProps extends ILangChainToolsOptions {
|
|
|
29
29
|
* Converts TypeScript class methods via `typia.llm.controller<Class>()` or
|
|
30
30
|
* OpenAPI operations via `HttpLlm.controller()` to LangChain tools.
|
|
31
31
|
*
|
|
32
|
-
* Every tool call is validated by typia.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Every tool call is validated by typia. Invalid arguments reject the call with
|
|
33
|
+
* LangChain's `ToolInputParsingException`, containing typia's formatted
|
|
34
|
+
* validation errors. The agent must handle that exception to give the model
|
|
35
|
+
* feedback for another attempt. Invocation and output failures are returned as
|
|
36
|
+
* `{ success: false, error }` tool results.
|
|
35
37
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* import { toLangChainTools } from "@typia/langchain";
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { toLangChainTools } from "@typia/langchain";
|
|
40
|
+
* import { initChatModel } from "langchain/chat_models/universal";
|
|
41
|
+
* import typia from "typia";
|
|
41
42
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* }
|
|
43
|
+
* class Calculator {
|
|
44
|
+
* add(input: { a: number; b: number }): { value: number } {
|
|
45
|
+
* return { value: input.a + input.b };
|
|
46
46
|
* }
|
|
47
|
+
* }
|
|
47
48
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
49
|
+
* const controller = typia.llm.controller<Calculator>(
|
|
50
|
+
* "calculator",
|
|
51
|
+
* new Calculator(),
|
|
52
|
+
* );
|
|
53
|
+
* const tools = toLangChainTools(controller);
|
|
53
54
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* const llm = await initChatModel("gpt-4o", { modelProvider: "openai" });
|
|
56
|
+
* const modelWithTools = llm.bindTools(tools);
|
|
57
|
+
* const result = await modelWithTools.invoke("What is 10 + 5?");
|
|
58
|
+
* ```
|
|
58
59
|
*
|
|
59
60
|
* @param input Controller, controller list, or conversion properties
|
|
60
61
|
* @param options Conversion options when `input` is not a properties object
|
|
62
|
+
*
|
|
61
63
|
* @returns Array of LangChain DynamicStructuredTool
|
|
64
|
+
*
|
|
65
|
+
* @evidence contracts/common.md#principled-implementation All overloads normalize to a controller list and prefix before using the same registrar; properties objects retain their own options, and class and HTTP execution remain delegated to their declared controllers.
|
|
66
|
+
* @evidence contracts/common.md#clear-and-simple-design The public overloads express the three accepted input shapes while two private normalization helpers and one registrar keep conversion behavior shared.
|
|
67
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the public LangChain factory through its registrar and typia's validation; normalization does not manufacture controllers, schemas or successful results.
|
|
68
|
+
* @evidence contracts/common.md#meaningful-documentation The API documents input shapes, prefix behavior, class usage and the distinction between argument exceptions and invocation/output failure results; the registrar explains strict-output validation.
|
|
62
69
|
*/
|
|
63
70
|
export declare function toLangChainTools(controller: ILangChainController, options?: ILangChainToolsOptions | undefined): DynamicStructuredTool[];
|
|
71
|
+
/** Converts a controller list with one shared prefix option. */
|
|
64
72
|
export declare function toLangChainTools(controllers: ILangChainController[], options?: ILangChainToolsOptions | undefined): DynamicStructuredTool[];
|
|
73
|
+
/** Converts explicit properties using their embedded prefix option. */
|
|
65
74
|
export declare function toLangChainTools(props: ILangChainToolsProps): DynamicStructuredTool[];
|
|
66
75
|
export {};
|
package/lib/index.d.mts
CHANGED
|
@@ -29,38 +29,47 @@ interface ILangChainToolsProps extends ILangChainToolsOptions {
|
|
|
29
29
|
* Converts TypeScript class methods via `typia.llm.controller<Class>()` or
|
|
30
30
|
* OpenAPI operations via `HttpLlm.controller()` to LangChain tools.
|
|
31
31
|
*
|
|
32
|
-
* Every tool call is validated by typia.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Every tool call is validated by typia. Invalid arguments reject the call with
|
|
33
|
+
* LangChain's `ToolInputParsingException`, containing typia's formatted
|
|
34
|
+
* validation errors. The agent must handle that exception to give the model
|
|
35
|
+
* feedback for another attempt. Invocation and output failures are returned as
|
|
36
|
+
* `{ success: false, error }` tool results.
|
|
35
37
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* import { toLangChainTools } from "@typia/langchain";
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { toLangChainTools } from "@typia/langchain";
|
|
40
|
+
* import { initChatModel } from "langchain/chat_models/universal";
|
|
41
|
+
* import typia from "typia";
|
|
41
42
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* }
|
|
43
|
+
* class Calculator {
|
|
44
|
+
* add(input: { a: number; b: number }): { value: number } {
|
|
45
|
+
* return { value: input.a + input.b };
|
|
46
46
|
* }
|
|
47
|
+
* }
|
|
47
48
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
49
|
+
* const controller = typia.llm.controller<Calculator>(
|
|
50
|
+
* "calculator",
|
|
51
|
+
* new Calculator(),
|
|
52
|
+
* );
|
|
53
|
+
* const tools = toLangChainTools(controller);
|
|
53
54
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* const llm = await initChatModel("gpt-4o", { modelProvider: "openai" });
|
|
56
|
+
* const modelWithTools = llm.bindTools(tools);
|
|
57
|
+
* const result = await modelWithTools.invoke("What is 10 + 5?");
|
|
58
|
+
* ```
|
|
58
59
|
*
|
|
59
60
|
* @param input Controller, controller list, or conversion properties
|
|
60
61
|
* @param options Conversion options when `input` is not a properties object
|
|
62
|
+
*
|
|
61
63
|
* @returns Array of LangChain DynamicStructuredTool
|
|
64
|
+
*
|
|
65
|
+
* @evidence contracts/common.md#principled-implementation All overloads normalize to a controller list and prefix before using the same registrar; properties objects retain their own options, and class and HTTP execution remain delegated to their declared controllers.
|
|
66
|
+
* @evidence contracts/common.md#clear-and-simple-design The public overloads express the three accepted input shapes while two private normalization helpers and one registrar keep conversion behavior shared.
|
|
67
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the public LangChain factory through its registrar and typia's validation; normalization does not manufacture controllers, schemas or successful results.
|
|
68
|
+
* @evidence contracts/common.md#meaningful-documentation The API documents input shapes, prefix behavior, class usage and the distinction between argument exceptions and invocation/output failure results; the registrar explains strict-output validation.
|
|
62
69
|
*/
|
|
63
70
|
export declare function toLangChainTools(controller: ILangChainController, options?: ILangChainToolsOptions | undefined): DynamicStructuredTool[];
|
|
71
|
+
/** Converts a controller list with one shared prefix option. */
|
|
64
72
|
export declare function toLangChainTools(controllers: ILangChainController[], options?: ILangChainToolsOptions | undefined): DynamicStructuredTool[];
|
|
73
|
+
/** Converts explicit properties using their embedded prefix option. */
|
|
65
74
|
export declare function toLangChainTools(props: ILangChainToolsProps): DynamicStructuredTool[];
|
|
66
75
|
export {};
|
package/lib/index.d.ts
CHANGED
|
@@ -29,38 +29,47 @@ interface ILangChainToolsProps extends ILangChainToolsOptions {
|
|
|
29
29
|
* Converts TypeScript class methods via `typia.llm.controller<Class>()` or
|
|
30
30
|
* OpenAPI operations via `HttpLlm.controller()` to LangChain tools.
|
|
31
31
|
*
|
|
32
|
-
* Every tool call is validated by typia.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Every tool call is validated by typia. Invalid arguments reject the call with
|
|
33
|
+
* LangChain's `ToolInputParsingException`, containing typia's formatted
|
|
34
|
+
* validation errors. The agent must handle that exception to give the model
|
|
35
|
+
* feedback for another attempt. Invocation and output failures are returned as
|
|
36
|
+
* `{ success: false, error }` tool results.
|
|
35
37
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* import { toLangChainTools } from "@typia/langchain";
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { toLangChainTools } from "@typia/langchain";
|
|
40
|
+
* import { initChatModel } from "langchain/chat_models/universal";
|
|
41
|
+
* import typia from "typia";
|
|
41
42
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* }
|
|
43
|
+
* class Calculator {
|
|
44
|
+
* add(input: { a: number; b: number }): { value: number } {
|
|
45
|
+
* return { value: input.a + input.b };
|
|
46
46
|
* }
|
|
47
|
+
* }
|
|
47
48
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
49
|
+
* const controller = typia.llm.controller<Calculator>(
|
|
50
|
+
* "calculator",
|
|
51
|
+
* new Calculator(),
|
|
52
|
+
* );
|
|
53
|
+
* const tools = toLangChainTools(controller);
|
|
53
54
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* const llm = await initChatModel("gpt-4o", { modelProvider: "openai" });
|
|
56
|
+
* const modelWithTools = llm.bindTools(tools);
|
|
57
|
+
* const result = await modelWithTools.invoke("What is 10 + 5?");
|
|
58
|
+
* ```
|
|
58
59
|
*
|
|
59
60
|
* @param input Controller, controller list, or conversion properties
|
|
60
61
|
* @param options Conversion options when `input` is not a properties object
|
|
62
|
+
*
|
|
61
63
|
* @returns Array of LangChain DynamicStructuredTool
|
|
64
|
+
*
|
|
65
|
+
* @evidence contracts/common.md#principled-implementation All overloads normalize to a controller list and prefix before using the same registrar; properties objects retain their own options, and class and HTTP execution remain delegated to their declared controllers.
|
|
66
|
+
* @evidence contracts/common.md#clear-and-simple-design The public overloads express the three accepted input shapes while two private normalization helpers and one registrar keep conversion behavior shared.
|
|
67
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the public LangChain factory through its registrar and typia's validation; normalization does not manufacture controllers, schemas or successful results.
|
|
68
|
+
* @evidence contracts/common.md#meaningful-documentation The API documents input shapes, prefix behavior, class usage and the distinction between argument exceptions and invocation/output failure results; the registrar explains strict-output validation.
|
|
62
69
|
*/
|
|
63
70
|
export declare function toLangChainTools(controller: ILangChainController, options?: ILangChainToolsOptions | undefined): DynamicStructuredTool[];
|
|
71
|
+
/** Converts a controller list with one shared prefix option. */
|
|
64
72
|
export declare function toLangChainTools(controllers: ILangChainController[], options?: ILangChainToolsOptions | undefined): DynamicStructuredTool[];
|
|
73
|
+
/** Converts explicit properties using their embedded prefix option. */
|
|
65
74
|
export declare function toLangChainTools(props: ILangChainToolsProps): DynamicStructuredTool[];
|
|
66
75
|
export {};
|
package/lib/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toLangChainTools = toLangChainTools;
|
|
4
4
|
const LangChainToolsRegistrar_1 = require("./internal/LangChainToolsRegistrar");
|
|
5
|
+
/** Normalizes the supported call forms before registration. */
|
|
5
6
|
function toLangChainTools(input, options) {
|
|
6
7
|
return LangChainToolsRegistrar_1.LangChainToolsRegistrar.convert(normalizeLangChainToolsProps(input, options));
|
|
7
8
|
}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAGA,gFAA6E;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAGA,gFAA6E;AAqF7E,+DAA+D;AAC/D,0BACE,KAA2E,EAC3E,OAA4C;IAE5C,OAAO,iDAAuB,CAAC,OAAO,CACpC,4BAA4B,CAAC,KAAK,EAAE,OAAO,CAAC,CAC7C,CAAC;AACJ,CAAC;AAED,MAAM,4BAA4B,GAAG,CACnC,KAA2E,EAC3E,OAA4C,EACtB,EAAE;IACxB,IAAI,qBAAqB,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACnD,MAAM,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM;KACxB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAC5B,KAA2E,EAC5C,EAAE,CACjC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK;IAC9B,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,aAAa,IAAI,KAAK,CAAC"}
|
package/lib/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LangChainToolsRegistrar } from "./internal/LangChainToolsRegistrar.mjs";
|
|
2
2
|
//#region src/index.ts
|
|
3
|
+
/** Normalizes the supported call forms before registration. */
|
|
3
4
|
function toLangChainTools(input, options) {
|
|
4
5
|
return LangChainToolsRegistrar.convert(normalizeLangChainToolsProps(input, options));
|
|
5
6
|
}
|
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport { IHttpLlmController, ILlmController } from \"@typia/interface\";\n\nimport { LangChainToolsRegistrar } from \"./internal/LangChainToolsRegistrar\";\n\ntype ILangChainController = ILlmController | IHttpLlmController;\n\ninterface ILangChainToolsOptions {\n /**\n * Whether to add controller name as prefix to tool names.\n *\n * If `true`, tool names become `{controllerName}_{methodName}`. If `false`,\n * tool names are just `{methodName}`.\n *\n * @default false\n */\n prefix?: boolean | undefined;\n}\n\ninterface ILangChainToolsProps extends ILangChainToolsOptions {\n /**\n * List of controllers to convert to LangChain tools.\n *\n * - {@link ILlmController}: from `typia.llm.controller<Class>()`, converts all\n * methods of the class to tools\n * - {@link IHttpLlmController}: from `HttpLlm.controller()`, converts all\n * operations from OpenAPI document to tools\n */\n controllers: ILangChainController[];\n}\n\n/**\n * Convert typia controllers to LangChain tools.\n *\n * Converts TypeScript class methods via `typia.llm.controller<Class>()` or\n * OpenAPI operations via `HttpLlm.controller()` to LangChain tools.\n *\n * Every tool call is validated by typia.
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport { IHttpLlmController, ILlmController } from \"@typia/interface\";\n\nimport { LangChainToolsRegistrar } from \"./internal/LangChainToolsRegistrar\";\n\ntype ILangChainController = ILlmController | IHttpLlmController;\n\ninterface ILangChainToolsOptions {\n /**\n * Whether to add controller name as prefix to tool names.\n *\n * If `true`, tool names become `{controllerName}_{methodName}`. If `false`,\n * tool names are just `{methodName}`.\n *\n * @default false\n */\n prefix?: boolean | undefined;\n}\n\ninterface ILangChainToolsProps extends ILangChainToolsOptions {\n /**\n * List of controllers to convert to LangChain tools.\n *\n * - {@link ILlmController}: from `typia.llm.controller<Class>()`, converts all\n * methods of the class to tools\n * - {@link IHttpLlmController}: from `HttpLlm.controller()`, converts all\n * operations from OpenAPI document to tools\n */\n controllers: ILangChainController[];\n}\n\n/**\n * Convert typia controllers to LangChain tools.\n *\n * Converts TypeScript class methods via `typia.llm.controller<Class>()` or\n * OpenAPI operations via `HttpLlm.controller()` to LangChain tools.\n *\n * Every tool call is validated by typia. Invalid arguments reject the call with\n * LangChain's `ToolInputParsingException`, containing typia's formatted\n * validation errors. The agent must handle that exception to give the model\n * feedback for another attempt. Invocation and output failures are returned as\n * `{ success: false, error }` tool results.\n *\n * ```typescript\n * import { toLangChainTools } from \"@typia/langchain\";\n * import { initChatModel } from \"langchain/chat_models/universal\";\n * import typia from \"typia\";\n *\n * class Calculator {\n * add(input: { a: number; b: number }): { value: number } {\n * return { value: input.a + input.b };\n * }\n * }\n *\n * const controller = typia.llm.controller<Calculator>(\n * \"calculator\",\n * new Calculator(),\n * );\n * const tools = toLangChainTools(controller);\n *\n * const llm = await initChatModel(\"gpt-4o\", { modelProvider: \"openai\" });\n * const modelWithTools = llm.bindTools(tools);\n * const result = await modelWithTools.invoke(\"What is 10 + 5?\");\n * ```\n *\n * @param input Controller, controller list, or conversion properties\n * @param options Conversion options when `input` is not a properties object\n *\n * @returns Array of LangChain DynamicStructuredTool\n *\n * @evidence contracts/common.md#principled-implementation All overloads normalize to a controller list and prefix before using the same registrar; properties objects retain their own options, and class and HTTP execution remain delegated to their declared controllers.\n * @evidence contracts/common.md#clear-and-simple-design The public overloads express the three accepted input shapes while two private normalization helpers and one registrar keep conversion behavior shared.\n * @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the public LangChain factory through its registrar and typia's validation; normalization does not manufacture controllers, schemas or successful results.\n * @evidence contracts/common.md#meaningful-documentation The API documents input shapes, prefix behavior, class usage and the distinction between argument exceptions and invocation/output failure results; the registrar explains strict-output validation.\n */\nexport function toLangChainTools(\n controller: ILangChainController,\n options?: ILangChainToolsOptions | undefined,\n): DynamicStructuredTool[];\n/** Converts a controller list with one shared prefix option. */\nexport function toLangChainTools(\n controllers: ILangChainController[],\n options?: ILangChainToolsOptions | undefined,\n): DynamicStructuredTool[];\n/** Converts explicit properties using their embedded prefix option. */\nexport function toLangChainTools(\n props: ILangChainToolsProps,\n): DynamicStructuredTool[];\n/** Normalizes the supported call forms before registration. */\nexport function toLangChainTools(\n input: ILangChainController | ILangChainController[] | ILangChainToolsProps,\n options?: ILangChainToolsOptions | undefined,\n): DynamicStructuredTool[] {\n return LangChainToolsRegistrar.convert(\n normalizeLangChainToolsProps(input, options),\n );\n}\n\nconst normalizeLangChainToolsProps = (\n input: ILangChainController | ILangChainController[] | ILangChainToolsProps,\n options?: ILangChainToolsOptions | undefined,\n): ILangChainToolsProps => {\n if (isLangChainToolsProps(input)) return input;\n return {\n controllers: Array.isArray(input) ? input : [input],\n prefix: options?.prefix,\n };\n};\n\nconst isLangChainToolsProps = (\n input: ILangChainController | ILangChainController[] | ILangChainToolsProps,\n): input is ILangChainToolsProps =>\n Array.isArray(input) === false &&\n typeof input === \"object\" &&\n input !== null &&\n \"controllers\" in input;\n"],"mappings":";;;AAyFA,SAAgB,iBACd,OACA,SACyB;CACzB,OAAO,wBAAwB,QAC7B,6BAA6B,OAAO,OAAO,CAC7C;AACF;AAEA,MAAM,gCACJ,OACA,YACyB;CACzB,IAAI,sBAAsB,KAAK,GAAG,OAAO;CACzC,OAAO;EACL,aAAa,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;EAClD,QAAQ,SAAS;CACnB;AACF;AAEA,MAAM,yBACJ,UAEA,MAAM,QAAQ,KAAK,MAAM,SACzB,OAAO,UAAU,YACjB,UAAU,QACV,iBAAiB"}
|
|
@@ -14,11 +14,11 @@ import { IHttpLlmFunction, ILlmFunction } from "@typia/interface";
|
|
|
14
14
|
*
|
|
15
15
|
* Standard JSON Schema separates the two roles. It carries a model-facing
|
|
16
16
|
* schema under `~standard.jsonSchema` and, by declaring no
|
|
17
|
-
* `~standard.validate`, no
|
|
18
|
-
* the
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* byte for byte.
|
|
17
|
+
* `~standard.validate`, no Standard Schema validator. LangChain's JSON Schema
|
|
18
|
+
* precheck sees the carrier rather than its nested parameter constraints, so
|
|
19
|
+
* parameter validation stays with `LlmJson.validateArguments` in the tool body.
|
|
20
|
+
* LangChain reads the model-facing schema back through its own `toJsonSchema`,
|
|
21
|
+
* so the model sees the same parameters document as before, byte for byte.
|
|
22
22
|
*
|
|
23
23
|
* `@typia/vercel` states the same contract to the AI SDK through
|
|
24
24
|
* `jsonSchema()`, whose `validate` is likewise left undefined so that
|
|
@@ -30,8 +30,25 @@ import { IHttpLlmFunction, ILlmFunction } from "@typia/interface";
|
|
|
30
30
|
* and would advertise _that_ to the model in place of the parameters — and
|
|
31
31
|
* `StandardJSONSchemaV1` only exists from `@standard-schema/spec@1.1.0`.
|
|
32
32
|
*
|
|
33
|
+
* @evidence contracts/common.md#principled-implementation The public Standard JSON Schema carrier exposes the reflected parameters through input/output callbacks while carrying no top-level parameter constraints or Standard Schema validator; the SDK precheck therefore leaves parameter coercion and correctable failures to LlmJson.
|
|
34
|
+
* @evidence contracts/common.md#clear-and-simple-design One converter owns the framework schema carrier, with the unchanged schema callback shared by both directions; execution validation stays in the registrar.
|
|
35
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the documented Standard JSON Schema extension and supported dependency floors instead of replacing LangChain internals or accepting raw data through a patched validator.
|
|
36
|
+
* @evidence contracts/common.md#meaningful-documentation The namespace explains the two schema roles, the validation trap avoided through the public extension, the Vercel equivalent and both required dependency floors with their consequences.
|
|
37
|
+
*
|
|
33
38
|
* @see https://github.com/standard-schema/standard-schema
|
|
34
39
|
*/
|
|
35
40
|
export declare namespace LangChainParameterConverter {
|
|
41
|
+
/**
|
|
42
|
+
* Returns a schema-only Standard JSON Schema carrier for one function.
|
|
43
|
+
*
|
|
44
|
+
* Input and output advertise the same required final argument shape; the
|
|
45
|
+
* registrar owns coercion, so the carrier deliberately has no Standard Schema
|
|
46
|
+
* validator and carries no top-level JSON Schema constraints.
|
|
47
|
+
*
|
|
48
|
+
* @evidence contracts/common.md#principled-implementation Both JSON Schema callbacks return func.parameters because coercion changes values rather than the required final shape; a carrier without top-level parameter constraints or a Standard Schema validator preserves the registrar's argument handling.
|
|
49
|
+
* @evidence contracts/common.md#clear-and-simple-design One shared callback and one standard carrier express the two equivalent schema directions without duplicating schema conversion or runtime checking.
|
|
50
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The returned version/vendor/jsonSchema fields implement Standard JSON Schema through its public contract; the function does not mutate LangChain or specialize known methods.
|
|
51
|
+
* @evidence contracts/common.md#meaningful-documentation The function comment explains shape equivalence and the validation owner, while the namespace supplies the framework semantics and supported-version rationale.
|
|
52
|
+
*/
|
|
36
53
|
const convert: (func: ILlmFunction | IHttpLlmFunction) => StandardJSONSchemaV1;
|
|
37
54
|
}
|
|
@@ -15,11 +15,11 @@ exports.LangChainParameterConverter = void 0;
|
|
|
15
15
|
*
|
|
16
16
|
* Standard JSON Schema separates the two roles. It carries a model-facing
|
|
17
17
|
* schema under `~standard.jsonSchema` and, by declaring no
|
|
18
|
-
* `~standard.validate`, no
|
|
19
|
-
* the
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* byte for byte.
|
|
18
|
+
* `~standard.validate`, no Standard Schema validator. LangChain's JSON Schema
|
|
19
|
+
* precheck sees the carrier rather than its nested parameter constraints, so
|
|
20
|
+
* parameter validation stays with `LlmJson.validateArguments` in the tool body.
|
|
21
|
+
* LangChain reads the model-facing schema back through its own `toJsonSchema`,
|
|
22
|
+
* so the model sees the same parameters document as before, byte for byte.
|
|
23
23
|
*
|
|
24
24
|
* `@typia/vercel` states the same contract to the AI SDK through
|
|
25
25
|
* `jsonSchema()`, whose `validate` is likewise left undefined so that
|
|
@@ -31,10 +31,27 @@ exports.LangChainParameterConverter = void 0;
|
|
|
31
31
|
* and would advertise _that_ to the model in place of the parameters — and
|
|
32
32
|
* `StandardJSONSchemaV1` only exists from `@standard-schema/spec@1.1.0`.
|
|
33
33
|
*
|
|
34
|
+
* @evidence contracts/common.md#principled-implementation The public Standard JSON Schema carrier exposes the reflected parameters through input/output callbacks while carrying no top-level parameter constraints or Standard Schema validator; the SDK precheck therefore leaves parameter coercion and correctable failures to LlmJson.
|
|
35
|
+
* @evidence contracts/common.md#clear-and-simple-design One converter owns the framework schema carrier, with the unchanged schema callback shared by both directions; execution validation stays in the registrar.
|
|
36
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the documented Standard JSON Schema extension and supported dependency floors instead of replacing LangChain internals or accepting raw data through a patched validator.
|
|
37
|
+
* @evidence contracts/common.md#meaningful-documentation The namespace explains the two schema roles, the validation trap avoided through the public extension, the Vercel equivalent and both required dependency floors with their consequences.
|
|
38
|
+
*
|
|
34
39
|
* @see https://github.com/standard-schema/standard-schema
|
|
35
40
|
*/
|
|
36
41
|
var LangChainParameterConverter;
|
|
37
42
|
(function (LangChainParameterConverter) {
|
|
43
|
+
/**
|
|
44
|
+
* Returns a schema-only Standard JSON Schema carrier for one function.
|
|
45
|
+
*
|
|
46
|
+
* Input and output advertise the same required final argument shape; the
|
|
47
|
+
* registrar owns coercion, so the carrier deliberately has no Standard Schema
|
|
48
|
+
* validator and carries no top-level JSON Schema constraints.
|
|
49
|
+
*
|
|
50
|
+
* @evidence contracts/common.md#principled-implementation Both JSON Schema callbacks return func.parameters because coercion changes values rather than the required final shape; a carrier without top-level parameter constraints or a Standard Schema validator preserves the registrar's argument handling.
|
|
51
|
+
* @evidence contracts/common.md#clear-and-simple-design One shared callback and one standard carrier express the two equivalent schema directions without duplicating schema conversion or runtime checking.
|
|
52
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The returned version/vendor/jsonSchema fields implement Standard JSON Schema through its public contract; the function does not mutate LangChain or specialize known methods.
|
|
53
|
+
* @evidence contracts/common.md#meaningful-documentation The function comment explains shape equivalence and the validation owner, while the namespace supplies the framework semantics and supported-version rationale.
|
|
54
|
+
*/
|
|
38
55
|
LangChainParameterConverter.convert = (func) => {
|
|
39
56
|
// Coercion never changes the shape a value must end up in, so the input and
|
|
40
57
|
// output schemas are the same document.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LangChainParameterConverter.js","sourceRoot":"","sources":["../../src/internal/LangChainParameterConverter.ts"],"names":[],"mappings":";;;AAGA
|
|
1
|
+
{"version":3,"file":"LangChainParameterConverter.js","sourceRoot":"","sources":["../../src/internal/LangChainParameterConverter.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,IAAiB,2BAA2B,CA+B3C;AA/BD,WAAiB,2BAA2B;IAC1C;;;;;;;;;;;OAWG;IACU,mCAAO,GAAG,CACrB,IAAqC,EACf,EAAE;QACxB,4EAA4E;QAC5E,wCAAwC;QACxC,MAAM,UAAU,GAAG,GAA4B,EAAE,CAC/C,IAAI,CAAC,UAAgD,CAAC;QACxD,OAAO;YACL,WAAW,EAAE;gBACX,OAAO,EAAE,CAAC;gBACV,MAAM,EAAE,OAAO;gBACf,UAAU,EAAE;oBACV,KAAK,EAAE,UAAU;oBACjB,MAAM,EAAE,UAAU;iBACnB;aACF;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC,EA/BgB,2BAA2B,aAA3B,2BAA2B,GAA3B,2BAA2B,QA+B3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LangChainParameterConverter.mjs","names":[],"sources":["../../src/internal/LangChainParameterConverter.ts"],"sourcesContent":["import { StandardJSONSchemaV1 } from \"@standard-schema/spec\";\nimport { IHttpLlmFunction, ILlmFunction } from \"@typia/interface\";\n\n/**\n * A Standard JSON Schema view of one typia function's parameters.\n *\n * LangChain's tool `schema` fills two roles at once:\n * `toJsonSchema(tool.schema)` turns it into the parameters the model is shown,\n * and `StructuredTool.call` validates incoming arguments against it before the\n * tool body runs. Handing over a bare `ILlmSchema.IParameters` fills the first\n * role but forfeits the second — LangChain validates it with\n * `@cfworker/json-schema`, which rejects what typia would have coerced and\n * reports the failure in its own words, so typia's coercion and its correctable\n * feedback both become unreachable.\n *\n * Standard JSON Schema separates the two roles. It carries a model-facing\n * schema under `~standard.jsonSchema` and, by declaring no\n * `~standard.validate`, no
|
|
1
|
+
{"version":3,"file":"LangChainParameterConverter.mjs","names":[],"sources":["../../src/internal/LangChainParameterConverter.ts"],"sourcesContent":["import { StandardJSONSchemaV1 } from \"@standard-schema/spec\";\nimport { IHttpLlmFunction, ILlmFunction } from \"@typia/interface\";\n\n/**\n * A Standard JSON Schema view of one typia function's parameters.\n *\n * LangChain's tool `schema` fills two roles at once:\n * `toJsonSchema(tool.schema)` turns it into the parameters the model is shown,\n * and `StructuredTool.call` validates incoming arguments against it before the\n * tool body runs. Handing over a bare `ILlmSchema.IParameters` fills the first\n * role but forfeits the second — LangChain validates it with\n * `@cfworker/json-schema`, which rejects what typia would have coerced and\n * reports the failure in its own words, so typia's coercion and its correctable\n * feedback both become unreachable.\n *\n * Standard JSON Schema separates the two roles. It carries a model-facing\n * schema under `~standard.jsonSchema` and, by declaring no\n * `~standard.validate`, no Standard Schema validator. LangChain's JSON Schema\n * precheck sees the carrier rather than its nested parameter constraints, so\n * parameter validation stays with `LlmJson.validateArguments` in the tool body.\n * LangChain reads the model-facing schema back through its own `toJsonSchema`,\n * so the model sees the same parameters document as before, byte for byte.\n *\n * `@typia/vercel` states the same contract to the AI SDK through\n * `jsonSchema()`, whose `validate` is likewise left undefined so that\n * `safeValidateTypes` short-circuits its own validation.\n *\n * Two version floors hold this together, and both are pinned in the package\n * manifest. `toJsonSchema` only reads `~standard.jsonSchema` from\n * `@langchain/core@1.1.30` onwards — older versions return the wrapper itself\n * and would advertise _that_ to the model in place of the parameters — and\n * `StandardJSONSchemaV1` only exists from `@standard-schema/spec@1.1.0`.\n *\n * @evidence contracts/common.md#principled-implementation The public Standard JSON Schema carrier exposes the reflected parameters through input/output callbacks while carrying no top-level parameter constraints or Standard Schema validator; the SDK precheck therefore leaves parameter coercion and correctable failures to LlmJson.\n * @evidence contracts/common.md#clear-and-simple-design One converter owns the framework schema carrier, with the unchanged schema callback shared by both directions; execution validation stays in the registrar.\n * @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the documented Standard JSON Schema extension and supported dependency floors instead of replacing LangChain internals or accepting raw data through a patched validator.\n * @evidence contracts/common.md#meaningful-documentation The namespace explains the two schema roles, the validation trap avoided through the public extension, the Vercel equivalent and both required dependency floors with their consequences.\n *\n * @see https://github.com/standard-schema/standard-schema\n */\nexport namespace LangChainParameterConverter {\n /**\n * Returns a schema-only Standard JSON Schema carrier for one function.\n *\n * Input and output advertise the same required final argument shape; the\n * registrar owns coercion, so the carrier deliberately has no Standard Schema\n * validator and carries no top-level JSON Schema constraints.\n *\n * @evidence contracts/common.md#principled-implementation Both JSON Schema callbacks return func.parameters because coercion changes values rather than the required final shape; a carrier without top-level parameter constraints or a Standard Schema validator preserves the registrar's argument handling.\n * @evidence contracts/common.md#clear-and-simple-design One shared callback and one standard carrier express the two equivalent schema directions without duplicating schema conversion or runtime checking.\n * @evidence contracts/common.md#prohibited-implementation-shortcuts The returned version/vendor/jsonSchema fields implement Standard JSON Schema through its public contract; the function does not mutate LangChain or specialize known methods.\n * @evidence contracts/common.md#meaningful-documentation The function comment explains shape equivalence and the validation owner, while the namespace supplies the framework semantics and supported-version rationale.\n */\n export const convert = (\n func: ILlmFunction | IHttpLlmFunction,\n ): StandardJSONSchemaV1 => {\n // Coercion never changes the shape a value must end up in, so the input and\n // output schemas are the same document.\n const jsonSchema = (): Record<string, unknown> =>\n func.parameters as unknown as Record<string, unknown>;\n return {\n \"~standard\": {\n version: 1,\n vendor: \"typia\",\n jsonSchema: {\n input: jsonSchema,\n output: jsonSchema,\n },\n },\n };\n };\n}\n"],"mappings":";AAwCO,IAAA;;yCAcH,SACyB;EAGzB,MAAM,mBACJ,KAAK;EACP,OAAO,EACL,aAAa;GACX,SAAS;GACT,QAAQ;GACR,YAAY;IACV,OAAO;IACP,QAAQ;GACV;EACF,EACF;CACF;GACD,gCAAA,8BAAA,CAAA,EAAD"}
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { DynamicStructuredTool } from "@langchain/core/tools";
|
|
2
2
|
import { IHttpLlmController, ILlmController } from "@typia/interface";
|
|
3
|
+
/**
|
|
4
|
+
* Registers class and HTTP operations as validated LangChain tools.
|
|
5
|
+
*
|
|
6
|
+
* Parameter validation precedes invocation. Output validation uses the source
|
|
7
|
+
* application's strictness config, and invocation failures become tool
|
|
8
|
+
* results.
|
|
9
|
+
*
|
|
10
|
+
* @evidence contracts/common.md#principled-implementation The registrar preserves class receivers, delegates HTTP transport to the controller or HttpLlm, and validates declared outputs with their application's config before returning model-visible data.
|
|
11
|
+
* @evidence contracts/common.md#clear-and-simple-design Name checking, protocol-specific invocation and shared tool construction have separate helpers; both protocols share the argument and output validation path.
|
|
12
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It uses LangChain's public tool factory and Standard JSON Schema carrier without dependency patches; failed argument validation prevents execution and output failures remain visible.
|
|
13
|
+
* @evidence contracts/common.md#meaningful-documentation This namespace describes validation order and error ownership; createTool explains the strict-schema inversion and the public JSON Schema carrier cast.
|
|
14
|
+
*/
|
|
3
15
|
export declare namespace LangChainToolsRegistrar {
|
|
16
|
+
/**
|
|
17
|
+
* Converts controllers in declaration order, rejecting cross-controller names
|
|
18
|
+
* that collide after applying the optional prefix.
|
|
19
|
+
*
|
|
20
|
+
* One application's function names are assumed unique, as established by its
|
|
21
|
+
* controller builder. Every class method must exist before its tool is
|
|
22
|
+
* added.
|
|
23
|
+
*
|
|
24
|
+
* @evidence contracts/common.md#principled-implementation A Map detects collisions for multiple controllers using the exact final tool name; class methods retain their receiver and HTTP operations retain their application and connection.
|
|
25
|
+
* @evidence contracts/common.md#clear-and-simple-design One traversal checks final names before the protocol-specific registration traversal, while createTool owns the validation and result envelope common to both protocols.
|
|
26
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It neither invents schemas nor bypasses typia validation: arguments are validated before transport, declared outputs are checked, and unknown methods fail conversion instead of creating a broken callback.
|
|
27
|
+
* @evidence contracts/common.md#meaningful-documentation The comment records ordering, prefix collision semantics and the within-application uniqueness premise; private helpers explain result validation and schema conversion ownership.
|
|
28
|
+
*/
|
|
4
29
|
const convert: (props: {
|
|
5
30
|
controllers: Array<ILlmController | IHttpLlmController>;
|
|
6
31
|
prefix?: boolean | undefined;
|
|
@@ -13,8 +13,33 @@ exports.LangChainToolsRegistrar = void 0;
|
|
|
13
13
|
const tools_1 = require("@langchain/core/tools");
|
|
14
14
|
const utils_1 = require("@typia/utils");
|
|
15
15
|
const LangChainParameterConverter_1 = require("./LangChainParameterConverter");
|
|
16
|
+
/**
|
|
17
|
+
* Registers class and HTTP operations as validated LangChain tools.
|
|
18
|
+
*
|
|
19
|
+
* Parameter validation precedes invocation. Output validation uses the source
|
|
20
|
+
* application's strictness config, and invocation failures become tool
|
|
21
|
+
* results.
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation The registrar preserves class receivers, delegates HTTP transport to the controller or HttpLlm, and validates declared outputs with their application's config before returning model-visible data.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design Name checking, protocol-specific invocation and shared tool construction have separate helpers; both protocols share the argument and output validation path.
|
|
25
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It uses LangChain's public tool factory and Standard JSON Schema carrier without dependency patches; failed argument validation prevents execution and output failures remain visible.
|
|
26
|
+
* @evidence contracts/common.md#meaningful-documentation This namespace describes validation order and error ownership; createTool explains the strict-schema inversion and the public JSON Schema carrier cast.
|
|
27
|
+
*/
|
|
16
28
|
var LangChainToolsRegistrar;
|
|
17
29
|
(function (LangChainToolsRegistrar) {
|
|
30
|
+
/**
|
|
31
|
+
* Converts controllers in declaration order, rejecting cross-controller names
|
|
32
|
+
* that collide after applying the optional prefix.
|
|
33
|
+
*
|
|
34
|
+
* One application's function names are assumed unique, as established by its
|
|
35
|
+
* controller builder. Every class method must exist before its tool is
|
|
36
|
+
* added.
|
|
37
|
+
*
|
|
38
|
+
* @evidence contracts/common.md#principled-implementation A Map detects collisions for multiple controllers using the exact final tool name; class methods retain their receiver and HTTP operations retain their application and connection.
|
|
39
|
+
* @evidence contracts/common.md#clear-and-simple-design One traversal checks final names before the protocol-specific registration traversal, while createTool owns the validation and result envelope common to both protocols.
|
|
40
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It neither invents schemas nor bypasses typia validation: arguments are validated before transport, declared outputs are checked, and unknown methods fail conversion instead of creating a broken callback.
|
|
41
|
+
* @evidence contracts/common.md#meaningful-documentation The comment records ordering, prefix collision semantics and the within-application uniqueness premise; private helpers explain result validation and schema conversion ownership.
|
|
42
|
+
*/
|
|
18
43
|
LangChainToolsRegistrar.convert = (props) => {
|
|
19
44
|
var _a;
|
|
20
45
|
const prefix = (_a = props.prefix) !== null && _a !== void 0 ? _a : false;
|
|
@@ -146,8 +171,9 @@ var LangChainToolsRegistrar;
|
|
|
146
171
|
}), {
|
|
147
172
|
name: entry.name,
|
|
148
173
|
description: (_a = entry.function.description) !== null && _a !== void 0 ? _a : "",
|
|
149
|
-
//
|
|
150
|
-
//
|
|
174
|
+
// The carrier exposes the model-facing schema without top-level JSON
|
|
175
|
+
// Schema constraints or a Standard Schema validator, so argument
|
|
176
|
+
// constraints and coercion stay with the step above; see
|
|
151
177
|
// `LangChainParameterConverter`. The cast is needed because `tool()`
|
|
152
178
|
// still types `schema` as Zod-or-JSON-Schema, even though the
|
|
153
179
|
// `toJsonSchema` it reads that schema back with accepts Standard JSON
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LangChainToolsRegistrar.js","sourceRoot":"","sources":["../../src/internal/LangChainToolsRegistrar.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iDAI+B;AAU/B,wCAAgD;AAEhD,+EAA4E;AAE5E,IAAiB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"LangChainToolsRegistrar.js","sourceRoot":"","sources":["../../src/internal/LangChainToolsRegistrar.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LangChainToolsRegistrar.mjs","names":[],"sources":["../../src/internal/LangChainToolsRegistrar.ts"],"sourcesContent":["import {\n DynamicStructuredTool,\n ToolInputParsingException,\n tool,\n} from \"@langchain/core/tools\";\nimport type { JSONSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n IHttpLlmController,\n IHttpLlmFunction,\n ILlmController,\n ILlmFunction,\n ILlmSchema,\n IValidation,\n} from \"@typia/interface\";\nimport { HttpLlm, LlmJson } from \"@typia/utils\";\n\nimport { LangChainParameterConverter } from \"./LangChainParameterConverter\";\n\nexport namespace LangChainToolsRegistrar {\n export const convert = (props: {\n controllers: Array<ILlmController | IHttpLlmController>;\n prefix?: boolean | undefined;\n }): DynamicStructuredTool[] => {\n const prefix: boolean = props.prefix ?? false;\n const tools: DynamicStructuredTool[] = [];\n\n // check duplicate tool names\n if (props.controllers.length >= 2) {\n const names: Map<string, string> = new Map();\n const duplicates: string[] = [];\n for (const controller of props.controllers) {\n for (const func of controller.application.functions) {\n const toolName: string = getToolName(\n controller.name,\n func.name,\n prefix,\n );\n const existing: string | undefined = names.get(toolName);\n const origin: string = `${controller.protocol} controller \"${controller.name}\" function \"${func.name}\"`;\n if (existing !== undefined)\n duplicates.push(\n `\"${toolName}\" from ${origin} (conflicts with ${existing})`,\n );\n else names.set(toolName, origin);\n }\n }\n if (duplicates.length > 0)\n throw new Error(\n `Duplicate tool names found:\\n - ${duplicates.join(\"\\n - \")}`,\n );\n }\n\n // convert controllers to tools\n for (const controller of props.controllers) {\n if (controller.protocol === \"class\") {\n convertClassController(tools, controller, prefix);\n } else {\n convertHttpController(tools, controller, prefix);\n }\n }\n\n return tools;\n };\n\n const convertClassController = (\n tools: DynamicStructuredTool[],\n controller: ILlmController,\n prefix: boolean,\n ): void => {\n const execute: Record<string, unknown> = controller.execute;\n\n for (const func of controller.application.functions) {\n const toolName: string = getToolName(controller.name, func.name, prefix);\n\n const method: unknown = execute[func.name];\n if (typeof method !== \"function\") {\n throw new Error(\n `Method \"${func.name}\" not found on controller \"${controller.name}\"`,\n );\n }\n\n tools.push(\n createTool({\n name: toolName,\n function: func,\n config: controller.application.config,\n execute: async (args: unknown) => method.call(execute, args),\n }),\n );\n }\n };\n\n const convertHttpController = (\n tools: DynamicStructuredTool[],\n controller: IHttpLlmController,\n prefix: boolean,\n ): void => {\n const application = controller.application;\n const connection = controller.connection;\n\n for (const func of application.functions) {\n const toolName: string = getToolName(controller.name, func.name, prefix);\n\n tools.push(\n createTool({\n name: toolName,\n function: func,\n config: application.config,\n execute: async (args: unknown) => {\n if (controller.execute !== undefined) {\n const response = await controller.execute({\n connection,\n application,\n function: func,\n arguments: args as object,\n });\n return response.body;\n }\n return HttpLlm.execute({\n application,\n function: func,\n connection,\n input: args as object,\n });\n },\n }),\n );\n }\n };\n\n const createTool = (entry: {\n name: string;\n function: ILlmFunction | IHttpLlmFunction;\n config: ILlmSchema.IConfig;\n execute: (args: unknown) => Promise<unknown>;\n }): DynamicStructuredTool => {\n // A declared return type is a promise to the model, so a result that breaks\n // it is reported rather than delivered. `@typia/mcp` and `@typia/vercel`\n // already refuse one; this tool consulted `output` for its existence alone,\n // so a method returning nothing was reported while a method returning the\n // wrong shape was not (#2302).\n //\n // The application's own config decides how the schema is read back: a\n // strict application carries its constraints as description tags instead of\n // keywords, and only that config tells the inverter to read them.\n const validateOutput:\n | ((output: unknown) => IValidation<unknown>)\n | undefined =\n entry.function.output === undefined\n ? undefined\n : LlmJson.validate(entry.function.output, true, entry.config);\n return tool(\n async (args: unknown): Promise<unknown> => {\n const valid: IValidation<unknown> = LlmJson.validateArguments(\n entry.function,\n args ?? {},\n );\n if (valid.success === false)\n throw new ToolInputParsingException(\n `Type errors in \"${entry.name}\" arguments:\\n\\n` +\n LlmJson.stringify(valid),\n JSON.stringify(args ?? {}),\n );\n try {\n const result: unknown = await entry.execute(valid.data);\n if (result === undefined) {\n return validateOutput === undefined\n ? ({ success: true } satisfies ITryResult)\n : ({\n success: false,\n error: `Function \"${entry.name}\" returned undefined despite declaring an output schema`,\n } satisfies ITryResult);\n }\n if (validateOutput !== undefined) {\n const output: IValidation<unknown> = validateOutput(result);\n if (output.success === false)\n return {\n success: false,\n error:\n `Type errors in \"${entry.name}\" output:\n\n` + LlmJson.stringify(output),\n } satisfies ITryResult;\n return { success: true, data: output.data } satisfies ITryResult;\n }\n return { success: true, data: result } satisfies ITryResult;\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof Error\n ? `${error.name}: ${error.message}`\n : String(error),\n } satisfies ITryResult;\n }\n },\n {\n name: entry.name,\n description: entry.function.description ?? \"\",\n // Declares the model-facing schema without a validator, so the\n // coerce-and-validate step above is the only one that runs; see\n // `LangChainParameterConverter`. The cast is needed because `tool()`\n // still types `schema` as Zod-or-JSON-Schema, even though the\n // `toJsonSchema` it reads that schema back with accepts Standard JSON\n // Schema by its own public signature.\n schema: LangChainParameterConverter.convert(\n entry.function,\n ) as JSONSchema,\n },\n );\n };\n\n const getToolName = (\n controllerName: string,\n functionName: string,\n prefix: boolean,\n ): string => (prefix ? `${controllerName}_${functionName}` : functionName);\n}\n\ntype ITryResult =\n | { success: true; data?: unknown | undefined }\n | { success: false; error: string };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LangChainToolsRegistrar.mjs","names":[],"sources":["../../src/internal/LangChainToolsRegistrar.ts"],"sourcesContent":["import {\n DynamicStructuredTool,\n ToolInputParsingException,\n tool,\n} from \"@langchain/core/tools\";\nimport type { JSONSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n IHttpLlmController,\n IHttpLlmFunction,\n ILlmController,\n ILlmFunction,\n ILlmSchema,\n IValidation,\n} from \"@typia/interface\";\nimport { HttpLlm, LlmJson } from \"@typia/utils\";\n\nimport { LangChainParameterConverter } from \"./LangChainParameterConverter\";\n\n/**\n * Registers class and HTTP operations as validated LangChain tools.\n *\n * Parameter validation precedes invocation. Output validation uses the source\n * application's strictness config, and invocation failures become tool\n * results.\n *\n * @evidence contracts/common.md#principled-implementation The registrar preserves class receivers, delegates HTTP transport to the controller or HttpLlm, and validates declared outputs with their application's config before returning model-visible data.\n * @evidence contracts/common.md#clear-and-simple-design Name checking, protocol-specific invocation and shared tool construction have separate helpers; both protocols share the argument and output validation path.\n * @evidence contracts/common.md#prohibited-implementation-shortcuts It uses LangChain's public tool factory and Standard JSON Schema carrier without dependency patches; failed argument validation prevents execution and output failures remain visible.\n * @evidence contracts/common.md#meaningful-documentation This namespace describes validation order and error ownership; createTool explains the strict-schema inversion and the public JSON Schema carrier cast.\n */\nexport namespace LangChainToolsRegistrar {\n /**\n * Converts controllers in declaration order, rejecting cross-controller names\n * that collide after applying the optional prefix.\n *\n * One application's function names are assumed unique, as established by its\n * controller builder. Every class method must exist before its tool is\n * added.\n *\n * @evidence contracts/common.md#principled-implementation A Map detects collisions for multiple controllers using the exact final tool name; class methods retain their receiver and HTTP operations retain their application and connection.\n * @evidence contracts/common.md#clear-and-simple-design One traversal checks final names before the protocol-specific registration traversal, while createTool owns the validation and result envelope common to both protocols.\n * @evidence contracts/common.md#prohibited-implementation-shortcuts It neither invents schemas nor bypasses typia validation: arguments are validated before transport, declared outputs are checked, and unknown methods fail conversion instead of creating a broken callback.\n * @evidence contracts/common.md#meaningful-documentation The comment records ordering, prefix collision semantics and the within-application uniqueness premise; private helpers explain result validation and schema conversion ownership.\n */\n export const convert = (props: {\n controllers: Array<ILlmController | IHttpLlmController>;\n prefix?: boolean | undefined;\n }): DynamicStructuredTool[] => {\n const prefix: boolean = props.prefix ?? false;\n const tools: DynamicStructuredTool[] = [];\n\n // check duplicate tool names\n if (props.controllers.length >= 2) {\n const names: Map<string, string> = new Map();\n const duplicates: string[] = [];\n for (const controller of props.controllers) {\n for (const func of controller.application.functions) {\n const toolName: string = getToolName(\n controller.name,\n func.name,\n prefix,\n );\n const existing: string | undefined = names.get(toolName);\n const origin: string = `${controller.protocol} controller \"${controller.name}\" function \"${func.name}\"`;\n if (existing !== undefined)\n duplicates.push(\n `\"${toolName}\" from ${origin} (conflicts with ${existing})`,\n );\n else names.set(toolName, origin);\n }\n }\n if (duplicates.length > 0)\n throw new Error(\n `Duplicate tool names found:\\n - ${duplicates.join(\"\\n - \")}`,\n );\n }\n\n // convert controllers to tools\n for (const controller of props.controllers) {\n if (controller.protocol === \"class\") {\n convertClassController(tools, controller, prefix);\n } else {\n convertHttpController(tools, controller, prefix);\n }\n }\n\n return tools;\n };\n\n const convertClassController = (\n tools: DynamicStructuredTool[],\n controller: ILlmController,\n prefix: boolean,\n ): void => {\n const execute: Record<string, unknown> = controller.execute;\n\n for (const func of controller.application.functions) {\n const toolName: string = getToolName(controller.name, func.name, prefix);\n\n const method: unknown = execute[func.name];\n if (typeof method !== \"function\") {\n throw new Error(\n `Method \"${func.name}\" not found on controller \"${controller.name}\"`,\n );\n }\n\n tools.push(\n createTool({\n name: toolName,\n function: func,\n config: controller.application.config,\n execute: async (args: unknown) => method.call(execute, args),\n }),\n );\n }\n };\n\n const convertHttpController = (\n tools: DynamicStructuredTool[],\n controller: IHttpLlmController,\n prefix: boolean,\n ): void => {\n const application = controller.application;\n const connection = controller.connection;\n\n for (const func of application.functions) {\n const toolName: string = getToolName(controller.name, func.name, prefix);\n\n tools.push(\n createTool({\n name: toolName,\n function: func,\n config: application.config,\n execute: async (args: unknown) => {\n if (controller.execute !== undefined) {\n const response = await controller.execute({\n connection,\n application,\n function: func,\n arguments: args as object,\n });\n return response.body;\n }\n return HttpLlm.execute({\n application,\n function: func,\n connection,\n input: args as object,\n });\n },\n }),\n );\n }\n };\n\n const createTool = (entry: {\n name: string;\n function: ILlmFunction | IHttpLlmFunction;\n config: ILlmSchema.IConfig;\n execute: (args: unknown) => Promise<unknown>;\n }): DynamicStructuredTool => {\n // A declared return type is a promise to the model, so a result that breaks\n // it is reported rather than delivered. `@typia/mcp` and `@typia/vercel`\n // already refuse one; this tool consulted `output` for its existence alone,\n // so a method returning nothing was reported while a method returning the\n // wrong shape was not (#2302).\n //\n // The application's own config decides how the schema is read back: a\n // strict application carries its constraints as description tags instead of\n // keywords, and only that config tells the inverter to read them.\n const validateOutput:\n | ((output: unknown) => IValidation<unknown>)\n | undefined =\n entry.function.output === undefined\n ? undefined\n : LlmJson.validate(entry.function.output, true, entry.config);\n return tool(\n async (args: unknown): Promise<unknown> => {\n const valid: IValidation<unknown> = LlmJson.validateArguments(\n entry.function,\n args ?? {},\n );\n if (valid.success === false)\n throw new ToolInputParsingException(\n `Type errors in \"${entry.name}\" arguments:\\n\\n` +\n LlmJson.stringify(valid),\n JSON.stringify(args ?? {}),\n );\n try {\n const result: unknown = await entry.execute(valid.data);\n if (result === undefined) {\n return validateOutput === undefined\n ? ({ success: true } satisfies ITryResult)\n : ({\n success: false,\n error: `Function \"${entry.name}\" returned undefined despite declaring an output schema`,\n } satisfies ITryResult);\n }\n if (validateOutput !== undefined) {\n const output: IValidation<unknown> = validateOutput(result);\n if (output.success === false)\n return {\n success: false,\n error:\n `Type errors in \"${entry.name}\" output:\n\n` + LlmJson.stringify(output),\n } satisfies ITryResult;\n return { success: true, data: output.data } satisfies ITryResult;\n }\n return { success: true, data: result } satisfies ITryResult;\n } catch (error) {\n return {\n success: false,\n error:\n error instanceof Error\n ? `${error.name}: ${error.message}`\n : String(error),\n } satisfies ITryResult;\n }\n },\n {\n name: entry.name,\n description: entry.function.description ?? \"\",\n // The carrier exposes the model-facing schema without top-level JSON\n // Schema constraints or a Standard Schema validator, so argument\n // constraints and coercion stay with the step above; see\n // `LangChainParameterConverter`. The cast is needed because `tool()`\n // still types `schema` as Zod-or-JSON-Schema, even though the\n // `toJsonSchema` it reads that schema back with accepts Standard JSON\n // Schema by its own public signature.\n schema: LangChainParameterConverter.convert(\n entry.function,\n ) as JSONSchema,\n },\n );\n };\n\n const getToolName = (\n controllerName: string,\n functionName: string,\n prefix: boolean,\n ): string => (prefix ? `${controllerName}_${functionName}` : functionName);\n}\n\ntype ITryResult =\n | { success: true; data?: unknown | undefined }\n | { success: false; error: string };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typia/langchain",
|
|
3
|
-
"version": "15.0
|
|
3
|
+
"version": "15.1.0",
|
|
4
4
|
"description": "LangChain.js integration for typia",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"homepage": "https://typia.io",
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@standard-schema/spec": "^1.1.0",
|
|
33
|
-
"@typia/interface": "^15.0
|
|
34
|
-
"@typia/utils": "^15.0
|
|
33
|
+
"@typia/interface": "^15.1.0",
|
|
34
|
+
"@typia/utils": "^15.1.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@langchain/core": ">=1.1.30"
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"rimraf": "^6.1.2",
|
|
42
42
|
"rolldown": "^1.1.5",
|
|
43
43
|
"tinyglobby": "^0.2.12",
|
|
44
|
-
"ttsc": "^0.
|
|
44
|
+
"ttsc": "^0.30.4",
|
|
45
45
|
"typescript": "^7.0.2"
|
|
46
46
|
},
|
|
47
47
|
"sideEffects": false,
|
|
@@ -69,7 +69,8 @@
|
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "rimraf lib && ttsc && node ../../scripts/create-conditional-declarations.cjs lib/index.d.ts && rolldown -c",
|
|
72
|
-
"dev": "ttsc --watch"
|
|
72
|
+
"dev": "ttsc --watch",
|
|
73
|
+
"evidence": "evidence"
|
|
73
74
|
},
|
|
74
75
|
"module": "lib/index.mjs",
|
|
75
76
|
"types": "lib/index.d.ts"
|
package/src/index.ts
CHANGED
|
@@ -35,48 +35,58 @@ interface ILangChainToolsProps extends ILangChainToolsOptions {
|
|
|
35
35
|
* Converts TypeScript class methods via `typia.llm.controller<Class>()` or
|
|
36
36
|
* OpenAPI operations via `HttpLlm.controller()` to LangChain tools.
|
|
37
37
|
*
|
|
38
|
-
* Every tool call is validated by typia.
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* Every tool call is validated by typia. Invalid arguments reject the call with
|
|
39
|
+
* LangChain's `ToolInputParsingException`, containing typia's formatted
|
|
40
|
+
* validation errors. The agent must handle that exception to give the model
|
|
41
|
+
* feedback for another attempt. Invocation and output failures are returned as
|
|
42
|
+
* `{ success: false, error }` tool results.
|
|
41
43
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* import { toLangChainTools } from "@typia/langchain";
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { toLangChainTools } from "@typia/langchain";
|
|
46
|
+
* import { initChatModel } from "langchain/chat_models/universal";
|
|
47
|
+
* import typia from "typia";
|
|
47
48
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* }
|
|
49
|
+
* class Calculator {
|
|
50
|
+
* add(input: { a: number; b: number }): { value: number } {
|
|
51
|
+
* return { value: input.a + input.b };
|
|
52
52
|
* }
|
|
53
|
+
* }
|
|
53
54
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
55
|
+
* const controller = typia.llm.controller<Calculator>(
|
|
56
|
+
* "calculator",
|
|
57
|
+
* new Calculator(),
|
|
58
|
+
* );
|
|
59
|
+
* const tools = toLangChainTools(controller);
|
|
59
60
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
61
|
+
* const llm = await initChatModel("gpt-4o", { modelProvider: "openai" });
|
|
62
|
+
* const modelWithTools = llm.bindTools(tools);
|
|
63
|
+
* const result = await modelWithTools.invoke("What is 10 + 5?");
|
|
64
|
+
* ```
|
|
64
65
|
*
|
|
65
66
|
* @param input Controller, controller list, or conversion properties
|
|
66
67
|
* @param options Conversion options when `input` is not a properties object
|
|
68
|
+
*
|
|
67
69
|
* @returns Array of LangChain DynamicStructuredTool
|
|
70
|
+
*
|
|
71
|
+
* @evidence contracts/common.md#principled-implementation All overloads normalize to a controller list and prefix before using the same registrar; properties objects retain their own options, and class and HTTP execution remain delegated to their declared controllers.
|
|
72
|
+
* @evidence contracts/common.md#clear-and-simple-design The public overloads express the three accepted input shapes while two private normalization helpers and one registrar keep conversion behavior shared.
|
|
73
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the public LangChain factory through its registrar and typia's validation; normalization does not manufacture controllers, schemas or successful results.
|
|
74
|
+
* @evidence contracts/common.md#meaningful-documentation The API documents input shapes, prefix behavior, class usage and the distinction between argument exceptions and invocation/output failure results; the registrar explains strict-output validation.
|
|
68
75
|
*/
|
|
69
76
|
export function toLangChainTools(
|
|
70
77
|
controller: ILangChainController,
|
|
71
78
|
options?: ILangChainToolsOptions | undefined,
|
|
72
79
|
): DynamicStructuredTool[];
|
|
80
|
+
/** Converts a controller list with one shared prefix option. */
|
|
73
81
|
export function toLangChainTools(
|
|
74
82
|
controllers: ILangChainController[],
|
|
75
83
|
options?: ILangChainToolsOptions | undefined,
|
|
76
84
|
): DynamicStructuredTool[];
|
|
85
|
+
/** Converts explicit properties using their embedded prefix option. */
|
|
77
86
|
export function toLangChainTools(
|
|
78
87
|
props: ILangChainToolsProps,
|
|
79
88
|
): DynamicStructuredTool[];
|
|
89
|
+
/** Normalizes the supported call forms before registration. */
|
|
80
90
|
export function toLangChainTools(
|
|
81
91
|
input: ILangChainController | ILangChainController[] | ILangChainToolsProps,
|
|
82
92
|
options?: ILangChainToolsOptions | undefined,
|
|
@@ -15,11 +15,11 @@ import { IHttpLlmFunction, ILlmFunction } from "@typia/interface";
|
|
|
15
15
|
*
|
|
16
16
|
* Standard JSON Schema separates the two roles. It carries a model-facing
|
|
17
17
|
* schema under `~standard.jsonSchema` and, by declaring no
|
|
18
|
-
* `~standard.validate`, no
|
|
19
|
-
* the
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* byte for byte.
|
|
18
|
+
* `~standard.validate`, no Standard Schema validator. LangChain's JSON Schema
|
|
19
|
+
* precheck sees the carrier rather than its nested parameter constraints, so
|
|
20
|
+
* parameter validation stays with `LlmJson.validateArguments` in the tool body.
|
|
21
|
+
* LangChain reads the model-facing schema back through its own `toJsonSchema`,
|
|
22
|
+
* so the model sees the same parameters document as before, byte for byte.
|
|
23
23
|
*
|
|
24
24
|
* `@typia/vercel` states the same contract to the AI SDK through
|
|
25
25
|
* `jsonSchema()`, whose `validate` is likewise left undefined so that
|
|
@@ -31,9 +31,26 @@ import { IHttpLlmFunction, ILlmFunction } from "@typia/interface";
|
|
|
31
31
|
* and would advertise _that_ to the model in place of the parameters — and
|
|
32
32
|
* `StandardJSONSchemaV1` only exists from `@standard-schema/spec@1.1.0`.
|
|
33
33
|
*
|
|
34
|
+
* @evidence contracts/common.md#principled-implementation The public Standard JSON Schema carrier exposes the reflected parameters through input/output callbacks while carrying no top-level parameter constraints or Standard Schema validator; the SDK precheck therefore leaves parameter coercion and correctable failures to LlmJson.
|
|
35
|
+
* @evidence contracts/common.md#clear-and-simple-design One converter owns the framework schema carrier, with the unchanged schema callback shared by both directions; execution validation stays in the registrar.
|
|
36
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The adapter uses the documented Standard JSON Schema extension and supported dependency floors instead of replacing LangChain internals or accepting raw data through a patched validator.
|
|
37
|
+
* @evidence contracts/common.md#meaningful-documentation The namespace explains the two schema roles, the validation trap avoided through the public extension, the Vercel equivalent and both required dependency floors with their consequences.
|
|
38
|
+
*
|
|
34
39
|
* @see https://github.com/standard-schema/standard-schema
|
|
35
40
|
*/
|
|
36
41
|
export namespace LangChainParameterConverter {
|
|
42
|
+
/**
|
|
43
|
+
* Returns a schema-only Standard JSON Schema carrier for one function.
|
|
44
|
+
*
|
|
45
|
+
* Input and output advertise the same required final argument shape; the
|
|
46
|
+
* registrar owns coercion, so the carrier deliberately has no Standard Schema
|
|
47
|
+
* validator and carries no top-level JSON Schema constraints.
|
|
48
|
+
*
|
|
49
|
+
* @evidence contracts/common.md#principled-implementation Both JSON Schema callbacks return func.parameters because coercion changes values rather than the required final shape; a carrier without top-level parameter constraints or a Standard Schema validator preserves the registrar's argument handling.
|
|
50
|
+
* @evidence contracts/common.md#clear-and-simple-design One shared callback and one standard carrier express the two equivalent schema directions without duplicating schema conversion or runtime checking.
|
|
51
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The returned version/vendor/jsonSchema fields implement Standard JSON Schema through its public contract; the function does not mutate LangChain or specialize known methods.
|
|
52
|
+
* @evidence contracts/common.md#meaningful-documentation The function comment explains shape equivalence and the validation owner, while the namespace supplies the framework semantics and supported-version rationale.
|
|
53
|
+
*/
|
|
37
54
|
export const convert = (
|
|
38
55
|
func: ILlmFunction | IHttpLlmFunction,
|
|
39
56
|
): StandardJSONSchemaV1 => {
|
|
@@ -16,7 +16,32 @@ import { HttpLlm, LlmJson } from "@typia/utils";
|
|
|
16
16
|
|
|
17
17
|
import { LangChainParameterConverter } from "./LangChainParameterConverter";
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Registers class and HTTP operations as validated LangChain tools.
|
|
21
|
+
*
|
|
22
|
+
* Parameter validation precedes invocation. Output validation uses the source
|
|
23
|
+
* application's strictness config, and invocation failures become tool
|
|
24
|
+
* results.
|
|
25
|
+
*
|
|
26
|
+
* @evidence contracts/common.md#principled-implementation The registrar preserves class receivers, delegates HTTP transport to the controller or HttpLlm, and validates declared outputs with their application's config before returning model-visible data.
|
|
27
|
+
* @evidence contracts/common.md#clear-and-simple-design Name checking, protocol-specific invocation and shared tool construction have separate helpers; both protocols share the argument and output validation path.
|
|
28
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It uses LangChain's public tool factory and Standard JSON Schema carrier without dependency patches; failed argument validation prevents execution and output failures remain visible.
|
|
29
|
+
* @evidence contracts/common.md#meaningful-documentation This namespace describes validation order and error ownership; createTool explains the strict-schema inversion and the public JSON Schema carrier cast.
|
|
30
|
+
*/
|
|
19
31
|
export namespace LangChainToolsRegistrar {
|
|
32
|
+
/**
|
|
33
|
+
* Converts controllers in declaration order, rejecting cross-controller names
|
|
34
|
+
* that collide after applying the optional prefix.
|
|
35
|
+
*
|
|
36
|
+
* One application's function names are assumed unique, as established by its
|
|
37
|
+
* controller builder. Every class method must exist before its tool is
|
|
38
|
+
* added.
|
|
39
|
+
*
|
|
40
|
+
* @evidence contracts/common.md#principled-implementation A Map detects collisions for multiple controllers using the exact final tool name; class methods retain their receiver and HTTP operations retain their application and connection.
|
|
41
|
+
* @evidence contracts/common.md#clear-and-simple-design One traversal checks final names before the protocol-specific registration traversal, while createTool owns the validation and result envelope common to both protocols.
|
|
42
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It neither invents schemas nor bypasses typia validation: arguments are validated before transport, declared outputs are checked, and unknown methods fail conversion instead of creating a broken callback.
|
|
43
|
+
* @evidence contracts/common.md#meaningful-documentation The comment records ordering, prefix collision semantics and the within-application uniqueness premise; private helpers explain result validation and schema conversion ownership.
|
|
44
|
+
*/
|
|
20
45
|
export const convert = (props: {
|
|
21
46
|
controllers: Array<ILlmController | IHttpLlmController>;
|
|
22
47
|
prefix?: boolean | undefined;
|
|
@@ -197,8 +222,9 @@ export namespace LangChainToolsRegistrar {
|
|
|
197
222
|
{
|
|
198
223
|
name: entry.name,
|
|
199
224
|
description: entry.function.description ?? "",
|
|
200
|
-
//
|
|
201
|
-
//
|
|
225
|
+
// The carrier exposes the model-facing schema without top-level JSON
|
|
226
|
+
// Schema constraints or a Standard Schema validator, so argument
|
|
227
|
+
// constraints and coercion stay with the step above; see
|
|
202
228
|
// `LangChainParameterConverter`. The cast is needed because `tool()`
|
|
203
229
|
// still types `schema` as Zod-or-JSON-Schema, even though the
|
|
204
230
|
// `toJsonSchema` it reads that schema back with accepts Standard JSON
|