@gringow/gringow 0.0.4 → 0.0.7

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.
Files changed (104) hide show
  1. package/dist/browser.d.mts +6 -0
  2. package/dist/browser.mjs +28 -0
  3. package/dist/config.d.mts +44 -0
  4. package/dist/config.mjs +154 -0
  5. package/dist/data/check-cache.d.mts +9 -0
  6. package/dist/data/check-cache.mjs +430 -0
  7. package/dist/data/clear-cache.d.mts +3 -0
  8. package/dist/data/clear-cache.mjs +379 -0
  9. package/dist/data/create-cache-dir.d.mts +3 -0
  10. package/dist/data/create-cache-dir.mjs +361 -0
  11. package/{src/data/create-cache-id.ts → dist/data/create-cache-id.d.mts} +3 -7
  12. package/dist/data/create-cache-id.mjs +10 -0
  13. package/dist/data/delete-cache-item.d.mts +9 -0
  14. package/dist/data/delete-cache-item.mjs +411 -0
  15. package/dist/data/get-cache.d.mts +3 -0
  16. package/dist/data/get-cache.mjs +374 -0
  17. package/dist/data/get-or-create-cache.d.mts +9 -0
  18. package/dist/data/get-or-create-cache.mjs +400 -0
  19. package/dist/data/save-cache.d.mts +13 -0
  20. package/dist/data/save-cache.mjs +374 -0
  21. package/dist/data/write-cache-to-disk.d.mts +9 -0
  22. package/dist/data/write-cache-to-disk.mjs +408 -0
  23. package/dist/default-config.d.mts +7 -0
  24. package/dist/default-config.mjs +25 -0
  25. package/dist/flat-template-string.d.mts +14 -0
  26. package/dist/flat-template-string.mjs +16 -0
  27. package/dist/flat-template-string.test.d.mts +2 -0
  28. package/dist/flat-template-string.test.mjs +18479 -0
  29. package/dist/gringow.d.mts +9 -0
  30. package/dist/gringow.mjs +904 -0
  31. package/dist/index.d.mts +60 -0
  32. package/dist/index.mjs +926 -0
  33. package/dist/io/anthropic/ask.d.mts +5 -0
  34. package/dist/io/anthropic/ask.mjs +181 -0
  35. package/dist/io/anthropic/commit-response.d.mts +15 -0
  36. package/dist/io/anthropic/commit-response.mjs +10 -0
  37. package/dist/io/anthropic/index.d.mts +14 -0
  38. package/dist/io/anthropic/index.mjs +199 -0
  39. package/dist/io/anthropic/parse.d.mts +14 -0
  40. package/dist/io/anthropic/parse.mjs +10 -0
  41. package/dist/io/ask-llm.d.mts +13 -0
  42. package/dist/io/ask-llm.mjs +573 -0
  43. package/dist/io/gemini/ask.d.mts +5 -0
  44. package/dist/io/gemini/ask.mjs +206 -0
  45. package/dist/io/gemini/commit-response.d.mts +5 -0
  46. package/dist/io/gemini/commit-response.mjs +7 -0
  47. package/dist/io/gemini/index.d.mts +14 -0
  48. package/dist/io/gemini/index.mjs +222 -0
  49. package/dist/io/gemini/parse.d.mts +14 -0
  50. package/dist/io/gemini/parse.mjs +11 -0
  51. package/dist/io/huggingface/ask.d.mts +13 -0
  52. package/dist/io/huggingface/ask.mjs +397 -0
  53. package/dist/io/huggingface/commit-response.d.mts +27 -0
  54. package/dist/io/huggingface/commit-response.mjs +14 -0
  55. package/dist/io/huggingface/index.d.mts +13 -0
  56. package/dist/io/huggingface/index.mjs +418 -0
  57. package/dist/io/huggingface/languagesMap.d.mts +186 -0
  58. package/dist/io/huggingface/languagesMap.mjs +187 -0
  59. package/dist/io/huggingface/parse.d.mts +14 -0
  60. package/dist/io/huggingface/parse.mjs +9 -0
  61. package/dist/logger.d.mts +24 -0
  62. package/dist/logger.mjs +21 -0
  63. package/dist/schemas/config.shcema.d.mts +199 -0
  64. package/dist/schemas/config.shcema.mjs +52 -0
  65. package/dist/types/index.d.mts +28 -0
  66. package/dist/types/index.mjs +1 -0
  67. package/package.json +10 -1
  68. package/.nvmrc +0 -1
  69. package/gringow.json +0 -12
  70. package/src/browser.ts +0 -4
  71. package/src/config.ts +0 -93
  72. package/src/data/check-cache.ts +0 -15
  73. package/src/data/clear-cache.ts +0 -5
  74. package/src/data/create-cache-dir.ts +0 -7
  75. package/src/data/delete-cache-item.ts +0 -20
  76. package/src/data/get-cache.ts +0 -17
  77. package/src/data/get-or-create-cache.ts +0 -21
  78. package/src/data/save-cache.ts +0 -17
  79. package/src/data/write-cache-to-disk.ts +0 -20
  80. package/src/default-config.ts +0 -27
  81. package/src/flat-template-string.test.ts +0 -109
  82. package/src/flat-template-string.ts +0 -27
  83. package/src/gringow.ts +0 -49
  84. package/src/index.ts +0 -37
  85. package/src/io/anthropic/ask.ts +0 -31
  86. package/src/io/anthropic/commit-response.ts +0 -11
  87. package/src/io/anthropic/index.ts +0 -3
  88. package/src/io/anthropic/parse.ts +0 -11
  89. package/src/io/ask-llm.ts +0 -44
  90. package/src/io/gemini/ask.ts +0 -65
  91. package/src/io/gemini/commit-response.ts +0 -6
  92. package/src/io/gemini/index.ts +0 -3
  93. package/src/io/gemini/parse.ts +0 -12
  94. package/src/io/huggingface/ask.ts +0 -82
  95. package/src/io/huggingface/commit-response.ts +0 -16
  96. package/src/io/huggingface/index.ts +0 -16
  97. package/src/io/huggingface/languagesMap.ts +0 -189
  98. package/src/io/huggingface/parse.ts +0 -10
  99. package/src/logger.ts +0 -25
  100. package/src/schemas/config.shcema.ts +0 -58
  101. package/src/types/index.ts +0 -22
  102. package/tsconfig.json +0 -29
  103. package/tsup.config.ts +0 -21
  104. package/vitest.config.ts +0 -8
