-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
openapi.ts
129 lines (124 loc) Β· 4.05 KB
/
openapi.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import type { BaseLanguageModelInterface } from "@langchain/core/language_models/base";
import type { ToolInterface } from "@langchain/core/tools";
import { DynamicTool } from "@langchain/core/tools";
import { Toolkit } from "@langchain/community/agents/toolkits/base";
import { JsonSpec } from "../../../tools/json.js";
import { AgentExecutor } from "../../executor.js";
import {
OPENAPI_PREFIX,
OPENAPI_SUFFIX,
JSON_EXPLORER_DESCRIPTION,
} from "./prompt.js";
import { LLMChain } from "../../../chains/llm_chain.js";
import { ZeroShotCreatePromptArgs, ZeroShotAgent } from "../../mrkl/index.js";
import {
Headers,
RequestsGetTool,
RequestsPostTool,
} from "../../../tools/requests.js";
import { createJsonAgent, JsonToolkit } from "../json/json.js";
/**
* Represents a toolkit for making HTTP requests. It initializes the
* request tools based on the provided headers.
*/
export class RequestsToolkit extends Toolkit {
tools: ToolInterface[];
constructor(headers?: Headers) {
super();
this.tools = [new RequestsGetTool(headers), new RequestsPostTool(headers)];
}
}
/**
* Extends the `RequestsToolkit` class and adds a dynamic tool for
* exploring JSON data. It creates a JSON agent using the `JsonToolkit`
* and the provided language model, and adds the JSON explorer tool to the
* toolkit.
* @example
* ```typescript
* const toolkit = new OpenApiToolkit(
* new JsonSpec({
* }),
* new ChatOpenAI({ temperature: 0 }),
* {
* "Content-Type": "application/json",
* Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
* },
* );
*
* const result = await toolkit.invoke({
* input:
* "Make a POST request to openai /completions. The prompt should be 'tell me a joke.'",
* });
* console.log(`Got output ${result.output}`);
* ```
*/
export class OpenApiToolkit extends RequestsToolkit {
constructor(
jsonSpec: JsonSpec,
llm: BaseLanguageModelInterface,
headers?: Headers
) {
super(headers);
const jsonAgent = createJsonAgent(llm, new JsonToolkit(jsonSpec));
this.tools = [
...this.tools,
new DynamicTool({
name: "json_explorer",
func: async (input: string) => {
const result = await jsonAgent.call({ input });
return result.output as string;
},
description: JSON_EXPLORER_DESCRIPTION,
}),
];
}
}
/**
* @deprecated Create a specific agent with a custom tool instead.
*
* Creates an OpenAPI agent using a language model, an OpenAPI toolkit,
* and optional prompt arguments. It creates a prompt for the agent using
* the OpenAPI tools and the provided prefix and suffix. It then creates a
* ZeroShotAgent with the prompt and the OpenAPI tools, and returns an
* AgentExecutor for executing the agent with the tools.
* @param llm The language model to use.
* @param openApiToolkit The OpenAPI toolkit to use.
* @param args Optional arguments for creating the prompt.
* @returns An AgentExecutor for executing the agent with the tools.
*
* @security **Security Notice** This agent provides access to external APIs.
* Use with caution as this agent can make API calls with arbitrary headers.
* Exposing this agent to users could lead to security vulnerabilities. Consider
* limiting access to what endpoints it can hit, what actions can be taken, and
* more.
*
* @link See https://js.langchain.com/docs/security for more information.
*/
export function createOpenApiAgent(
llm: BaseLanguageModelInterface,
openApiToolkit: OpenApiToolkit,
args?: ZeroShotCreatePromptArgs
) {
const {
prefix = OPENAPI_PREFIX,
suffix = OPENAPI_SUFFIX,
inputVariables = ["input", "agent_scratchpad"],
} = args ?? {};
const { tools } = openApiToolkit;
const prompt = ZeroShotAgent.createPrompt(tools, {
prefix,
suffix,
inputVariables,
});
const chain = new LLMChain({
prompt,
llm,
});
const toolNames = tools.map((tool) => tool.name);
const agent = new ZeroShotAgent({ llmChain: chain, allowedTools: toolNames });
return AgentExecutor.fromAgentAndTools({
agent,
tools,
returnIntermediateSteps: true,
});
}