@luanpoppe/ai 1.0.4 → 1.0.6
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/.env.example +10 -0
- package/dist/@types/model-names.d.ts +4 -1
- package/dist/@types/model-names.d.ts.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -7
- package/dist/index.js.map +1 -1
- package/dist/langchain/models.d.ts +4 -0
- package/dist/langchain/models.d.ts.map +1 -1
- package/dist/langchain/models.js +17 -0
- package/dist/langchain/models.js.map +1 -1
- package/dist/langchain/tools.d.ts +1 -1
- package/package.json +19 -9
- package/src/@types/model-names.ts +17 -1
- package/src/index.ts +17 -9
- package/src/langchain/models.ts +22 -0
- package/tests/e2e/README.md +47 -0
- package/tests/e2e/langchain.test.ts +477 -0
- package/tests/tsconfig.json +17 -0
- package/tests/unit/index.test.ts +355 -0
- package/tests/unit/langchain/messages.test.ts +101 -0
- package/tests/unit/langchain/models.test.ts +192 -0
- package/tests/unit/langchain/tools.test.ts +134 -0
- package/vitest.config.ts +24 -0
package/.env.example
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Variáveis de ambiente necessárias APENAS para os testes E2E
|
|
2
|
+
|
|
3
|
+
# OpenAI API Key (obrigatória para testes com GPT)
|
|
4
|
+
OPENAI_API_KEY=sk-...
|
|
5
|
+
|
|
6
|
+
# Google Gemini Token (obrigatória para testes com Gemini)
|
|
7
|
+
GOOGLE_GEMINI_TOKEN=...
|
|
8
|
+
|
|
9
|
+
# Obrigatória para testes com OpenRouter
|
|
10
|
+
OPENROUTER_API_KEY=...
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
type ChatGPTModels = "gpt-4" | "gpt-4o" | "gpt-4.1" | "gpt-5" | "gpt-5.1" | "gpt-5-mini" | "gpt-5-nano";
|
|
2
2
|
type GeminiModels = "gemini-2.5-flash" | "gemini-2.5-pro" | "gemini-3-flash" | "gemini-3-pro";
|
|
3
|
-
|
|
3
|
+
type AnthropicModels = "claude-opus-4.5" | "claude-haiku-4.5" | "claude-sonnet-4.5" | "claude-opus-4.1" | "claude-opus-4" | "claude-sonnet-4";
|
|
4
|
+
type OpenRouterProvidersModels = `google/${GeminiModels}` | `openai/${ChatGPTModels}` | `anthropic/${AnthropicModels}`;
|
|
5
|
+
type OpenRouterModels = `openrouter:${OpenRouterProvidersModels}` | `openrouter/${OpenRouterProvidersModels}`;
|
|
6
|
+
export type AIModelNames = ChatGPTModels | GeminiModels | OpenRouterModels;
|
|
4
7
|
export {};
|
|
5
8
|
//# sourceMappingURL=model-names.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-names.d.ts","sourceRoot":"","sources":["../../src/@types/model-names.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GACd,OAAO,GACP,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,GACT,YAAY,GACZ,YAAY,CAAC;AAEjB,KAAK,YAAY,GACb,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,CAAC;AAEnB,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"model-names.d.ts","sourceRoot":"","sources":["../../src/@types/model-names.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GACd,OAAO,GACP,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,GACT,YAAY,GACZ,YAAY,CAAC;AAEjB,KAAK,YAAY,GACb,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,CAAC;AAEnB,KAAK,eAAe,GAAG,iBAAiB,GACpC,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,GACjB,eAAe,GACf,iBAAiB,CAAC;AAEtB,KAAK,yBAAyB,GAC1B,UAAU,YAAY,EAAE,GACxB,UAAU,aAAa,EAAE,GACzB,aAAa,eAAe,EAAE,CAAA;AAElC,KAAK,gBAAgB,GACjB,cAAc,yBAAyB,EAAE,GACzC,cAAc,yBAAyB,EAAE,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,YAAY,GAAG,gBAAgB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,13 +9,14 @@ import { LangchainTools } from "./langchain/tools";
|
|
|
9
9
|
type LangchainConstructor = {
|
|
10
10
|
googleGeminiToken?: string;
|
|
11
11
|
openAIApiKey?: string;
|
|
12
|
+
openRouterApiKey?: string;
|
|
12
13
|
};
|
|
13
14
|
export type LangchainCallParams = {
|
|
14
|
-
agent
|
|
15
|
+
agent?: {
|
|
15
16
|
middleware?: AgentMiddleware[];
|
|
16
17
|
tools?: (ServerTool | ClientTool)[];
|
|
17
18
|
};
|
|
18
|
-
|
|
19
|
+
modelConfig?: Omit<LLMModelConfig, "apiKey" | "model">;
|
|
19
20
|
aiModel: AIModelNames;
|
|
20
21
|
messages: MessageInput[];
|
|
21
22
|
systemPrompt?: string;
|
|
@@ -37,7 +38,7 @@ export declare class Langchain {
|
|
|
37
38
|
call(params: LangchainCallParams): LangchainCallReturn;
|
|
38
39
|
callStructuredOutput<T extends z.ZodSchema>(params: LangchainCallStructuredOutputParams<T>): LangchainCallStructuredOutputReturn<typeof params.outputSchema>;
|
|
39
40
|
getRawAgent(params: LangchainCallParams, outputSchema?: z.ZodSchema | undefined): {
|
|
40
|
-
agent: import("langchain").ReactAgent<Record<string, any>, import("@langchain/core/utils/types").InteropZodObject | import("langchain").AnyAnnotationRoot | undefined, import("@langchain/core/utils/types").InteropZodObject | import("langchain").AnyAnnotationRoot, readonly AgentMiddleware<any, any, any>[]
|
|
41
|
+
agent: import("langchain").ReactAgent<import("langchain").AgentTypeConfig<Record<string, any>, import("@langchain/core/utils/types").InteropZodObject | import("langchain").AnyAnnotationRoot | undefined, import("@langchain/core/utils/types").InteropZodObject | import("langchain").AnyAnnotationRoot, readonly AgentMiddleware<any, any, any, readonly (ClientTool | ServerTool)[]>[], readonly (ClientTool | ServerTool)[]>>;
|
|
41
42
|
};
|
|
42
43
|
private getModel;
|
|
43
44
|
private standardAgent;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EACL,eAAe,EACf,WAAW,EAIZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,KAAK,oBAAoB,GAAG;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EACL,eAAe,EACf,WAAW,EAIZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,KAAK,oBAAoB,GAAG;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE;QACN,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;QAC/B,KAAK,CAAC,EAAE,CAAC,UAAU,GAAG,UAAU,CAAC,EAAE,CAAC;KACrC,CAAC;IAEF,WAAW,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;IAEvD,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB,CAAC,CAAC;AAEH,MAAM,MAAM,mCAAmC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,IACnE,mBAAmB,GAAG;IACpB,YAAY,EAAE,CAAC,CAAC;CACjB,CAAC;AAEJ,MAAM,MAAM,mCAAmC,CAAC,CAAC,IAAI,OAAO,CAAC;IAC3D,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;CACtB,CAAC,CAAC;AAEH,qBAAa,SAAS;IACR,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,oBAAoB;IAE1C,IAAI,CAAC,MAAM,EAAE,mBAAmB,GAAG,mBAAmB;IAiBtD,oBAAoB,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAC9C,MAAM,EAAE,mCAAmC,CAAC,CAAC,CAAC,GAC7C,mCAAmC,CAAC,OAAO,MAAM,CAAC,YAAY,CAAC;IAiBlE,WAAW,CACT,MAAM,EAAE,mBAAmB,EAC3B,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS;;;IAUxC,OAAO,CAAC,QAAQ;IAiChB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,mBAAmB;CAU5B;AAED,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -45,12 +45,11 @@ class Langchain {
|
|
|
45
45
|
return { agent };
|
|
46
46
|
}
|
|
47
47
|
getModel(params) {
|
|
48
|
-
const { aiModel,
|
|
49
|
-
const { maxTokens, temperature } = model;
|
|
48
|
+
const { aiModel, modelConfig } = params;
|
|
50
49
|
const config = {
|
|
51
50
|
model: aiModel,
|
|
52
|
-
maxTokens: maxTokens,
|
|
53
|
-
temperature: temperature,
|
|
51
|
+
maxTokens: modelConfig?.maxTokens,
|
|
52
|
+
temperature: modelConfig?.temperature,
|
|
54
53
|
};
|
|
55
54
|
if (aiModel.startsWith("gpt")) {
|
|
56
55
|
config.apiKey = this.tokens.openAIApiKey;
|
|
@@ -60,20 +59,27 @@ class Langchain {
|
|
|
60
59
|
config.apiKey = this.tokens.googleGeminiToken;
|
|
61
60
|
return models_1.LangchainModels.gemini(config);
|
|
62
61
|
}
|
|
62
|
+
if (aiModel.startsWith("openrouter:") || aiModel.startsWith("openrouter/")) {
|
|
63
|
+
const modelName = aiModel.replace(/^openrouter[:/]/, "");
|
|
64
|
+
return models_1.LangchainModels.openrouter({
|
|
65
|
+
...config,
|
|
66
|
+
model: modelName,
|
|
67
|
+
apiKey: this.tokens.openRouterApiKey,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
63
70
|
throw new Error("Model not supported");
|
|
64
71
|
}
|
|
65
72
|
standardAgent(params) {
|
|
66
73
|
const { systemPrompt, maxRetries = 3 } = params;
|
|
67
|
-
const { middleware, tools } = params.agent;
|
|
68
74
|
const model = this.getModel(params);
|
|
69
75
|
return {
|
|
70
76
|
model,
|
|
71
77
|
systemPrompt: systemPrompt ?? "",
|
|
72
78
|
middleware: [
|
|
73
79
|
...this.standardMiddlewares(maxRetries),
|
|
74
|
-
...(middleware ?? []),
|
|
80
|
+
...(params.agent?.middleware ?? []),
|
|
75
81
|
],
|
|
76
|
-
tools: tools ?? [],
|
|
82
|
+
tools: params.agent?.tools ?? [],
|
|
77
83
|
responseFormat: undefined,
|
|
78
84
|
};
|
|
79
85
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+CAAqE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,5 +9,9 @@ export type LLMModelConfig = {
|
|
|
9
9
|
export declare class LangchainModels {
|
|
10
10
|
static gpt(params: LLMModelConfig): ChatOpenAI<import("@langchain/openai").ChatOpenAICallOptions>;
|
|
11
11
|
static gemini(params: LLMModelConfig): ChatGoogleGenerativeAI;
|
|
12
|
+
static openrouter(params: LLMModelConfig & {
|
|
13
|
+
httpReferer?: string;
|
|
14
|
+
title?: string;
|
|
15
|
+
}): ChatOpenAI<import("@langchain/openai").ChatOpenAICallOptions>;
|
|
12
16
|
}
|
|
13
17
|
//# sourceMappingURL=models.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/langchain/models.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAEvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,qBAAa,eAAe;IAC1B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc;IAgBjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/langchain/models.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EAEvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,qBAAa,eAAe;IAC1B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc;IAgBjC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc;IAmBpC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAqBpF"}
|
package/dist/langchain/models.js
CHANGED
|
@@ -32,6 +32,23 @@ class LangchainModels {
|
|
|
32
32
|
options.temperature = temperature;
|
|
33
33
|
return new google_genai_1.ChatGoogleGenerativeAI(options);
|
|
34
34
|
}
|
|
35
|
+
static openrouter(params) {
|
|
36
|
+
const { apiKey, maxTokens, model, temperature, httpReferer, title } = params;
|
|
37
|
+
if (!apiKey)
|
|
38
|
+
throw new Error("OpenRouter API key is not passed in the model parameters");
|
|
39
|
+
const options = {
|
|
40
|
+
model,
|
|
41
|
+
apiKey,
|
|
42
|
+
configuration: {
|
|
43
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
if (maxTokens)
|
|
47
|
+
options.maxTokens = maxTokens;
|
|
48
|
+
if (temperature)
|
|
49
|
+
options.temperature = temperature;
|
|
50
|
+
return new openai_1.ChatOpenAI(options);
|
|
51
|
+
}
|
|
35
52
|
}
|
|
36
53
|
exports.LangchainModels = LangchainModels;
|
|
37
54
|
//# sourceMappingURL=models.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/langchain/models.ts"],"names":[],"mappings":";;;AAAA,0DAGiC;AACjC,8CAAiE;AASjE,MAAa,eAAe;IAC1B,MAAM,CAAC,GAAG,CAAC,MAAsB;QAC/B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QACzD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAE1E,MAAM,OAAO,GAAqB;YAChC,KAAK;YACL,MAAM;SACP,CAAC;QAEF,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7C,IAAI,WAAW;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QAEnD,OAAO,IAAI,mBAAU,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,MAAsB;QAClC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QAEzD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;QAEJ,MAAM,OAAO,GAAgC;YAC3C,KAAK;YACL,MAAM;SACP,CAAC;QAEF,IAAI,SAAS;YAAE,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;QACnD,IAAI,WAAW;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QAEnD,OAAO,IAAI,qCAAsB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/langchain/models.ts"],"names":[],"mappings":";;;AAAA,0DAGiC;AACjC,8CAAiE;AASjE,MAAa,eAAe;IAC1B,MAAM,CAAC,GAAG,CAAC,MAAsB;QAC/B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QACzD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAE1E,MAAM,OAAO,GAAqB;YAChC,KAAK;YACL,MAAM;SACP,CAAC;QAEF,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7C,IAAI,WAAW;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QAEnD,OAAO,IAAI,mBAAU,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,MAAsB;QAClC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QAEzD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;QAEJ,MAAM,OAAO,GAAgC;YAC3C,KAAK;YACL,MAAM;SACP,CAAC;QAEF,IAAI,SAAS;YAAE,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;QACnD,IAAI,WAAW;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QAEnD,OAAO,IAAI,qCAAsB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,MAAiE;QACjF,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;QAE7E,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAC;QAEJ,MAAM,OAAO,GAAqB;YAChC,KAAK;YACL,MAAM;YACN,aAAa,EAAE;gBACb,OAAO,EAAE,8BAA8B;aACxC;SACF,CAAC;QAEF,IAAI,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7C,IAAI,WAAW;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QAEnD,OAAO,IAAI,mBAAU,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;CACF;AAzDD,0CAyDC"}
|
|
@@ -7,6 +7,6 @@ export type CreateToolParams = {
|
|
|
7
7
|
schema: z.ZodSchema;
|
|
8
8
|
};
|
|
9
9
|
export declare class LangchainTools {
|
|
10
|
-
createTool(params: CreateToolParams): import("langchain").DynamicStructuredTool<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, unknown, unknown, unknown>;
|
|
10
|
+
createTool(params: CreateToolParams): import("langchain").DynamicStructuredTool<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, unknown, unknown, unknown, string>;
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=tools.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luanpoppe/ai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"keywords": [],
|
|
7
7
|
"author": "",
|
|
8
8
|
"license": "ISC",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@langchain/core": "^1.1.
|
|
11
|
-
"@langchain/google-genai": "^2.1.
|
|
12
|
-
"@langchain/openai": "^1.2.
|
|
13
|
-
"langchain": "^1.2.
|
|
14
|
-
"zod": "^4.
|
|
10
|
+
"@langchain/core": "^1.1.16",
|
|
11
|
+
"@langchain/google-genai": "^2.1.12",
|
|
12
|
+
"@langchain/openai": "^1.2.3",
|
|
13
|
+
"langchain": "^1.2.12",
|
|
14
|
+
"zod": "^4.3.6"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@types/node": "^25.0.
|
|
17
|
+
"@types/node": "^25.0.10",
|
|
18
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
19
|
+
"@vitest/ui": "^4.0.18",
|
|
20
|
+
"dotenv": "^16.4.7",
|
|
18
21
|
"tsx": "^4.21.0",
|
|
19
|
-
"typescript": "^5.9.3"
|
|
22
|
+
"typescript": "^5.9.3",
|
|
23
|
+
"vitest": "^4.0.18"
|
|
20
24
|
},
|
|
21
25
|
"scripts": {
|
|
22
26
|
"build": "tsc",
|
|
23
|
-
"pub": "pnpm build && pnpm publish --access=public"
|
|
27
|
+
"pub": "pnpm build && pnpm publish --access=public",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:ui": "vitest --ui",
|
|
31
|
+
"test:coverage": "vitest --coverage",
|
|
32
|
+
"test:e2e": "vitest run tests/e2e",
|
|
33
|
+
"test:unit": "vitest run tests/unit"
|
|
24
34
|
}
|
|
25
35
|
}
|
|
@@ -13,4 +13,20 @@ type GeminiModels =
|
|
|
13
13
|
| "gemini-3-flash"
|
|
14
14
|
| "gemini-3-pro";
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
type AnthropicModels = "claude-opus-4.5"
|
|
17
|
+
| "claude-haiku-4.5"
|
|
18
|
+
| "claude-sonnet-4.5"
|
|
19
|
+
| "claude-opus-4.1"
|
|
20
|
+
| "claude-opus-4"
|
|
21
|
+
| "claude-sonnet-4";
|
|
22
|
+
|
|
23
|
+
type OpenRouterProvidersModels =
|
|
24
|
+
| `google/${GeminiModels}`
|
|
25
|
+
| `openai/${ChatGPTModels}`
|
|
26
|
+
| `anthropic/${AnthropicModels}`
|
|
27
|
+
|
|
28
|
+
type OpenRouterModels =
|
|
29
|
+
| `openrouter:${OpenRouterProvidersModels}`
|
|
30
|
+
| `openrouter/${OpenRouterProvidersModels}`;
|
|
31
|
+
|
|
32
|
+
export type AIModelNames = ChatGPTModels | GeminiModels | OpenRouterModels;
|
package/src/index.ts
CHANGED
|
@@ -16,15 +16,16 @@ import { LangchainTools } from "./langchain/tools";
|
|
|
16
16
|
type LangchainConstructor = {
|
|
17
17
|
googleGeminiToken?: string;
|
|
18
18
|
openAIApiKey?: string;
|
|
19
|
+
openRouterApiKey?: string;
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export type LangchainCallParams = {
|
|
22
|
-
agent
|
|
23
|
+
agent?: {
|
|
23
24
|
middleware?: AgentMiddleware[];
|
|
24
25
|
tools?: (ServerTool | ClientTool)[];
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
modelConfig?: Omit<LLMModelConfig, "apiKey" | "model">;
|
|
28
29
|
|
|
29
30
|
aiModel: AIModelNames;
|
|
30
31
|
messages: MessageInput[];
|
|
@@ -98,13 +99,12 @@ export class Langchain {
|
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
private getModel(params: LangchainCallParams) {
|
|
101
|
-
const { aiModel,
|
|
102
|
-
const { maxTokens, temperature } = model;
|
|
102
|
+
const { aiModel, modelConfig } = params;
|
|
103
103
|
|
|
104
104
|
const config: LLMModelConfig = {
|
|
105
105
|
model: aiModel,
|
|
106
|
-
maxTokens: maxTokens,
|
|
107
|
-
temperature: temperature,
|
|
106
|
+
maxTokens: modelConfig?.maxTokens,
|
|
107
|
+
temperature: modelConfig?.temperature,
|
|
108
108
|
};
|
|
109
109
|
|
|
110
110
|
if (aiModel.startsWith("gpt")) {
|
|
@@ -119,6 +119,15 @@ export class Langchain {
|
|
|
119
119
|
return LangchainModels.gemini(config);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
if (aiModel.startsWith("openrouter:") || aiModel.startsWith("openrouter/")) {
|
|
123
|
+
const modelName = aiModel.replace(/^openrouter[:/]/, "");
|
|
124
|
+
return LangchainModels.openrouter({
|
|
125
|
+
...config,
|
|
126
|
+
model: modelName,
|
|
127
|
+
apiKey: this.tokens.openRouterApiKey,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
122
131
|
throw new Error("Model not supported");
|
|
123
132
|
}
|
|
124
133
|
|
|
@@ -126,7 +135,6 @@ export class Langchain {
|
|
|
126
135
|
params: LangchainCallParams
|
|
127
136
|
): Parameters<typeof createAgent>[0] {
|
|
128
137
|
const { systemPrompt, maxRetries = 3 } = params;
|
|
129
|
-
const { middleware, tools } = params.agent;
|
|
130
138
|
|
|
131
139
|
const model = this.getModel(params);
|
|
132
140
|
return {
|
|
@@ -134,9 +142,9 @@ export class Langchain {
|
|
|
134
142
|
systemPrompt: systemPrompt ?? "",
|
|
135
143
|
middleware: [
|
|
136
144
|
...this.standardMiddlewares(maxRetries),
|
|
137
|
-
...(middleware ?? []),
|
|
145
|
+
...(params.agent?.middleware ?? []),
|
|
138
146
|
],
|
|
139
|
-
tools: tools ?? [],
|
|
147
|
+
tools: params.agent?.tools ?? [],
|
|
140
148
|
responseFormat: undefined as any,
|
|
141
149
|
};
|
|
142
150
|
}
|
package/src/langchain/models.ts
CHANGED
|
@@ -46,4 +46,26 @@ export class LangchainModels {
|
|
|
46
46
|
|
|
47
47
|
return new ChatGoogleGenerativeAI(options);
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
static openrouter(params: LLMModelConfig & { httpReferer?: string; title?: string }) {
|
|
51
|
+
const { apiKey, maxTokens, model, temperature, httpReferer, title } = params;
|
|
52
|
+
|
|
53
|
+
if (!apiKey)
|
|
54
|
+
throw new Error(
|
|
55
|
+
"OpenRouter API key is not passed in the model parameters"
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const options: ChatOpenAIFields = {
|
|
59
|
+
model,
|
|
60
|
+
apiKey,
|
|
61
|
+
configuration: {
|
|
62
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if (maxTokens) options.maxTokens = maxTokens;
|
|
67
|
+
if (temperature) options.temperature = temperature;
|
|
68
|
+
|
|
69
|
+
return new ChatOpenAI(options);
|
|
70
|
+
}
|
|
49
71
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Testes End-to-End (E2E)
|
|
2
|
+
|
|
3
|
+
Estes testes fazem chamadas reais para as APIs das LLMs (OpenAI e Google Gemini).
|
|
4
|
+
|
|
5
|
+
## Configuração
|
|
6
|
+
|
|
7
|
+
### Onde colocar o arquivo .env?
|
|
8
|
+
|
|
9
|
+
**Coloque o arquivo `.env` na raiz do pacote `packages/ai/`** (não dentro de `tests/e2e/`).
|
|
10
|
+
|
|
11
|
+
1. Copie o arquivo de exemplo:
|
|
12
|
+
```bash
|
|
13
|
+
cd packages/ai
|
|
14
|
+
cp tests/e2e/env.example .env
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
2. Preencha as variáveis de ambiente no arquivo `.env`:
|
|
18
|
+
- `OPENAI_API_KEY`: Sua chave da API da OpenAI (necessária para testes com GPT)
|
|
19
|
+
- `GOOGLE_GEMINI_TOKEN`: Seu token da API do Google Gemini (necessária para testes com Gemini)
|
|
20
|
+
- `OPENROUTER_API_KEY`: Sua chave da API do OpenRouter (necessária para testes com OpenRouter)
|
|
21
|
+
|
|
22
|
+
### Como funciona?
|
|
23
|
+
|
|
24
|
+
O arquivo `.env` é carregado automaticamente pelo `dotenv` configurado no `vitest.config.ts`. O arquivo `.env` deve estar em `packages/ai/.env` e será carregado quando você executar `pnpm test:e2e`.
|
|
25
|
+
|
|
26
|
+
## Executando os testes
|
|
27
|
+
|
|
28
|
+
### Todos os testes E2E
|
|
29
|
+
```bash
|
|
30
|
+
pnpm test:e2e
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Apenas testes unitários
|
|
34
|
+
```bash
|
|
35
|
+
pnpm test:unit
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Todos os testes (unitários + E2E)
|
|
39
|
+
```bash
|
|
40
|
+
pnpm test
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Notas
|
|
44
|
+
|
|
45
|
+
- Os testes E2E são marcados com `skipIf` e só serão executados se as respectivas API keys estiverem configuradas
|
|
46
|
+
- Os testes E2E têm timeout de 30 segundos devido às chamadas de API
|
|
47
|
+
- **Atenção**: Estes testes consomem créditos das suas APIs. Use com moderação em desenvolvimento
|