koishi-plugin-chatluna-google-gemini-adapter 1.0.0-beta.3 → 1.0.0-beta.4

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/lib/client.js CHANGED
@@ -30,6 +30,7 @@ class GeminiClient extends client_1.PlatformModelAndEmbeddingsClient {
30
30
  .map((model) => {
31
31
  return {
32
32
  name: model,
33
+ maxTokens: model.includes('vision') ? 12288 : 30720,
33
34
  type: model.includes('embedding')
34
35
  ? types_1.ModelType.embeddings
35
36
  : types_1.ModelType.llm,
package/lib/requester.js CHANGED
@@ -19,7 +19,7 @@ class GeminiRequester extends api_1.ModelRequester {
19
19
  async *completionStream(params) {
20
20
  try {
21
21
  const response = await this._post(`models/${params.model}:streamGenerateContent`, {
22
- contents: (0, utils_1.langchainMessageToGeminiMessage)(params.input, params.model),
22
+ contents: await (0, utils_1.langchainMessageToGeminiMessage)(params.input, params.model),
23
23
  safetySettings: [
24
24
  {
25
25
  category: 'HARM_CATEGORY_HARASSMENT',
@@ -66,20 +66,28 @@ class GeminiRequester extends api_1.ModelRequester {
66
66
  throw new Error(JSON.stringify(value));
67
67
  }
68
68
  const text = parts[0].text;
69
+ _1.logger.debug('text', text);
69
70
  if (text) {
70
71
  await writable.write(text);
71
72
  }
72
73
  }
73
74
  };
74
75
  await (0, sse_1.sse)(response, async (rawData) => {
76
+ _1.logger.debug('chunk', rawData);
75
77
  jsonParser.write(rawData);
76
78
  return true;
77
79
  });
78
80
  let content = '';
79
- for await (const chunk of iterable) {
81
+ let isVisionModel = params.model.includes('vision');
82
+ for await (let chunk of iterable) {
80
83
  if (chunk === '[DONE]') {
81
84
  return;
82
85
  }
86
+ // match /w*model:
87
+ if (isVisionModel && /\s*model:\s*/.test(chunk)) {
88
+ isVisionModel = false;
89
+ chunk = chunk.replace(/\s*model:\s*/, '');
90
+ }
83
91
  try {
84
92
  const messageChunk = new schema_1.AIMessageChunk(chunk);
85
93
  messageChunk.content = content + messageChunk.content;
package/lib/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AIMessageChunk, BaseMessage, ChatMessageChunk, HumanMessageChunk, MessageType, SystemMessageChunk } from 'langchain/schema';
2
2
  import { ChatCompletionResponseMessage, ChatCompletionResponseMessageRoleEnum } from './types';
3
- export declare function langchainMessageToGeminiMessage(messages: BaseMessage[], model?: string): ChatCompletionResponseMessage[];
3
+ export declare function langchainMessageToGeminiMessage(messages: BaseMessage[], model?: string): Promise<ChatCompletionResponseMessage[]>;
4
4
  export declare function messageTypeToGeminiRole(type: MessageType): ChatCompletionResponseMessageRoleEnum;
5
5
  export declare function convertDeltaToMessageChunk(delta: Record<string, any>, defaultRole?: ChatCompletionResponseMessageRoleEnum): HumanMessageChunk | AIMessageChunk | SystemMessageChunk | ChatMessageChunk;
package/lib/utils.js CHANGED
@@ -2,9 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertDeltaToMessageChunk = exports.messageTypeToGeminiRole = exports.langchainMessageToGeminiMessage = void 0;
4
4
  const schema_1 = require("langchain/schema");
5
- function langchainMessageToGeminiMessage(messages, model) {
6
- // TODO: image vision
7
- const mappedMessage = messages.map((rawMessage) => {
5
+ async function langchainMessageToGeminiMessage(messages, model) {
6
+ const mappedMessage = await Promise.all(messages.map(async (rawMessage) => {
8
7
  const role = messageTypeToGeminiRole(rawMessage._getType());
9
8
  const images = rawMessage.additional_kwargs.images;
10
9
  const result = {
@@ -20,14 +19,14 @@ function langchainMessageToGeminiMessage(messages, model) {
20
19
  result.parts.push({
21
20
  inline_data: {
22
21
  // base64 image match type
23
- data: image,
22
+ data: image.replace(/^data:image\/\w+;base64,/, ''),
24
23
  mime_type: 'image/jpeg'
25
24
  }
26
25
  });
27
26
  }
28
27
  }
29
28
  return result;
30
- });
29
+ }));
31
30
  const result = [];
32
31
  for (let i = 0; i < mappedMessage.length; i++) {
33
32
  const message = mappedMessage[i];
@@ -60,6 +59,46 @@ function langchainMessageToGeminiMessage(messages, model) {
60
59
  ]
61
60
  });
62
61
  }
62
+ if (model.includes('vision')) {
63
+ // format prompts
64
+ const textBuffer = [];
65
+ const last = result.pop();
66
+ for (let i = 0; i < result.length; i++) {
67
+ const message = result[i];
68
+ const text = message.parts[0].text;
69
+ textBuffer.push(`${message.role}: ${text}`);
70
+ }
71
+ const lastParts = last.parts;
72
+ let lastImagesParts = lastParts.filter((part) => part.inline_data?.mime_type ===
73
+ 'image/jpeg');
74
+ if (lastImagesParts.length < 1) {
75
+ for (let i = result.length - 1; i >= 0; i--) {
76
+ const message = result[i];
77
+ const images = message.parts.filter((part) => part.inline_data?.mime_type ===
78
+ 'image/jpeg');
79
+ if (images.length > 0) {
80
+ lastImagesParts = images;
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ ;
86
+ lastParts.filter((part) => part.text !== undefined &&
87
+ part.text !== null).forEach((part) => {
88
+ textBuffer.push(`${last.role}: ${part.text}`);
89
+ });
90
+ return [
91
+ {
92
+ role: 'user',
93
+ parts: [
94
+ {
95
+ text: textBuffer.join('\n')
96
+ },
97
+ ...lastImagesParts
98
+ ]
99
+ }
100
+ ];
101
+ }
63
102
  return result;
64
103
  }
65
104
  exports.langchainMessageToGeminiMessage = langchainMessageToGeminiMessage;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-google-gemini-adapter",
3
3
  "description": "google-gemini adapter for chatluna",
4
- "version": "1.0.0-beta.3",
4
+ "version": "1.0.0-beta.4",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -43,11 +43,11 @@
43
43
  },
44
44
  "devDependencies": {
45
45
  "atsc": "^1.2.2",
46
- "koishi": "^4.16.1"
46
+ "koishi": "^4.16.3"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "koishi": "^4.16.0",
50
- "koishi-plugin-chatluna": "^1.0.0-beta.28"
50
+ "koishi-plugin-chatluna": "^1.0.0-beta.31"
51
51
  },
52
52
  "koishi": {
53
53
  "description": {