@gringow/gringow 0.1.3 → 0.2.0
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/README.md +279 -43
- package/dist/config.d.mts +7 -8
- package/dist/config.mjs +32 -20
- package/dist/config.test.mjs +39 -25
- package/dist/constants/default-config.mjs +4 -3
- package/dist/data/check-cache.mjs +33 -63
- package/dist/data/clear-cache.mjs +32 -20
- package/dist/data/create-cache-dir.mjs +32 -20
- package/dist/data/delete-cache-item.mjs +32 -20
- package/dist/data/get-cache.mjs +32 -20
- package/dist/data/get-or-create-cache.mjs +32 -20
- package/dist/data/save-cache.mjs +32 -20
- package/dist/data/write-cache-to-disk.mjs +32 -20
- package/dist/gringow.mjs +84 -491
- package/dist/index.mjs +84 -491
- package/dist/io/ask-llm.d.mts +3 -1
- package/dist/io/ask-llm.mjs +77 -449
- package/dist/schemas/config.shcema.d.mts +40 -47
- package/dist/schemas/config.shcema.mjs +26 -15
- package/dist/types/index.d.mts +3 -25
- package/gringow.config.js.example +2 -4
- package/gringow.config.json.example +4 -2
- package/package.json +2 -5
- package/dist/io/anthropic/ask.d.mts +0 -11
- package/dist/io/anthropic/ask.mjs +0 -190
- package/dist/io/anthropic/commit-response.d.mts +0 -21
- package/dist/io/anthropic/commit-response.mjs +0 -10
- package/dist/io/anthropic/index.d.mts +0 -14
- package/dist/io/anthropic/index.mjs +0 -208
- package/dist/io/anthropic/parse.d.mts +0 -20
- package/dist/io/anthropic/parse.mjs +0 -10
- package/dist/io/gemini/ask.d.mts +0 -11
- package/dist/io/gemini/ask.mjs +0 -232
- package/dist/io/gemini/commit-response.d.mts +0 -11
- package/dist/io/gemini/commit-response.mjs +0 -7
- package/dist/io/gemini/index.d.mts +0 -14
- package/dist/io/gemini/index.mjs +0 -248
- package/dist/io/gemini/parse.d.mts +0 -20
- package/dist/io/gemini/parse.mjs +0 -11
- package/dist/io/huggingface/ask.d.mts +0 -13
- package/dist/io/huggingface/ask.mjs +0 -405
- package/dist/io/huggingface/commit-response.d.mts +0 -39
- package/dist/io/huggingface/commit-response.mjs +0 -14
- package/dist/io/huggingface/index.d.mts +0 -13
- package/dist/io/huggingface/index.mjs +0 -426
- package/dist/io/huggingface/languages-map.d.mts +0 -191
- package/dist/io/huggingface/languages-map.mjs +0 -187
- package/dist/io/huggingface/parse.d.mts +0 -20
- package/dist/io/huggingface/parse.mjs +0 -9
package/README.md
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
# @gringow/gringow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@gringow/gringow)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
AI-powered translation library for template strings using multiple LLM providers (Hugging Face, Anthropic, Gemini). Gringow provides smart caching, deterministic content hashing, and seamless integration for modern JavaScript/TypeScript projects.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🌍 **Multi-language translation** using LLM providers
|
|
11
|
+
- 🏷️ **Tagged template literal** syntax for inline translations
|
|
12
|
+
- 💾 **Smart caching** with content-based hashing
|
|
13
|
+
- 🔌 **Three LLM providers**: Hugging Face (local), Anthropic, Gemini
|
|
14
|
+
- 🚀 **Zero configuration** - works out of the box with Hugging Face
|
|
15
|
+
- 📦 **Optimized builds** via Vite/Next.js plugins
|
|
4
16
|
|
|
5
17
|
## Installation
|
|
6
18
|
|
|
@@ -12,45 +24,90 @@ pnpm add @gringow/gringow
|
|
|
12
24
|
yarn add @gringow/gringow
|
|
13
25
|
```
|
|
14
26
|
|
|
15
|
-
##
|
|
27
|
+
## Quick Start
|
|
16
28
|
|
|
17
29
|
```typescript
|
|
18
|
-
import Gringow
|
|
30
|
+
import Gringow from '@gringow/gringow'
|
|
19
31
|
|
|
20
32
|
// Simple string translation
|
|
21
33
|
const { cacheId, translation } = await Gringow`Hello world`
|
|
22
|
-
console.log(
|
|
23
|
-
|
|
34
|
+
console.log(translation.translation)
|
|
35
|
+
// => { "pt-BR": "Olá mundo", "fr-CA": "Bonjour le monde" }
|
|
24
36
|
|
|
25
|
-
// Template string
|
|
37
|
+
// Template string with dynamic values
|
|
26
38
|
const name = 'John'
|
|
27
|
-
const { translation:
|
|
28
|
-
console.log(
|
|
39
|
+
const { translation: result } = await Gringow`Welcome, ${name}!`
|
|
40
|
+
console.log(result.translation)
|
|
41
|
+
// => { "pt-BR": "Bem-vindo, John!", "fr-CA": "Bienvenue, John!" }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage Examples
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
### Basic Translation
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import Gringow from '@gringow/gringow'
|
|
50
|
+
|
|
51
|
+
// Translate a static string
|
|
52
|
+
const { translation } = await Gringow`Hello world`
|
|
53
|
+
console.log(translation.translation['pt-BR']) // "Olá mundo"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Dynamic Content
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// Template literals are flattened before hashing - dynamic values preserved
|
|
60
|
+
const user = { name: 'Alice', role: 'admin' }
|
|
61
|
+
const { translation } = await Gringow`User ${user.name} has ${user.role} privileges`
|
|
62
|
+
|
|
63
|
+
console.log(translation.translation['pt-BR'])
|
|
64
|
+
// => "Usuário Alice tem privilégios de admin"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Cache Management
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import Gringow, { rebuild, checkCache } from '@gringow/gringow'
|
|
71
|
+
|
|
72
|
+
const { cacheId } = await Gringow`Hello world`
|
|
73
|
+
|
|
74
|
+
// Check if translation exists in cache
|
|
75
|
+
const cached = await checkCache(cacheId)
|
|
76
|
+
console.log(cached) // GringowCacheItem or undefined
|
|
77
|
+
|
|
78
|
+
// Force re-translation by rebuilding cache entry
|
|
31
79
|
const refreshed = await rebuild(cacheId)
|
|
32
80
|
console.log(refreshed.translation.translation)
|
|
33
81
|
```
|
|
34
82
|
|
|
35
|
-
|
|
36
|
-
|
|
83
|
+
### Browser Usage
|
|
84
|
+
|
|
85
|
+
For client-side interpolation without Node.js dependencies:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { interpolateTemplate } from '@gringow/gringow/browser'
|
|
89
|
+
|
|
90
|
+
const template = 'Hello {name}, you have {count} messages'
|
|
91
|
+
const result = interpolateTemplate(template, { name: 'Alice', count: 5 })
|
|
92
|
+
console.log(result) // "Hello Alice, you have 5 messages"
|
|
93
|
+
```
|
|
37
94
|
|
|
38
95
|
## Configuration
|
|
39
96
|
|
|
40
|
-
Gringow
|
|
41
|
-
|
|
42
|
-
|
|
97
|
+
Gringow uses [cosmiconfig](https://github.com/cosmiconfig/cosmiconfig) to load configuration from your project root. Supported formats: `gringow.config.js`, `gringow.config.mjs`, `gringow.config.json`, or a `gringow` field in `package.json`.
|
|
98
|
+
|
|
99
|
+
### Default Configuration
|
|
43
100
|
|
|
44
101
|
```js
|
|
45
102
|
// gringow.config.js
|
|
46
103
|
export default {
|
|
47
104
|
debug: false,
|
|
48
|
-
log: { level: '
|
|
105
|
+
log: { level: 'info' },
|
|
49
106
|
cache: {
|
|
50
107
|
dir: './gringow',
|
|
51
108
|
file: 'gringow.json',
|
|
52
109
|
prefix: 'grw',
|
|
53
|
-
write: true,
|
|
110
|
+
write: true,
|
|
54
111
|
},
|
|
55
112
|
keys: {
|
|
56
113
|
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
|
@@ -63,35 +120,171 @@ export default {
|
|
|
63
120
|
model: 'Xenova/nllb-200-distilled-600M',
|
|
64
121
|
temperature: 1.0,
|
|
65
122
|
sleep: 0,
|
|
66
|
-
// Prompt shaping (all optional)
|
|
67
|
-
prePrompt: undefined,
|
|
68
|
-
postPrompt: undefined,
|
|
69
|
-
prePromptAppend: undefined,
|
|
70
|
-
postPromptPrepend: undefined,
|
|
71
|
-
prePromptReplace: undefined,
|
|
72
|
-
postPromptReplace: undefined,
|
|
73
123
|
},
|
|
74
|
-
// Files scanned by the Vite/Next.js plugins when building caches
|
|
75
124
|
globby: './src/**/*.{js,jsx,ts,tsx}',
|
|
76
125
|
}
|
|
77
126
|
```
|
|
78
127
|
|
|
79
|
-
|
|
128
|
+
### Example: Using Gemini
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
// gringow.config.js
|
|
132
|
+
export default {
|
|
133
|
+
keys: {
|
|
134
|
+
geminiApiKey: process.env.GEMINI_API_KEY,
|
|
135
|
+
},
|
|
136
|
+
llm: {
|
|
137
|
+
choice: 'gemini',
|
|
138
|
+
model: 'gemini-2.0-flash',
|
|
139
|
+
prePromptAppend: 'Please respond in a friendly tone.',
|
|
140
|
+
},
|
|
141
|
+
languages: ['es-ES', 'de-DE', 'ja-JP'],
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Example: Using Anthropic
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
// gringow.config.js
|
|
149
|
+
export default {
|
|
150
|
+
keys: {
|
|
151
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
|
152
|
+
},
|
|
153
|
+
llm: {
|
|
154
|
+
choice: 'anthropic',
|
|
155
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
156
|
+
temperature: 0.7,
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Prompt Customization
|
|
162
|
+
|
|
163
|
+
Fine-tune LLM behavior with prompt options:
|
|
164
|
+
|
|
165
|
+
```js
|
|
166
|
+
export default {
|
|
167
|
+
llm: {
|
|
168
|
+
choice: 'huggingface',
|
|
169
|
+
prePrompt: 'Translate the following text:', // Default prompt prefix
|
|
170
|
+
postPrompt: 'Ensure translations are natural.', // Additional context
|
|
171
|
+
prePromptAppend: 'Use formal language.', // Appended to pre-prompt
|
|
172
|
+
postPromptPrepend: 'Maintain original formatting.', // Prepended to post-prompt
|
|
173
|
+
prePromptReplace: 'Custom instruction here', // Replaces entire pre-prompt
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
```
|
|
80
177
|
|
|
81
178
|
## LLM Providers
|
|
82
179
|
|
|
83
|
-
|
|
84
|
-
- **Anthropic**: Requires `keys.anthropicApiKey`.
|
|
85
|
-
- **Gemini**: Requires `keys.geminiApiKey`.
|
|
180
|
+
### Hugging Face (Default)
|
|
86
181
|
|
|
87
|
-
|
|
182
|
+
Runs local models via `@huggingface/transformers`. **No API key required.**
|
|
183
|
+
|
|
184
|
+
```js
|
|
185
|
+
// gringow.config.js
|
|
186
|
+
export default {
|
|
187
|
+
llm: {
|
|
188
|
+
choice: 'huggingface',
|
|
189
|
+
model: 'Xenova/nllb-200-distilled-600M', // Multilingual translation model
|
|
190
|
+
},
|
|
191
|
+
}
|
|
192
|
+
```
|
|
88
193
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- Cache helpers: `checkCache`, `getCache`, `getOrCreateCache`, `writeCacheToDisk`, `deleteCacheItem`, `clearCache`.
|
|
92
|
-
- Utilities: `createCacheId`, `flatTemplateString`, `interpolateTemplate` (browser build), `awaitedConfig`, `isLocalConfigFound`, `getConfigSource`.
|
|
194
|
+
**Pros**: Free, private, offline-capable
|
|
195
|
+
**Cons**: Slower first run (model download), higher memory usage
|
|
93
196
|
|
|
94
|
-
|
|
197
|
+
### Anthropic
|
|
198
|
+
|
|
199
|
+
Uses Claude models via Anthropic API. **Requires API key.**
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
// gringow.config.js
|
|
203
|
+
export default {
|
|
204
|
+
keys: {
|
|
205
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
|
206
|
+
},
|
|
207
|
+
llm: {
|
|
208
|
+
choice: 'anthropic',
|
|
209
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Pros**: High-quality translations, fast
|
|
215
|
+
**Cons**: API costs, requires internet
|
|
216
|
+
|
|
217
|
+
### Gemini
|
|
218
|
+
|
|
219
|
+
Uses Google's Gemini models. **Requires API key.**
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
// gringow.config.js
|
|
223
|
+
export default {
|
|
224
|
+
keys: {
|
|
225
|
+
geminiApiKey: process.env.GEMINI_API_KEY,
|
|
226
|
+
},
|
|
227
|
+
llm: {
|
|
228
|
+
choice: 'gemini',
|
|
229
|
+
model: 'gemini-2.0-flash',
|
|
230
|
+
},
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Pros**: Fast, cost-effective
|
|
235
|
+
**Cons**: API costs, requires internet
|
|
236
|
+
|
|
237
|
+
## API Reference
|
|
238
|
+
|
|
239
|
+
### Core Functions
|
|
240
|
+
|
|
241
|
+
#### `Gringow(strings, ...values): Promise<GringowResponse>`
|
|
242
|
+
|
|
243
|
+
Main translation function. Accepts tagged template literals or plain strings.
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
const result = await Gringow`Hello ${name}`
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Returns**: `Promise<GringowResponse>` with `{ cacheId, translation }`
|
|
250
|
+
|
|
251
|
+
#### `rebuild(cacheId: string): Promise<GringowResponse>`
|
|
252
|
+
|
|
253
|
+
Re-translates a cached entry using the current LLM configuration.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
const refreshed = await rebuild('grw_abc123')
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Cache Helpers
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import {
|
|
263
|
+
checkCache, // Check if cacheId exists
|
|
264
|
+
getCache, // Get entire cache object
|
|
265
|
+
getOrCreateCache,// Get cache or create empty one
|
|
266
|
+
writeCacheToDisk,// Manually write cache entry
|
|
267
|
+
deleteCacheItem, // Remove cache entry
|
|
268
|
+
clearCache, // Clear all cache entries
|
|
269
|
+
} from '@gringow/gringow'
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Utilities
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import {
|
|
276
|
+
createCacheId, // Generate cache ID from string
|
|
277
|
+
flatTemplateString, // Flatten template literal to string
|
|
278
|
+
interpolateTemplate, // Browser-safe interpolation (from /browser export)
|
|
279
|
+
awaitedConfig, // Access resolved configuration
|
|
280
|
+
isLocalConfigFound, // Check if local config exists
|
|
281
|
+
getConfigSource, // Get config file path
|
|
282
|
+
} from '@gringow/gringow'
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Type Definitions
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
95
288
|
type GringowTranslation = Record<string, string>
|
|
96
289
|
|
|
97
290
|
type GringowCacheItem = {
|
|
@@ -108,22 +301,65 @@ type GringowResponse = {
|
|
|
108
301
|
}
|
|
109
302
|
```
|
|
110
303
|
|
|
304
|
+
## How It Works
|
|
305
|
+
|
|
306
|
+
1. **Input Processing**: Template strings are flattened to plain text (preserving dynamic values)
|
|
307
|
+
2. **Cache ID Generation**: Content-based hash created using `createCacheId()`
|
|
308
|
+
3. **Cache Lookup**: Check `./gringow/gringow.json` for existing translation
|
|
309
|
+
4. **LLM Query**: If not cached, request translation from configured provider
|
|
310
|
+
5. **Response Parsing**: Parse provider response to `GringowCacheItem` format
|
|
311
|
+
6. **Cache Storage**: Write to disk when `cache.write` is `true`
|
|
312
|
+
|
|
313
|
+
**Example cache structure:**
|
|
314
|
+
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"grw_a1b2c3": {
|
|
318
|
+
"original": "Hello world",
|
|
319
|
+
"translation": {
|
|
320
|
+
"pt-BR": "Olá mundo",
|
|
321
|
+
"fr-CA": "Bonjour le monde"
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
111
327
|
## Development
|
|
112
328
|
|
|
113
329
|
```bash
|
|
330
|
+
# Install dependencies
|
|
114
331
|
pnpm install
|
|
115
|
-
|
|
116
|
-
|
|
332
|
+
|
|
333
|
+
# Build the package
|
|
334
|
+
pnpm run build
|
|
335
|
+
|
|
336
|
+
# Run tests
|
|
337
|
+
pnpm run test
|
|
338
|
+
|
|
339
|
+
# Watch mode
|
|
340
|
+
pnpm run test:watch
|
|
117
341
|
```
|
|
118
342
|
|
|
343
|
+
## Integrations
|
|
344
|
+
|
|
345
|
+
Gringow has official integrations for modern web frameworks:
|
|
346
|
+
|
|
347
|
+
- **[@gringow/cli](https://www.npmjs.com/package/@gringow/gringow-cli)** - Command-line interface for cache management and translations
|
|
348
|
+
- **[@gringow/gringow-vite](https://www.npmjs.com/package/@gringow/gringow-vite)** - Vite plugin for build-time translation extraction
|
|
349
|
+
- **[@gringow/gringow-react](https://www.npmjs.com/package/@gringow/gringow-react)** - React hooks and components
|
|
350
|
+
- **[@gringow/gringow-shadow](https://www.npmjs.com/package/@gringow/gringow-shadow)** - Web Component layer (vanilla JS)
|
|
351
|
+
- **[@gringow/gringow-nextjs](https://www.npmjs.com/package/@gringow/gringow-nextjs)** - Next.js plugin (experimental)
|
|
352
|
+
|
|
353
|
+
## Related Resources
|
|
354
|
+
|
|
355
|
+
- [Documentation](https://gringow.dev)
|
|
356
|
+
- [GitHub Repository](https://github.com/rntgspr/gringow)
|
|
357
|
+
- [Examples](https://github.com/rntgspr/gringow/tree/main/example-gringow-vite)
|
|
358
|
+
|
|
119
359
|
## License
|
|
120
360
|
|
|
121
|
-
MIT
|
|
361
|
+
MIT © [Renato Gaspar](https://github.com/rntgspr)
|
|
122
362
|
|
|
123
|
-
|
|
363
|
+
---
|
|
124
364
|
|
|
125
|
-
|
|
126
|
-
- [@gringow/gringow-shadow](https://www.npmjs.com/package/@gringow/gringow-shadow) - Web Component layer powering the React bindings
|
|
127
|
-
- [@gringow/gringow-react](https://www.npmjs.com/package/@gringow/gringow-react) - React bindings
|
|
128
|
-
- [@gringow/gringow-vite](https://www.npmjs.com/package/@gringow/gringow-vite) - Vite plugin
|
|
129
|
-
- [@gringow/gringow-nextjs](https://www.npmjs.com/package/@gringow/gringow-nextjs) - Experimental Next.js plugin
|
|
365
|
+
**Questions or Issues?** Open an issue on [GitHub](https://github.com/rntgspr/gringow/issues)
|
package/dist/config.d.mts
CHANGED
|
@@ -26,10 +26,6 @@ declare function loadUserConfig(): Promise<GringowConfig>;
|
|
|
26
26
|
* @returns The user configuration.
|
|
27
27
|
*/
|
|
28
28
|
declare const awaitedConfig: Promise<{
|
|
29
|
-
keys: {
|
|
30
|
-
anthropicApiKey?: string | undefined;
|
|
31
|
-
geminiApiKey?: string | undefined;
|
|
32
|
-
};
|
|
33
29
|
log: {
|
|
34
30
|
level: "debug" | "info" | "warn" | "error" | "trace";
|
|
35
31
|
};
|
|
@@ -40,14 +36,17 @@ declare const awaitedConfig: Promise<{
|
|
|
40
36
|
write?: boolean | undefined;
|
|
41
37
|
};
|
|
42
38
|
sourceLanguage: string;
|
|
39
|
+
defaultLanguage: string;
|
|
43
40
|
languages: string[];
|
|
44
41
|
llm: {
|
|
45
|
-
|
|
42
|
+
provider: "anthropic" | "gemini" | "openai" | "groq" | "mistral" | "ollama" | "xai" | "deepseek" | "openrouter" | "cerebras" | "lmstudio" | "azure" | "meta";
|
|
46
43
|
model: string | null;
|
|
47
|
-
temperature?: number | undefined;
|
|
48
|
-
sleep?: number | undefined;
|
|
49
44
|
prePrompt?: string | undefined;
|
|
50
45
|
postPrompt?: string | undefined;
|
|
46
|
+
apiKey?: string | undefined;
|
|
47
|
+
baseURL?: string | undefined;
|
|
48
|
+
temperature?: number | undefined;
|
|
49
|
+
sleep?: number | undefined;
|
|
51
50
|
prePromptReplace?: string | undefined;
|
|
52
51
|
postPromptReplace?: string | undefined;
|
|
53
52
|
prePromptAppend?: string | undefined;
|
|
@@ -58,7 +57,7 @@ declare const awaitedConfig: Promise<{
|
|
|
58
57
|
}>;
|
|
59
58
|
declare function defaultPrePrompt(config: GringowConfig, extraInstructions?: string): string;
|
|
60
59
|
declare function defaultPostPrompt(_config: GringowConfig): string;
|
|
61
|
-
declare function prePrompt(config: GringowConfig,
|
|
60
|
+
declare function prePrompt(config: GringowConfig, prepend?: string, replace?: string): string;
|
|
62
61
|
declare function postPrompt(config: GringowConfig, prepend?: string, replace?: string): string;
|
|
63
62
|
|
|
64
63
|
export { awaitedConfig, defaultPostPrompt, defaultPrePrompt, getConfigSource, isLocalConfigFound, loadUserConfig, postPrompt, prePrompt };
|
package/dist/config.mjs
CHANGED
|
@@ -16,19 +16,34 @@ var defaultConfig = {
|
|
|
16
16
|
prefix: "grw",
|
|
17
17
|
write: true
|
|
18
18
|
},
|
|
19
|
-
keys: {},
|
|
20
19
|
sourceLanguage: "en-US",
|
|
20
|
+
defaultLanguage: "pt-BR",
|
|
21
21
|
languages: ["pt-BR", "fr-CA"],
|
|
22
22
|
llm: {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
provider: "openai",
|
|
24
|
+
apiKey: void 0,
|
|
25
|
+
model: "gpt-4o-mini",
|
|
25
26
|
temperature: 1,
|
|
26
27
|
sleep: 0
|
|
27
28
|
},
|
|
28
29
|
globby: "./src/**/*.{js,jsx,ts,tsx}"
|
|
29
30
|
};
|
|
30
31
|
var languageSchema = z.string().regex(/^[a-z]{2,3}(-[A-Z]{2})?$/);
|
|
31
|
-
var
|
|
32
|
+
var llmProviderSchema = z.enum([
|
|
33
|
+
"anthropic",
|
|
34
|
+
"gemini",
|
|
35
|
+
"openai",
|
|
36
|
+
"groq",
|
|
37
|
+
"mistral",
|
|
38
|
+
"ollama",
|
|
39
|
+
"xai",
|
|
40
|
+
"deepseek",
|
|
41
|
+
"openrouter",
|
|
42
|
+
"cerebras",
|
|
43
|
+
"lmstudio",
|
|
44
|
+
"azure",
|
|
45
|
+
"meta"
|
|
46
|
+
]);
|
|
32
47
|
var configSchema = z.object({
|
|
33
48
|
debug: z.boolean().optional(),
|
|
34
49
|
log: z.object({
|
|
@@ -40,14 +55,13 @@ var configSchema = z.object({
|
|
|
40
55
|
prefix: z.string(),
|
|
41
56
|
write: z.boolean().optional()
|
|
42
57
|
}),
|
|
43
|
-
keys: z.object({
|
|
44
|
-
anthropicApiKey: z.string().optional(),
|
|
45
|
-
geminiApiKey: z.string().optional()
|
|
46
|
-
}),
|
|
47
58
|
sourceLanguage: languageSchema,
|
|
59
|
+
defaultLanguage: languageSchema,
|
|
48
60
|
languages: z.array(languageSchema),
|
|
49
61
|
llm: z.object({
|
|
50
|
-
|
|
62
|
+
provider: llmProviderSchema,
|
|
63
|
+
apiKey: z.string().optional(),
|
|
64
|
+
baseURL: z.string().optional(),
|
|
51
65
|
model: z.string().nullable(),
|
|
52
66
|
temperature: z.number().optional(),
|
|
53
67
|
sleep: z.number().optional(),
|
|
@@ -61,17 +75,15 @@ var configSchema = z.object({
|
|
|
61
75
|
globby: z.string().regex(/^\.\/.*/).optional()
|
|
62
76
|
}).refine(
|
|
63
77
|
(data) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (data.llm.choice === "anthropic" && !data.keys.anthropicApiKey) {
|
|
68
|
-
return false;
|
|
78
|
+
const noApiKeyRequired = ["ollama", "lmstudio"];
|
|
79
|
+
if (noApiKeyRequired.includes(data.llm.provider)) {
|
|
80
|
+
return true;
|
|
69
81
|
}
|
|
70
|
-
return
|
|
82
|
+
return !!data.llm.apiKey;
|
|
71
83
|
},
|
|
72
84
|
{
|
|
73
|
-
message: "The API key
|
|
74
|
-
path: ["
|
|
85
|
+
message: "The API key must be present in llm.apiKey for the chosen provider.",
|
|
86
|
+
path: ["llm", "apiKey"]
|
|
75
87
|
}
|
|
76
88
|
);
|
|
77
89
|
|
|
@@ -113,7 +125,7 @@ Your task is to translate a given text and output **only one valid JSON object**
|
|
|
113
125
|
|
|
114
126
|
Follow these rules strictly:
|
|
115
127
|
|
|
116
|
-
1. The original text is written in English.
|
|
128
|
+
1. The original text is written in English or Spanish.
|
|
117
129
|
2. You will receive additional user parameters under the variable 'extraInstructions'. These may specify tone, persona, style, context, or any relevant translation guideline.
|
|
118
130
|
- Examples: \u201Ctranslate as if you were a Shakespearean narrator\u201D or \u201Cuse a formal business tone suitable for a corporate presentation.\u201D
|
|
119
131
|
- Apply these creatively but **without altering the meaning or punctuation** of the original text.
|
|
@@ -146,10 +158,10 @@ Translate the following text faithfully:
|
|
|
146
158
|
function defaultPostPrompt(_config) {
|
|
147
159
|
return "";
|
|
148
160
|
}
|
|
149
|
-
function prePrompt(config,
|
|
161
|
+
function prePrompt(config, prepend, replace) {
|
|
150
162
|
return [
|
|
151
163
|
// ...(append ? ['[SPECIFIC_INPUTS]', String(append), '[/SPECIFIC_INPUTS]'] : []),
|
|
152
|
-
replace ? String(replace) : defaultPrePrompt(config,
|
|
164
|
+
replace ? String(replace) : defaultPrePrompt(config, prepend)
|
|
153
165
|
].join(" ").trim();
|
|
154
166
|
}
|
|
155
167
|
function postPrompt(config, prepend, replace) {
|
package/dist/config.test.mjs
CHANGED
|
@@ -18133,19 +18133,34 @@ var defaultConfig = {
|
|
|
18133
18133
|
prefix: "grw",
|
|
18134
18134
|
write: true
|
|
18135
18135
|
},
|
|
18136
|
-
keys: {},
|
|
18137
18136
|
sourceLanguage: "en-US",
|
|
18137
|
+
defaultLanguage: "pt-BR",
|
|
18138
18138
|
languages: ["pt-BR", "fr-CA"],
|
|
18139
18139
|
llm: {
|
|
18140
|
-
|
|
18141
|
-
|
|
18140
|
+
provider: "openai",
|
|
18141
|
+
apiKey: void 0,
|
|
18142
|
+
model: "gpt-4o-mini",
|
|
18142
18143
|
temperature: 1,
|
|
18143
18144
|
sleep: 0
|
|
18144
18145
|
},
|
|
18145
18146
|
globby: "./src/**/*.{js,jsx,ts,tsx}"
|
|
18146
18147
|
};
|
|
18147
18148
|
var languageSchema = z.string().regex(/^[a-z]{2,3}(-[A-Z]{2})?$/);
|
|
18148
|
-
var
|
|
18149
|
+
var llmProviderSchema = z.enum([
|
|
18150
|
+
"anthropic",
|
|
18151
|
+
"gemini",
|
|
18152
|
+
"openai",
|
|
18153
|
+
"groq",
|
|
18154
|
+
"mistral",
|
|
18155
|
+
"ollama",
|
|
18156
|
+
"xai",
|
|
18157
|
+
"deepseek",
|
|
18158
|
+
"openrouter",
|
|
18159
|
+
"cerebras",
|
|
18160
|
+
"lmstudio",
|
|
18161
|
+
"azure",
|
|
18162
|
+
"meta"
|
|
18163
|
+
]);
|
|
18149
18164
|
var configSchema = z.object({
|
|
18150
18165
|
debug: z.boolean().optional(),
|
|
18151
18166
|
log: z.object({
|
|
@@ -18157,14 +18172,13 @@ var configSchema = z.object({
|
|
|
18157
18172
|
prefix: z.string(),
|
|
18158
18173
|
write: z.boolean().optional()
|
|
18159
18174
|
}),
|
|
18160
|
-
keys: z.object({
|
|
18161
|
-
anthropicApiKey: z.string().optional(),
|
|
18162
|
-
geminiApiKey: z.string().optional()
|
|
18163
|
-
}),
|
|
18164
18175
|
sourceLanguage: languageSchema,
|
|
18176
|
+
defaultLanguage: languageSchema,
|
|
18165
18177
|
languages: z.array(languageSchema),
|
|
18166
18178
|
llm: z.object({
|
|
18167
|
-
|
|
18179
|
+
provider: llmProviderSchema,
|
|
18180
|
+
apiKey: z.string().optional(),
|
|
18181
|
+
baseURL: z.string().optional(),
|
|
18168
18182
|
model: z.string().nullable(),
|
|
18169
18183
|
temperature: z.number().optional(),
|
|
18170
18184
|
sleep: z.number().optional(),
|
|
@@ -18178,17 +18192,15 @@ var configSchema = z.object({
|
|
|
18178
18192
|
globby: z.string().regex(/^\.\/.*/).optional()
|
|
18179
18193
|
}).refine(
|
|
18180
18194
|
(data) => {
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
if (data.llm.choice === "anthropic" && !data.keys.anthropicApiKey) {
|
|
18185
|
-
return false;
|
|
18195
|
+
const noApiKeyRequired = ["ollama", "lmstudio"];
|
|
18196
|
+
if (noApiKeyRequired.includes(data.llm.provider)) {
|
|
18197
|
+
return true;
|
|
18186
18198
|
}
|
|
18187
|
-
return
|
|
18199
|
+
return !!data.llm.apiKey;
|
|
18188
18200
|
},
|
|
18189
18201
|
{
|
|
18190
|
-
message: "The API key
|
|
18191
|
-
path: ["
|
|
18202
|
+
message: "The API key must be present in llm.apiKey for the chosen provider.",
|
|
18203
|
+
path: ["llm", "apiKey"]
|
|
18192
18204
|
}
|
|
18193
18205
|
);
|
|
18194
18206
|
|
|
@@ -18224,7 +18236,7 @@ Your task is to translate a given text and output **only one valid JSON object**
|
|
|
18224
18236
|
|
|
18225
18237
|
Follow these rules strictly:
|
|
18226
18238
|
|
|
18227
|
-
1. The original text is written in English.
|
|
18239
|
+
1. The original text is written in English or Spanish.
|
|
18228
18240
|
2. You will receive additional user parameters under the variable 'extraInstructions'. These may specify tone, persona, style, context, or any relevant translation guideline.
|
|
18229
18241
|
- Examples: \u201Ctranslate as if you were a Shakespearean narrator\u201D or \u201Cuse a formal business tone suitable for a corporate presentation.\u201D
|
|
18230
18242
|
- Apply these creatively but **without altering the meaning or punctuation** of the original text.
|
|
@@ -18257,10 +18269,10 @@ Translate the following text faithfully:
|
|
|
18257
18269
|
function defaultPostPrompt(_config) {
|
|
18258
18270
|
return "";
|
|
18259
18271
|
}
|
|
18260
|
-
function prePrompt(config2,
|
|
18272
|
+
function prePrompt(config2, prepend, replace) {
|
|
18261
18273
|
return [
|
|
18262
18274
|
// ...(append ? ['[SPECIFIC_INPUTS]', String(append), '[/SPECIFIC_INPUTS]'] : []),
|
|
18263
|
-
replace ? String(replace) : defaultPrePrompt(config2,
|
|
18275
|
+
replace ? String(replace) : defaultPrePrompt(config2, prepend)
|
|
18264
18276
|
].join(" ").trim();
|
|
18265
18277
|
}
|
|
18266
18278
|
function postPrompt(config2, prepend, replace) {
|
|
@@ -18279,9 +18291,11 @@ describe("config", () => {
|
|
|
18279
18291
|
languages: ["pt-BR", "fr-CA", "es-ES"]
|
|
18280
18292
|
};
|
|
18281
18293
|
const result2 = defaultPrePrompt(config2);
|
|
18282
|
-
globalExpect(result2).toContain("You are a translation generator.");
|
|
18283
|
-
globalExpect(result2).toContain("Your task is to output **only one valid JSON object**");
|
|
18284
|
-
globalExpect(result2).toContain("pt-BR
|
|
18294
|
+
globalExpect(result2).toContain("You are a ultimate translation generator server api.");
|
|
18295
|
+
globalExpect(result2).toContain("Your task is to translate a given text and output **only one valid JSON object**");
|
|
18296
|
+
globalExpect(result2).toContain("pt-BR");
|
|
18297
|
+
globalExpect(result2).toContain("fr-CA");
|
|
18298
|
+
globalExpect(result2).toContain("es-ES");
|
|
18285
18299
|
globalExpect(result2).toContain('"original": "<original input text>"');
|
|
18286
18300
|
globalExpect(result2).toContain('"translation": {');
|
|
18287
18301
|
});
|
|
@@ -18319,7 +18333,7 @@ describe("config", () => {
|
|
|
18319
18333
|
};
|
|
18320
18334
|
const result2 = prePrompt(config2, "Additional instructions");
|
|
18321
18335
|
globalExpect(result2).toContain("extraInstructions: Additional instructions");
|
|
18322
|
-
globalExpect(result2).toContain("You are a translation generator.");
|
|
18336
|
+
globalExpect(result2).toContain("You are a ultimate translation generator server api.");
|
|
18323
18337
|
});
|
|
18324
18338
|
it("should use prePromptReplace and prePromptAppend together", () => {
|
|
18325
18339
|
const config2 = {
|
|
@@ -18333,7 +18347,7 @@ describe("config", () => {
|
|
|
18333
18347
|
...defaultConfig
|
|
18334
18348
|
};
|
|
18335
18349
|
const result2 = prePrompt(config2);
|
|
18336
|
-
globalExpect(result2).toContain("You are a translation generator.");
|
|
18350
|
+
globalExpect(result2).toContain("You are a ultimate translation generator server api.");
|
|
18337
18351
|
globalExpect(result2).toContain("Translate the following text faithfully:");
|
|
18338
18352
|
});
|
|
18339
18353
|
});
|
|
@@ -10,12 +10,13 @@ var defaultConfig = {
|
|
|
10
10
|
prefix: "grw",
|
|
11
11
|
write: true
|
|
12
12
|
},
|
|
13
|
-
keys: {},
|
|
14
13
|
sourceLanguage: "en-US",
|
|
14
|
+
defaultLanguage: "pt-BR",
|
|
15
15
|
languages: ["pt-BR", "fr-CA"],
|
|
16
16
|
llm: {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
provider: "openai",
|
|
18
|
+
apiKey: void 0,
|
|
19
|
+
model: "gpt-4o-mini",
|
|
19
20
|
temperature: 1,
|
|
20
21
|
sleep: 0
|
|
21
22
|
},
|