@adminforth/completion-adapter-google-gemini 2.0.6 → 2.0.9

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.
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ npm run build 2>&1 | tee build.log
4
+ build_status=${PIPESTATUS[0]}
5
+
6
+ if [ $build_status -ne 0 ]; then
7
+ echo "Build failed. Exiting with status code $build_status"
8
+ exit $build_status
9
+ fi
@@ -0,0 +1,44 @@
1
+ #!/bin/sh
2
+
3
+ set -x
4
+
5
+ COMMIT_SHORT_SHA=$(echo $CI_COMMIT_SHA | cut -c1-8)
6
+
7
+ STATUS=${1}
8
+
9
+ if [ "$STATUS" = "success" ]; then
10
+ MESSAGE="Did a build without issues on \`$CI_REPO_NAME/$CI_COMMIT_BRANCH\`. Commit: _${CI_COMMIT_MESSAGE}_ (<$CI_COMMIT_URL|$COMMIT_SHORT_SHA>)"
11
+
12
+ curl -s -X POST -H "Content-Type: application/json" -d '{
13
+ "username": "'"$CI_COMMIT_AUTHOR"'",
14
+ "icon_url": "'"$CI_COMMIT_AUTHOR_AVATAR"'",
15
+ "attachments": [
16
+ {
17
+ "mrkdwn_in": ["text", "pretext"],
18
+ "color": "#36a64f",
19
+ "text": "'"$MESSAGE"'"
20
+ }
21
+ ]
22
+ }' "$DEVELOPERS_SLACK_WEBHOOK"
23
+ exit 0
24
+ fi
25
+ export BUILD_LOG=$(cat ./build.log)
26
+
27
+ BUILD_LOG=$(echo $BUILD_LOG | sed 's/"/\\"/g')
28
+
29
+ MESSAGE="Broke \`$CI_REPO_NAME/$CI_COMMIT_BRANCH\` with commit _${CI_COMMIT_MESSAGE}_ (<$CI_COMMIT_URL|$COMMIT_SHORT_SHA>)"
30
+ CODE_BLOCK="\`\`\`$BUILD_LOG\n\`\`\`"
31
+
32
+ echo "Sending slack message to developers $MESSAGE"
33
+ curl -sS -X POST -H "Content-Type: application/json" -d '{
34
+ "username": "'"$CI_COMMIT_AUTHOR"'",
35
+ "icon_url": "'"$CI_COMMIT_AUTHOR_AVATAR"'",
36
+ "attachments": [
37
+ {
38
+ "mrkdwn_in": ["text", "pretext"],
39
+ "color": "#8A1C12",
40
+ "text": "'"$CODE_BLOCK"'",
41
+ "pretext": "'"$MESSAGE"'"
42
+ }
43
+ ]
44
+ }' "$DEVELOPERS_SLACK_WEBHOOK" 2>&1
@@ -0,0 +1,56 @@
1
+ clone:
2
+ git:
3
+ image: woodpeckerci/plugin-git
4
+ settings:
5
+ partial: false
6
+ depth: 5
7
+
8
+ steps:
9
+ init-secrets:
10
+ when:
11
+ - event: push
12
+ image: infisical/cli
13
+ environment:
14
+ INFISICAL_TOKEN:
15
+ from_secret: VAULT_TOKEN
16
+ commands:
17
+ - infisical export --domain https://vault.devforth.io/api --format=dotenv-export --env="prod" > /woodpecker/deploy.vault.env
18
+
19
+ build:
20
+ image: devforth/node20-pnpm:latest
21
+ when:
22
+ - event: push
23
+ commands:
24
+ - . /woodpecker/deploy.vault.env
25
+ - pnpm install
26
+ - /bin/bash ./.woodpecker/buildRelease.sh
27
+ - npm audit signatures
28
+
29
+ release:
30
+ image: devforth/node20-pnpm:latest
31
+ when:
32
+ - event:
33
+ - push
34
+ branch:
35
+ - main
36
+ commands:
37
+ - . /woodpecker/deploy.vault.env
38
+ - pnpm exec semantic-release
39
+
40
+ slack-on-failure:
41
+ image: curlimages/curl
42
+ when:
43
+ - event: push
44
+ status: [failure]
45
+ commands:
46
+ - . /woodpecker/deploy.vault.env
47
+ - /bin/sh ./.woodpecker/buildSlackNotify.sh failure
48
+
49
+ slack-on-success:
50
+ image: curlimages/curl
51
+ when:
52
+ - event: push
53
+ status: [success]
54
+ commands:
55
+ - . /woodpecker/deploy.vault.env
56
+ - /bin/sh ./.woodpecker/buildSlackNotify.sh success
package/build.log ADDED
@@ -0,0 +1,4 @@
1
+
2
+ > @adminforth/completion-adapter-google-gemini@1.0.0 build
3
+ > tsc
4
+
package/dist/index.js CHANGED
@@ -7,12 +7,54 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
10
11
  import { GoogleGenAI } from "@google/genai";