@@ -1,15 +0,0 @@
1
- import { getOrCreateCache } from '@/data/get-or-create-cache'
2
- import logger from '@/logger'
3
-
4
- import type { GringowCacheItem } from '@/index'
5
-
6
- export async function checkCache(cacheId: string): Promise<GringowCacheItem | undefined> {
7
- const cache = await getOrCreateCache()
8
-
9
- if (cache?.[cacheId]) {
10
- logger.debug(`Cache hit, id:${cacheId}`)
11
- return cache[cacheId]
12
- }
13
-
14
- return undefined
15
- }
@@ -1,5 +0,0 @@
1
- import { saveCache } from '@/data/save-cache'
2
-
3
- export async function clearCache() {
4
- await saveCache({})
5
- }
@@ -1,7 +0,0 @@
1
- import { mkdirp } from 'mkdirp'
2
- import { awaitedConfig } from '@/config'
3
-
4
- export async function createCacheDir() {
5
- const config = await awaitedConfig
6
- await mkdirp(config.cache.dir)
7
- }
@@ -1,20 +0,0 @@
1
- import { getOrCreateCache } from '@/data/get-or-create-cache'
2
- import { saveCache } from '@/data/save-cache'
3
-
4
- /**
5
- * Deletes a cache item.
6
- *
7
- * @param cacheId - The cache ID.
8
- * @returns The cache ID.
9
- */
10
- export async function deleteCacheItem(cacheId: string) {
11
- const rawCache = await getOrCreateCache()
12
- const cache = rawCache
13
- if (cache[cacheId]) {
14
- delete cache[cacheId]
15
- }
16
-
17
- await saveCache(cache)
18
-
19
- return cache
20
- }
@@ -1,17 +0,0 @@
1
- import fs from 'node:fs/promises'
2
-
3
- import { awaitedConfig } from '@/config'
4
- import { createCacheDir } from '@/data/create-cache-dir'
5
-
6
- import type { GringowError } from '@/index'
7
-
8
- export async function getCache(): Promise<string> {
9
- try {
10
- const config = await awaitedConfig
11
- await createCacheDir()
12
- const rawCache = await fs.readFile(`${config.cache.dir}/${config.cache.file}`)
13
- return rawCache.toString()
14
- } catch (error) {
15
- throw error as GringowError
16
- }
17
- }
@@ -1,21 +0,0 @@
1
- import { getCache } from '@/data/get-cache'
2
- import { saveCache } from '@/data/save-cache'
3
-
4
- import type { GringowCache, GringowError } from '@/index'
5
-
6
- export async function getOrCreateCache(): Promise<GringowCache> {
7
- let rawCache: string | undefined
8
-
9
- try {
10
- rawCache = await getCache()
11
- } catch (error: unknown) {
12
- if ((error as GringowError)?.code === 'ENOENT') {
13
- await saveCache({})
14
- rawCache = await getCache()
15
- } else {
16
- throw error as GringowError
17
- }
18
- }
19
-
20
- return rawCache ? JSON.parse(rawCache?.toString()) : {}
21
- }
@@ -1,17 +0,0 @@
1
- import fs from 'node:fs/promises'
2
- import { awaitedConfig } from '@/config'
3
- import { createCacheDir } from '@/data/create-cache-dir'
4
-
5
- import type { GringowCache, GringowError } from '@/index'
6
-
7
- export async function saveCache(cache: GringowCache) {
8
- try {
9
- const config = await awaitedConfig
10
- await createCacheDir()
11
-
12
- const contents = JSON.stringify(cache, null, 2)
13
- await fs.writeFile(`${config.cache.dir}/${config.cache.file}`, contents)
14
- } catch (error) {
15
- throw error as GringowError
16
- }
17
- }
@@ -1,20 +0,0 @@
1
- import { getOrCreateCache } from '@/data/get-or-create-cache'
2
- import { saveCache } from '@/data/save-cache'
3
-
4
- import type { GringowCacheItem } from '@/index'
5
-
6
- /**
7
- * Writes the cache to disk.
8
- *
9
- * @param cacheId - The cache ID.
10
- * @param cached - The cached function.
11
- * @returns The cache ID.
12
- */
13
- export async function writeCacheToDisk(cacheId: string, cached: GringowCacheItem) {
14
- const cache = await getOrCreateCache()
15
- cache[cacheId] = cached
16
-
17
- await saveCache(cache)
18
-
19
- return cache[cacheId]
20
- }
@@ -1,27 +0,0 @@
1
- import type { z } from 'zod'
2
- import type { configSchema } from '@/schemas/config.shcema'
3
-
4
- export type GringowConfig = z.infer<typeof configSchema>
5
-
6
- export const defaultConfig: GringowConfig = {
7
- debug: false,
8
- log: {
9
- level: 'debug',
10
- },
11
- cache: {
12
- dir: './gringow',
13
- file: 'gringow.json',
14
- prefix: 'grw',
15
- write: true,
16
- },
17
- keys: {},
18
- sourceLanguage: 'en-US',
19
- languages: ['pt-BR', 'fr-CA'],
20
- llm: {
21
- choice: 'huggingface',
22
- model: 'Xenova/nllb-200-distilled-600M',
23
- temperature: 1.0,
24
- sleep: 0,
25
- },
26
- globby: './src/**/*.{js,jsx,ts,tsx}',
27
- }
@@ -1,109 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
-
3
- import { flatTemplateString } from './flat-template-string'
4
-
5
- // Helper function to create a mock TemplateStringsArray
6
- function createTemplateStringsArray(strings: string[]): TemplateStringsArray {
7
- return Object.assign(strings, { raw: [...strings] })
8
- }
9
-
10
- describe('flatTemplateString', () => {
11
- it('should concatenate simple strings without values', () => {
12
- const result = flatTemplateString(createTemplateStringsArray(['Hello World']), [])
13
- expect(result).toBe('Hello World')
14
- })
15
-
16
- it('should interpolate simple values', () => {
17
- const result = flatTemplateString(createTemplateStringsArray(['Hello ', '!']), ['World'])
18
- expect(result).toBe('Hello World!')
19
- })
20
-
21
- it('should interpolate multiple values', () => {
22
- const result = flatTemplateString(createTemplateStringsArray(['Hello ', ', you are ', ' years old']), ['John', 25])
23
- expect(result).toBe('Hello John, you are 25 years old')
24
- })
25
-
26
- it('should handle null and undefined values', () => {
27
- const result = flatTemplateString(createTemplateStringsArray(['Value: ', ', null: ', ', undefined: ']), [
28
- null,
29
- null,
30
- undefined,
31
- ])
32
- expect(result).toBe('Value: null, null: null, undefined: undefined')
33
- })
34
-
35
- it('should convert numbers to string', () => {
36
- const result = flatTemplateString(createTemplateStringsArray(['Number: ', '']), [42])
37
- expect(result).toBe('Number: 42')
38
- })
39
-
40
- it('should convert booleans to string', () => {
41
- const result = flatTemplateString(createTemplateStringsArray(['Boolean: ', ', false: ']), [true, false])
42
- expect(result).toBe('Boolean: true, false: false')
43
- })
44
-
45
- it('should handle objects by converting to string', () => {
46
- const obj = { name: 'John', age: 30 }
47
- const result = flatTemplateString(createTemplateStringsArray(['Object: ', '']), [obj])
48
- expect(result).toBe('Object: [object Object]')
49
- })
50
-
51
- it('should handle arrays by converting to string', () => {
52
- const arr = [1, 2, 3]
53
- const result = flatTemplateString(createTemplateStringsArray(['Array: ', '']), [arr])
54
- expect(result).toBe('Array: 1,2,3')
55
- })
56
-
57
- it('should handle empty strings', () => {
58
- const result = flatTemplateString(createTemplateStringsArray(['', 'middle', '']), ['start', 'end'])
59
- expect(result).toBe('startmiddleend')
60
- })
61
-
62
- it('should handle complex template string', () => {
63
- const name = 'Alice'
64
- const age = 28
65
- const city = 'São Paulo'
66
-
67
- const result = flatTemplateString(
68
- createTemplateStringsArray(['Olá, meu nome é ', ', tenho ', ' anos e moro em ', '.']),
69
- [name, age, city]
70
- )
71
-
72
- expect(result).toBe('Olá, meu nome é Alice, tenho 28 anos e moro em São Paulo.')
73
- })
74
-
75
- it('should handle values that are empty strings', () => {
76
- const result = flatTemplateString(createTemplateStringsArray(['Start', 'Middle', 'End']), ['', ''])
77
- expect(result).toBe('StartMiddleEnd')
78
- })
79
-
80
- it('should preserve whitespace and line breaks', () => {
81
- const result = flatTemplateString(createTemplateStringsArray(['Line 1\n', 'Line 2\n', 'Line 3']), ['', ''])
82
- expect(result).toBe('Line 1\nLine 2\nLine 3')
83
- })
84
-
85
- it('should handle special characters', () => {
86
- const result = flatTemplateString(createTemplateStringsArray(['Special: ', '']), ['@#$%^&*()'])
87
- expect(result).toBe('Special: @#$%^&*()')
88
- })
89
-
90
- it('should handle emojis', () => {
91
- const result = flatTemplateString(createTemplateStringsArray(['Hello ', '!']), ['👋'])
92
- expect(result).toBe('Hello 👋!')
93
- })
94
-
95
- it('should handle template string without values (strings only)', () => {
96
- const result = flatTemplateString(createTemplateStringsArray(['Apenas', 'texto', 'simples']), [])
97
- expect(result).toBe('Apenastextosimples')
98
- })
99
-
100
- it('should handle more values than strings', () => {
101
- const result = flatTemplateString(createTemplateStringsArray(['Start', 'End']), ['Middle1', 'Middle2', 'Extra'])
102
- expect(result).toBe('StartMiddle1EndMiddle2')
103
- })
104
-
105
- it('should handle fewer values than strings', () => {
106
- const result = flatTemplateString(createTemplateStringsArray(['Start', 'Middle', 'End']), ['Value'])
107
- expect(result).toBe('StartValueMiddleEnd')
108
- })
109
- })
@@ -1,27 +0,0 @@
1
- /**
2
- * Flattens a template string with its values into a single flat string
3
- *
4
- * @param givenStrings - The template strings
5
- * @param givenValues - The values to be interpolated
6
- * @returns The flattened string
7
- *
8
- * @example
9
- * const result = flatTemplateString`Hello ${name}!`
10
- * // result = 'Hello John!'
11
- */
12
- export function flatTemplateString(givenStrings: TemplateStringsArray, givenValues: Array<unknown>) {
13
- const strings = [...givenStrings.raw]
14
- const values = [...givenValues]
15
-
16
- const flatted = strings.reduce((acc: string, item: string, index: number) => {
17
- acc += String(item ?? '')
18
- if (index < values.length) {
19
- const value = values[index]
20
- // Preserve null and undefined as strings, but handle other falsy values
21
- acc += String(value ?? '')
22
- }
23
- return acc
24
- }, '')
25
-
26
- return flatted
27
- }
package/src/gringow.ts DELETED
@@ -1,49 +0,0 @@
1
- import { awaitedConfig } from '@/config'
2
- import { checkCache } from '@/data/check-cache'
3
- import { createCacheId } from '@/data/create-cache-id'
4
- import { writeCacheToDisk } from '@/data/write-cache-to-disk'
5
- import { flatTemplateString } from '@/flat-template-string'
6
- import { askLLM } from '@/io/ask-llm'
7
-
8
- import type { GringowResponse } from '.'
9
-
10
- /**
11
- * Gringow is a function that translates a string or a template string into a
12
- * translated string.
13
- *
14
- * @param strings - The string or template string to translate.
15
- * @param values - The values to interpolate into the string.
16
- * @returns The translated string.
17
- */
18
- async function Gringow(strings: TemplateStringsArray | string, ...values: Array<unknown>): Promise<GringowResponse> {
19
- const config = await awaitedConfig
20
-
21
- // flat template string
22
- let flatten: string
23
- if (typeof strings === 'string') {
24
- flatten = String(strings ?? '')
25
- } else {
26
- flatten = flatTemplateString(strings, values)
27
- }
28
-
29
- // create cache id
30
- const cacheId = createCacheId(flatten)
31
-
32
- // check cache
33
- const cached = await checkCache(cacheId)
34
- if (cached !== undefined && cached.original !== 'undefined') {
35
- return { cacheId, translation: cached }
36
- }
37
-
38
- // ask LLM
39
- const translation = await askLLM(flatten)
40
-
41
- if (config.cache.write) {
42
- // write cache to disk
43
- await writeCacheToDisk(cacheId, translation)
44
- }
45
-
46
- return { cacheId, translation }
47
- }
48
-
49
- export { Gringow }
package/src/index.ts DELETED
@@ -1,37 +0,0 @@
1
- import '@/config'
2
-
3
- export type GringowTranslation = {
4
- [key: string]: string
5
- }
6
-
7
- export type GringowCacheItem = {
8
- original: string
9
- translation: GringowTranslation
10
- }
11
-
12
- export type GringowCache = {
13
- [key: string]: GringowCacheItem
14
- }
15
-
16
- export type GringowResponse = {
17
- cacheId: string
18
- translation: GringowCacheItem
19
- }
20
-
21
- export type GringowError = Error & {
22
- code?: string
23
- cause?: Error
24
- }
25
-
26
- export { awaitedConfig, getConfigSource, isLocalConfigFound } from '@/config'
27
- export { checkCache } from '@/data/check-cache'
28
- export { clearCache } from '@/data/clear-cache'
29
- export { createCacheId } from '@/data/create-cache-id'
30
- export { deleteCacheItem } from '@/data/delete-cache-item'
31
- export { getCache } from '@/data/get-cache'
32
- export { getOrCreateCache } from '@/data/get-or-create-cache'
33
- export { writeCacheToDisk } from '@/data/write-cache-to-disk'
34
- export { flatTemplateString } from '@/flat-template-string'
35
- export { Gringow as default } from '@/gringow'
36
-
37
- export type { GringowConfig } from '@/default-config'
@@ -1,31 +0,0 @@
1
- import Anthropic from '@anthropic-ai/sdk'
2
- import { awaitedConfig } from '@/config'
3
-
4
- export async function askAnthropic(message: string) {
5
- const config = await awaitedConfig
6
- if (Number(config.llm.sleep)) {
7
- await new Promise((resolve) => setTimeout(resolve, config.llm.sleep ?? 1))
8
- }
9
-
10
- if (!config.keys.anthropicApiKey) {
11
- throw new Error('Anthropic API key is not set in the config')
12
- }
13
-
14
- const anthropic = new Anthropic({
15
- apiKey: config.keys.anthropicApiKey,
16
- dangerouslyAllowBrowser: true,
17
- })
18
-
19
- const response = await anthropic.messages.create({
20
- model: config.llm.model as Anthropic.Model,
21
- max_tokens: 1024,
22
- messages: [
23
- {
24
- role: 'user',
25
- content: `${config.llm.prePrompt}\n\n\n${message}\n\n\n${config.llm.postPrompt}`,
26
- },
27
- ],
28
- })
29
-
30
- return response as Anthropic.Messages.Message
31
- }
@@ -1,11 +0,0 @@
1
- import type { Anthropic } from '@anthropic-ai/sdk'
2
- import type { CommitResponse } from '@/types'
3
-
4
- export function commitResponseAnthropic(response: Anthropic.Messages.Message) {
5
- const result = response.content.reduce((acc: string, item: Anthropic.Messages.ContentBlock) => {
6
- const nextAcc = acc + (item.type === 'text' ? item.text : '')
7
- return nextAcc
8
- }, '')
9
-
10
- return result as CommitResponse
11
- }
@@ -1,3 +0,0 @@
1
- export * from './ask'
2
- export * from './commit-response'
3
- export * from './parse'
@@ -1,11 +0,0 @@
1
- import type { GringowCacheItem } from '@/index'
2
- import type { CommitResponse } from '@/types'
3
-
4
- export function parseAnthropic(unparsed: CommitResponse): GringowCacheItem {
5
- if (typeof unparsed !== 'string') {
6
- throw new Error('CommitResponse should be a string here.')
7
- }
8
-
9
- const parsed = JSON.parse(unparsed) as GringowCacheItem
10
- return parsed
11
- }
package/src/io/ask-llm.ts DELETED
@@ -1,44 +0,0 @@
1
- import { awaitedConfig } from '@/config'
2
- import { askAnthropic, commitResponseAnthropic, parseAnthropic } from './anthropic'
3
- import { askGemini, commitResponseGemini, parseGemini } from './gemini'
4
- import { askHuggingface, commitResponseHuggingface, parseHuggingface } from './huggingface'
5
-
6
- import type { GringowCacheItem } from '@/index'
7
- import type { LLMChoice, LLMChoices, LLMOptions } from '@/types'
8
-
9
- const llmChoices: LLMChoices = {
10
- anthropic: {
11
- ask: askAnthropic,
12
- commitResponse: commitResponseAnthropic,
13
- parse: parseAnthropic,
14
- },
15
- gemini: {
16
- ask: askGemini,
17
- commitResponse: commitResponseGemini,
18
- parse: parseGemini,
19
- },
20
- huggingface: {
21
- ask: askHuggingface,
22
- commitResponse: commitResponseHuggingface,
23
- parse: parseHuggingface,
24
- },
25
- }
26
-
27
- async function processChoice<T = { test: number }>(choice: LLMChoice<T>, prompt: string): Promise<GringowCacheItem> {
28
- const response = await choice.ask(prompt)
29
- const unparsed = choice.commitResponse(response)
30
- const parsed = choice.parse(unparsed)
31
- return parsed
32
- }
33
-
34
- export async function askLLM(prompt: string): Promise<GringowCacheItem> {
35
- const config = await awaitedConfig
36
- const llmChoiceName = config.llm.choice as LLMOptions
37
- const llmChoice = llmChoices[llmChoiceName]
38
-
39
- if (!llmChoice) {
40
- throw new Error('LLMChoice not found')
41
- }
42
-
43
- return processChoice<Awaited<ReturnType<typeof llmChoice.ask>>>(llmChoice, prompt)
44
- }
@@ -1,65 +0,0 @@
1
- import { type GenerateContentResult, GoogleGenerativeAI } from '@google/generative-ai'
2
-
3
- import { awaitedConfig } from '@/config'
4
-
5
- async function generateResponse(message: string, temperature: number = 1.0) {
6
- const config = await awaitedConfig
7
- if (!config.keys.geminiApiKey) {
8
- throw new Error('Gemini API key is not set in the config')
9
- }
10
-
11
- const generativeAIClient = new GoogleGenerativeAI(config.keys.geminiApiKey)
12
- const model = generativeAIClient.getGenerativeModel({
13
- model: config.llm.model as string,
14
- generationConfig: {
15
- temperature,
16
- },
17
- })
18
-
19
- const prompt = String(`${config.llm.prePrompt}\n\n\n${message}\n\n\n${config.llm.postPrompt}`).trim()
20
- if (config.debug) {
21
- console.log('Gemini model prompt:', JSON.stringify({ prompt }))
22
- }
23
-
24
- const response = await model.generateContent([prompt])
25
-
26
- return response
27
- }
28
-
29
- export async function askGemini(message: string) {
30
- const config = await awaitedConfig
31
- if (Number(config.llm.sleep)) {
32
- await new Promise((resolve) => setTimeout(resolve, config.llm.sleep ?? 1))
33
- }
34
-
35
- if (!config.keys.geminiApiKey) {
36
- throw new Error('Gemini API key is not set in the config')
37
- }
38
-
39
- if (config.debug) {
40
- console.log('\nAsking Gemini model:', JSON.stringify({ model: config.llm.model, message }))
41
- }
42
-
43
- let response: GenerateContentResult | undefined
44
- for (let i = 0; i < 3; i++) {
45
- const maybeResponse = await generateResponse(message, config.llm.temperature)
46
- if (!String(maybeResponse.response.candidates?.[0]?.content?.parts?.[0]?.text ?? '').includes('```json')) {
47
- response = maybeResponse
48
- break
49
- }
50
-
51
- if (config.debug) {
52
- console.log('Gemini model response is not valid, contains no JSON:', JSON.stringify({ maybeResponse }))
53
- }
54
- }
55
-
56
- if (config.debug) {
57
- console.log('Gemini model response:', JSON.stringify({ response }))
58
- }
59
-
60
- if (!response) {
61
- throw new Error('Gemini model response is not valid')
62
- }
63
-
64
- return response
65
- }
@@ -1,6 +0,0 @@
1
- import type { GenerateContentResult } from '@google/generative-ai'
2
-
3
- export function commitResponseGemini(response: GenerateContentResult): string {
4
- const result = response.response.text()
5
- return result
6
- }
@@ -1,3 +0,0 @@
1
- export * from './ask'
2
- export * from './commit-response'
3
- export * from './parse'
@@ -1,12 +0,0 @@
1
- import type { GringowCacheItem } from '@/index'
2
- import type { CommitResponse } from '@/types'
3
-
4
- export function parseGemini(unparsed: CommitResponse): GringowCacheItem {
5
- if (typeof unparsed !== 'string') {
6
- throw new Error('CommitResponse should be a string here.')
7
- }
8
-
9
- const cleaned = unparsed.replace(/```json/g, '').replace(/```/g, '')
10
- const parsed = JSON.parse(cleaned) as GringowCacheItem
11
- return parsed
12
- }
@@ -1,82 +0,0 @@
1
- import {
2
- env,
3
- type ProgressInfo,
4
- pipeline,
5
- type TranslationPipeline,
6
- type TranslationSingle,
7
- } from '@huggingface/transformers'
8
- import 'node:fs'
9
-
10
- import { awaitedConfig } from '@/config'
11
- import { languagesMap } from './languagesMap'
12
-
13
- import type { AskHuggingfaceResponse, AskHuggingfaceResponseTranslation } from '@/io/huggingface'
14
-
15
- function getLanguageCode(language: string) {
16
- return languagesMap[language as keyof typeof languagesMap]
17
- }
18
-
19
- function progressCallback(progress: ProgressInfo) {
20
- process.stdout.clearLine(0)
21
- process.stdout.cursorTo(0)
22
- if (progress.status === 'download') {
23
- process.stdout.write('Downloading...')
24
- } else if (progress.status === 'initiate') {
25
- process.stdout.write('Initializing...')
26
- } else if (progress.status === 'done') {
27
- process.stdout.write('Done!')
28
- } else if (progress.status === 'progress' && 'progress' in progress && 'loaded' in progress && 'total' in progress) {
29
- process.stdout.write(
30
- `Downloading: ${Number(progress.progress).toFixed(2)}%, loaded: ${progress.loaded}/${progress.total}`
31
- )
32
- }
33
- }
34
-
35
- async function pipeLanguage(pipe: TranslationPipeline, original: string, srcLanguage: string, targetLanguage: string) {
36
- const response = await pipe(original, {
37
- src_lang: srcLanguage,
38
- tgt_lang: targetLanguage,
39
- temperature: 1.0,
40
- } as Parameters<TranslationPipeline['call']>[1])
41
-
42
- return response
43
- }
44
-
45
- export async function askHuggingface(original: string) {
46
- const config = await awaitedConfig
47
- const cacheDir = `${config.cache.dir}/.cache`
48
- env.cacheDir = cacheDir
49
-
50
- const pipe = await pipeline('translation', config.llm.model as string, {
51
- progress_callback: progressCallback,
52
- cache_dir: cacheDir,
53
- })
54
-
55
- const { languages } = config
56
-
57
- let responses: AskHuggingfaceResponseTranslation[] = []
58
- for await (const language of languages) {
59
- const response = await pipeLanguage(
60
- pipe,
61
- original,
62
- getLanguageCode(config.sourceLanguage),
63
- getLanguageCode(language)
64
- )
65
-
66
- if (Array.isArray(response)) {
67
- responses = responses.concat(
68
- response.map((r) => ({
69
- ...r,
70
- targetLanguage: language,
71
- })) as AskHuggingfaceResponseTranslation[]
72
- )
73
- } else {
74
- responses.push({
75
- ...(response as TranslationSingle),
76
- targetLanguage: language,
77
- } as AskHuggingfaceResponseTranslation)
78
- }
79
- }
80
-
81
- return { responses, original } as AskHuggingfaceResponse
82
- }