11
12
  import pRetry from 'p-retry';
12
13
  import { logger } from "adminforth";
14
+ const GOOGLE_LANGCHAIN_AGENT_OPTION_KEYS = [
15
+ "temperature",
16
+ "topP",
17
+ "topK",
18
+ "stopSequences",
19
+ "safetySettings",
20
+ "apiVersion",
21
+ "baseUrl",
22
+ "customHeaders",
23
+ "streaming",
24
+ "json",
25
+ "streamUsage",
26
+ "convertSystemMessageToHumanContent",
27
+ "thinkingConfig",
28
+ ];
29
+ function getGoogleLangChainAgentOptions(extraRequestBodyParameters) {
30
+ const options = {};
31
+ if (!extraRequestBodyParameters) {
32
+ return options;
33
+ }
34
+ for (const key of GOOGLE_LANGCHAIN_AGENT_OPTION_KEYS) {
35
+ if (key in extraRequestBodyParameters) {
36
+ options[key] = extraRequestBodyParameters[key];
37
+ }
38
+ }
39
+ return options;
40
+ }
13
41
  export default class CompletionAdapterGoogleGemini {
14
42
  constructor(options) {
15
- this.complete = (content_1, ...args_1) => __awaiter(this, [content_1, ...args_1], void 0, function* (content, stop = ["."], maxTokens = 50, outputSchema) {
43
+ this.complete = (requestOrContent_1, ...args_1) => __awaiter(this, [requestOrContent_1, ...args_1], void 0, function* (requestOrContent, stopOrMaxTokens = 50, maxTokensOrOutputSchema = 50, outputSchema) {
44
+ const request = typeof requestOrContent === "string"
45
+ ? {
46
+ content: requestOrContent,
47
+ maxTokens: typeof stopOrMaxTokens === "number"
48
+ ? stopOrMaxTokens
49
+ : typeof maxTokensOrOutputSchema === "number"
50
+ ? maxTokensOrOutputSchema
51
+ : 50,
52
+ outputSchema: typeof stopOrMaxTokens === "number"
53
+ ? maxTokensOrOutputSchema
54
+ : outputSchema,
55
+ }
56
+ : requestOrContent;
57
+ const { content, maxTokens: requestMaxTokens = 50, outputSchema: requestOutputSchema, } = request;
16
58
  const ai = new GoogleGenAI({
17
59
  apiKey: this.options.geminiApiKey,
18
60
  });
@@ -21,8 +63,13 @@ export default class CompletionAdapterGoogleGemini {
21
63
  try {
22
64
  const response = yield ai.models.generateContent({
23
65
  model: this.options.model || "gemini-3-flash-preview",
24
- contents: content,
25
- config: Object.assign({ responseJsonSchema: outputSchema ? outputSchema : undefined, maxOutputTokens: maxTokens }, this.options.extraRequestBodyParameters),
66
+ contents: [
67
+ {
68
+ role: "user",
69
+ parts: [{ text: content }],
70
+ },
71
+ ],
72
+ config: Object.assign({ responseJsonSchema: requestOutputSchema ? requestOutputSchema : undefined, maxOutputTokens: requestMaxTokens }, this.options.extraRequestBodyParameters),
26
73
  });
27
74
  logger.debug(`Google Gemini SUCCESSFUL API response: ${response}`);
28
75
  return {
@@ -31,7 +78,14 @@ export default class CompletionAdapterGoogleGemini {
31
78
  }
32
79
  catch (error) {
33
80
  logger.error(`Error during Google Gemini API call: ${error}`);
34
- throw new Error(`Error during Google Gemini API call: ${JSON.parse(error.message).error.message}`);
81
+ const errorMessage = error instanceof Error ? error.message : String(error);
82
+ let googleErrorMessage = errorMessage;
83
+ try {
84
+ googleErrorMessage = JSON.parse(errorMessage).error.message;
85
+ }
86
+ catch (_a) {
87
+ }
88
+ throw new Error(`Error during Google Gemini API call: ${googleErrorMessage}`);
35
89
  }
36
90
  });
37
91
  const result = yield pRetry(tryToGenerate, {
@@ -62,4 +116,10 @@ export default class CompletionAdapterGoogleGemini {
62
116
  return countTokensResponse.totalTokens;
63
117
  });
64
118
  }
119
+ getLangChainAgentSpec(params) {
120
+ const modelOptions = getGoogleLangChainAgentOptions(this.options.extraRequestBodyParameters);
121
+ return {
122
+ model: new ChatGoogleGenerativeAI(Object.assign({ model: this.options.model || "gemini-3-flash-preview", apiKey: this.options.geminiApiKey, maxOutputTokens: params.maxTokens }, modelOptions)),
123
+ };
124
+ }
65
125
  }
package/index.ts CHANGED
@@ -1,9 +1,52 @@
1
1
  import type { AdapterOptions } from "./types.js";
2
2
  import type { CompletionAdapter } from "adminforth";
3
+ import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
3
4
  import { GoogleGenAI } from "@google/genai";
4
5
  import pRetry from 'p-retry';
5
6
  import { logger } from "adminforth";
6
7
 
8
+ type CompletionRequestInput = {
9
+ content: string;
10
+ maxTokens?: number;
11
+ outputSchema?: any;
12
+ };
13
+
14
+ type AgentModelPurpose = "primary" | "summary";
15
+
16
+ const GOOGLE_LANGCHAIN_AGENT_OPTION_KEYS = [
17
+ "temperature",
18
+ "topP",
19
+ "topK",
20
+ "stopSequences",
21
+ "safetySettings",
22
+ "apiVersion",
23
+ "baseUrl",
24
+ "customHeaders",
25
+ "streaming",
26
+ "json",
27
+ "streamUsage",
28
+ "convertSystemMessageToHumanContent",
29
+ "thinkingConfig",
30
+ ] as const;
31
+
32
+ function getGoogleLangChainAgentOptions(
33
+ extraRequestBodyParameters?: Record<string, unknown>,
34
+ ) {
35
+ const options: Record<string, unknown> = {};
36
+
37
+ if (!extraRequestBodyParameters) {
38
+ return options;
39
+ }
40
+
41
+ for (const key of GOOGLE_LANGCHAIN_AGENT_OPTION_KEYS) {
42
+ if (key in extraRequestBodyParameters) {
43
+ options[key] = extraRequestBodyParameters[key];
44
+ }
45
+ }
46
+
47
+ return options;
48
+ }
49
+
7
50
  export default class CompletionAdapterGoogleGemini
8
51
  implements CompletionAdapter
9
52
  {
@@ -32,12 +75,56 @@ export default class CompletionAdapterGoogleGemini
32
75
  return countTokensResponse.totalTokens;
33
76
  }
34
77
 
78
+ getLangChainAgentSpec(params: {
79
+ maxTokens: number;
80
+ purpose: AgentModelPurpose;
81
+ }) {
82
+ const modelOptions = getGoogleLangChainAgentOptions(
83
+ this.options.extraRequestBodyParameters,
84
+ );
85
+
86
+ return {
87
+ model: new ChatGoogleGenerativeAI({
88
+ model: this.options.model || "gemini-3-flash-preview",
89
+ apiKey: this.options.geminiApiKey,
90
+ maxOutputTokens: params.maxTokens,
91
+ ...modelOptions,
92
+ } as any),
93
+ };
94
+ }
95
+
35
96
 
36
- complete = async (content: string, stop = ["."], maxTokens = 50, outputSchema?: any): Promise<{
97
+ complete = async (
98
+ requestOrContent: CompletionRequestInput | string,
99
+ stopOrMaxTokens: string[] | number = 50,
100
+ maxTokensOrOutputSchema: number | any = 50,
101
+ outputSchema?: any,
102
+ ): Promise<{
37
103
  content?: string;
38
104
  finishReason?: string;
39
105
  error?: string;
40
106
  }> => {
107
+ const request =
108
+ typeof requestOrContent === "string"
109
+ ? {
110
+ content: requestOrContent,
111
+ maxTokens:
112
+ typeof stopOrMaxTokens === "number"
113
+ ? stopOrMaxTokens
114
+ : typeof maxTokensOrOutputSchema === "number"
115
+ ? maxTokensOrOutputSchema
116
+ : 50,
117
+ outputSchema:
118
+ typeof stopOrMaxTokens === "number"
119
+ ? maxTokensOrOutputSchema
120
+ : outputSchema,
121
+ }
122
+ : requestOrContent;
123
+ const {
124
+ content,
125
+ maxTokens: requestMaxTokens = 50,
126
+ outputSchema: requestOutputSchema,
127
+ } = request;
41
128
 
42
129
  const ai = new GoogleGenAI({
43
130
  apiKey: this.options.geminiApiKey,
@@ -48,10 +135,15 @@ export default class CompletionAdapterGoogleGemini
48
135
  try {
49
136
  const response = await ai.models.generateContent({
50
137
  model: this.options.model || "gemini-3-flash-preview",
51
- contents: content,
138
+ contents: [
139
+ {
140
+ role: "user",
141
+ parts: [{ text: content }],
142
+ },
143
+ ],
52
144
  config: {
53
- responseJsonSchema: outputSchema ? outputSchema : undefined,
54
- maxOutputTokens: maxTokens,
145
+ responseJsonSchema: requestOutputSchema ? requestOutputSchema : undefined,
146
+ maxOutputTokens: requestMaxTokens,
55
147
  ...this.options.extraRequestBodyParameters,
56
148
  },
57
149
  });
@@ -61,7 +153,13 @@ export default class CompletionAdapterGoogleGemini
61
153
  };
62
154
  } catch (error) {
63
155
  logger.error(`Error during Google Gemini API call: ${error}`);
64
- throw new Error(`Error during Google Gemini API call: ${JSON.parse(error.message).error.message}`);
156
+ const errorMessage = error instanceof Error ? error.message : String(error);
157
+ let googleErrorMessage = errorMessage;
158
+ try {
159
+ googleErrorMessage = JSON.parse(errorMessage).error.message;
160
+ } catch {
161
+ }
162
+ throw new Error(`Error during Google Gemini API call: ${googleErrorMessage}`);
65
163
  }
66
164
  }
67
165
  const result = await pRetry(tryToGenerate, {
package/package.json CHANGED
@@ -1,25 +1,55 @@
1
1
  {
2
2
  "name": "@adminforth/completion-adapter-google-gemini",
3
- "version": "2.0.6",
3
+ "version": "2.0.9",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
7
10
  "scripts": {
8
- "build": "tsc && npm version patch",
9
- "rollout": "npm run build && npm publish --access public"
11
+ "build": "tsc"
10
12
  },
11
13
  "keywords": [],
12
- "author": "",
14
+ "author": "DevForth (https://devforth.io)",
13
15
  "license": "MIT",
14
16
  "description": "",
15
17
  "dependencies": {
16
18
  "@google/genai": "^1.35.0",
19
+ "@langchain/google-genai": "2.1.28",
17
20
  "p-retry": "^7.1.1"
18
21
  },
19
22
  "peerDependencies": {
20
23
  "adminforth": "^2.24.0"
21
24
  },
25
+ "release": {
26
+ "plugins": [
27
+ "@semantic-release/commit-analyzer",
28
+ "@semantic-release/release-notes-generator",
29
+ "@semantic-release/npm",
30
+ "@semantic-release/github",
31
+ [
32
+ "semantic-release-slack-bot",
33
+ {
34
+ "packageName": "@adminforth/completion-adapter-google-gemini",
35
+ "notifyOnSuccess": true,
36
+ "notifyOnFail": true,
37
+ "slackIcon": ":package:",
38
+ "markdownReleaseNotes": true
39
+ }
40
+ ]
41
+ ],
42
+ "branches": [
43
+ "main",
44
+ {
45
+ "name": "next",
46
+ "prerelease": true
47
+ }
48
+ ]
49
+ },
22
50
  "devDependencies": {
23
- "typescript": "^5.9.3"
51
+ "typescript": "^5.9.3",
52
+ "semantic-release": "^24.2.1",
53
+ "semantic-release-slack-bot": "^4.0.2"
24
54
  }
25
55
  }