@gringow/gringow 0.0.8 → 0.1.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.
@@ -54,12 +54,12 @@ var configSchema = z.object({
54
54
  model: z.string().nullable(),
55
55
  temperature: z.number().optional(),
56
56
  sleep: z.number().optional(),
57
- prePrompt: z.string().optional(),
58
- postPrompt: z.string().optional(),
57
+ prePrompt: z.string().max(128).optional(),
58
+ postPrompt: z.string().max(128).optional(),
59
59
  prePromptReplace: z.string().optional(),
60
60
  postPromptReplace: z.string().optional(),
61
61
  prePromptAppend: z.string().optional(),
62
- postPromptAppend: z.string().optional()
62
+ postPromptPrepend: z.string().optional()
63
63
  }),
64
64
  globby: z.string().regex(/^\.\/.*/).optional()
65
65
  }).refine(
@@ -85,8 +85,16 @@ async function loadUserConfig() {
85
85
  try {
86
86
  const mergedConfig = merge({}, defaultConfig, result?.config);
87
87
  const parsedConfig = await configSchema.parseAsync(mergedConfig);
88
- parsedConfig.llm.prePrompt = prePrompt(parsedConfig);
89
- parsedConfig.llm.postPrompt = postPrompt(parsedConfig);
88
+ parsedConfig.llm.prePrompt = prePrompt(
89
+ parsedConfig,
90
+ parsedConfig.llm.prePromptAppend ?? "",
91
+ parsedConfig.llm.prePromptReplace ?? ""
92
+ );
93
+ parsedConfig.llm.postPrompt = postPrompt(
94
+ parsedConfig,
95
+ parsedConfig.llm.postPromptPrepend ?? "",
96
+ parsedConfig.llm.postPromptReplace ?? ""
97
+ );
90
98
  return parsedConfig;
91
99
  } catch (error) {
92
100
  console.warn(`${error?.message}, using default configuration`);
@@ -135,16 +143,16 @@ function defaultPostPrompt(_config) {
135
143
  [/POST-MESSAGE]
136
144
  `;
137
145
  }
138
- function prePrompt(config) {
146
+ function prePrompt(config, append, replace) {
139
147
  return [
140
- config.llm.prePromptReplace ? `${config.llm.prePromptReplace}` : defaultPrePrompt(config),
141
- config.llm.prePromptAppend ? ` ${config.llm.prePromptAppend}` : ""
148
+ ...append ? ["[SPECIFIC_INPUTS]", String(append), "[/SPECIFIC_INPUTS]"] : [],
149
+ replace ? String(replace) : defaultPrePrompt(config)
142
150
  ].join(" ").trim();
143
151
  }
144
- function postPrompt(config) {
152
+ function postPrompt(config, prepend, replace) {
145
153
  return [
146
- config?.llm?.postPromptReplace ? `${config.llm.postPromptReplace}` : defaultPostPrompt(),
147
- config.llm.postPromptAppend ? ` ${config.llm.postPromptAppend}` : ""
154
+ ...prepend ? ["[SPECIFIC_INPUTS]", String(prepend), "[/SPECIFIC_INPUTS]"] : [],
155
+ replace ? String(replace) : defaultPostPrompt()
148
156
  ].join(" ").trim();
149
157
  }
150
158
  var optsArg = (opts) => {
@@ -54,12 +54,12 @@ var configSchema = z.object({
54
54
  model: z.string().nullable(),
55
55
  temperature: z.number().optional(),
56
56
  sleep: z.number().optional(),
57
- prePrompt: z.string().optional(),
58
- postPrompt: z.string().optional(),
57
+ prePrompt: z.string().max(128).optional(),
58
+ postPrompt: z.string().max(128).optional(),
59
59
  prePromptReplace: z.string().optional(),
60
60
  postPromptReplace: z.string().optional(),
61
61
  prePromptAppend: z.string().optional(),
62
- postPromptAppend: z.string().optional()
62
+ postPromptPrepend: z.string().optional()
63
63
  }),
64
64
  globby: z.string().regex(/^\.\/.*/).optional()
65
65
  }).refine(
@@ -85,8 +85,16 @@ async function loadUserConfig() {
85
85
  try {
86
86
  const mergedConfig = merge({}, defaultConfig, result?.config);
87
87
  const parsedConfig = await configSchema.parseAsync(mergedConfig);
88
- parsedConfig.llm.prePrompt = prePrompt(parsedConfig);
89
- parsedConfig.llm.postPrompt = postPrompt(parsedConfig);
88
+ parsedConfig.llm.prePrompt = prePrompt(
89
+ parsedConfig,
90
+ parsedConfig.llm.prePromptAppend ?? "",
91
+ parsedConfig.llm.prePromptReplace ?? ""
92
+ );
93
+ parsedConfig.llm.postPrompt = postPrompt(
94
+ parsedConfig,
95
+ parsedConfig.llm.postPromptPrepend ?? "",
96
+ parsedConfig.llm.postPromptReplace ?? ""
97
+ );
90
98
  return parsedConfig;
91
99
  } catch (error) {
92
100
  console.warn(`${error?.message}, using default configuration`);
@@ -135,16 +143,16 @@ function defaultPostPrompt(_config) {
135
143
  [/POST-MESSAGE]
136
144
  `;
137
145
  }
138
- function prePrompt(config) {
146
+ function prePrompt(config, append, replace) {
139
147
  return [
140
- config.llm.prePromptReplace ? `${config.llm.prePromptReplace}` : defaultPrePrompt(config),
141
- config.llm.prePromptAppend ? ` ${config.llm.prePromptAppend}` : ""
148
+ ...append ? ["[SPECIFIC_INPUTS]", String(append), "[/SPECIFIC_INPUTS]"] : [],
149
+ replace ? String(replace) : defaultPrePrompt(config)
142
150
  ].join(" ").trim();
143
151
  }
144
- function postPrompt(config) {
152
+ function postPrompt(config, prepend, replace) {
145
153
  return [
146
- config?.llm?.postPromptReplace ? `${config.llm.postPromptReplace}` : defaultPostPrompt(),
147
- config.llm.postPromptAppend ? ` ${config.llm.postPromptAppend}` : ""
154
+ ...prepend ? ["[SPECIFIC_INPUTS]", String(prepend), "[/SPECIFIC_INPUTS]"] : [],
155
+ replace ? String(replace) : defaultPostPrompt()
148
156
  ].join(" ").trim();
149
157
  }
150
158
  var optsArg = (opts) => {
@@ -54,12 +54,12 @@ var configSchema = z.object({
54
54
  model: z.string().nullable(),
55
55
  temperature: z.number().optional(),
56
56
  sleep: z.number().optional(),
57
- prePrompt: z.string().optional(),
58
- postPrompt: z.string().optional(),
57
+ prePrompt: z.string().max(128).optional(),
58
+ postPrompt: z.string().max(128).optional(),
59
59
  prePromptReplace: z.string().optional(),
60
60
  postPromptReplace: z.string().optional(),
61
61
  prePromptAppend: z.string().optional(),
62
- postPromptAppend: z.string().optional()
62
+ postPromptPrepend: z.string().optional()
63
63
  }),
64
64
  globby: z.string().regex(/^\.\/.*/).optional()
65
65
  }).refine(
@@ -85,8 +85,16 @@ async function loadUserConfig() {
85
85
  try {
86
86
  const mergedConfig = merge({}, defaultConfig, result?.config);
87
87
  const parsedConfig = await configSchema.parseAsync(mergedConfig);
88
- parsedConfig.llm.prePrompt = prePrompt(parsedConfig);
89
- parsedConfig.llm.postPrompt = postPrompt(parsedConfig);
88
+ parsedConfig.llm.prePrompt = prePrompt(
89
+ parsedConfig,
90
+ parsedConfig.llm.prePromptAppend ?? "",
91
+ parsedConfig.llm.prePromptReplace ?? ""
92
+ );
93
+ parsedConfig.llm.postPrompt = postPrompt(
94
+ parsedConfig,
95
+ parsedConfig.llm.postPromptPrepend ?? "",
96
+ parsedConfig.llm.postPromptReplace ?? ""
97
+ );
90
98
  return parsedConfig;
91
99
  } catch (error) {
92
100
  console.warn(`${error?.message}, using default configuration`);
@@ -135,16 +143,16 @@ function defaultPostPrompt(_config) {
135
143
  [/POST-MESSAGE]
136
144
  `;
137
145
  }
138
- function prePrompt(config) {
146
+ function prePrompt(config, append, replace) {
139
147
  return [
140
- config.llm.prePromptReplace ? `${config.llm.prePromptReplace}` : defaultPrePrompt(config),
141
- config.llm.prePromptAppend ? ` ${config.llm.prePromptAppend}` : ""
148
+ ...append ? ["[SPECIFIC_INPUTS]", String(append), "[/SPECIFIC_INPUTS]"] : [],
149
+ replace ? String(replace) : defaultPrePrompt(config)
142
150
  ].join(" ").trim();
143
151
  }
144
- function postPrompt(config) {
152
+ function postPrompt(config, prepend, replace) {
145
153
  return [
146
- config?.llm?.postPromptReplace ? `${config.llm.postPromptReplace}` : defaultPostPrompt(),
147
- config.llm.postPromptAppend ? ` ${config.llm.postPromptAppend}` : ""
154
+ ...prepend ? ["[SPECIFIC_INPUTS]", String(prepend), "[/SPECIFIC_INPUTS]"] : [],
155
+ replace ? String(replace) : defaultPostPrompt()
148
156
  ].join(" ").trim();
149
157
  }
150
158
  var optsArg = (opts) => {
@@ -39,7 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
39
39
  mod
40
40
  ));
41
41
 
42
- // ../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.4/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
42
+ // ../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
43
43
  function encodeInteger(builder, num, relative2) {
44
44
  let delta = num - relative2;
45
45
  delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
@@ -78,7 +78,7 @@ function encode(decoded) {
78
78
  }
79
79
  var comma2, semicolon, chars2, intToChar2, charToInt2, bufLength, td, StringWriter;
80
80
  var init_sourcemap_codec = __esm({
81
- "../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.4/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs"() {
81
+ "../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs"() {
82
82
  comma2 = ",".charCodeAt(0);
83
83
  semicolon = ";".charCodeAt(0);
84
84
  chars2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -126,7 +126,7 @@ var init_sourcemap_codec = __esm({
126
126
  }
127
127
  });
128
128
 
129
- // ../node_modules/.pnpm/magic-string@0.30.17/node_modules/magic-string/dist/magic-string.es.mjs
129
+ // ../node_modules/.pnpm/magic-string@0.30.19/node_modules/magic-string/dist/magic-string.es.mjs
130
130
  var magic_string_es_exports = {};
131
131
  __export(magic_string_es_exports, {
132
132
  Bundle: () => Bundle,
@@ -202,7 +202,7 @@ function getLocator(source) {
202
202
  }
203
203
  var BitSet, Chunk, btoa, SourceMap, toString4, wordRegex, Mappings, n, warned, MagicString, hasOwnProp, Bundle;
204
204
  var init_magic_string_es = __esm({
205
- "../node_modules/.pnpm/magic-string@0.30.17/node_modules/magic-string/dist/magic-string.es.mjs"() {
205
+ "../node_modules/.pnpm/magic-string@0.30.19/node_modules/magic-string/dist/magic-string.es.mjs"() {
206
206
  init_sourcemap_codec();
207
207
  BitSet = class _BitSet {
208
208
  constructor(arg) {
@@ -573,6 +573,9 @@ var init_magic_string_es = __esm({
573
573
  }
574
574
  if (chunk.outro.length) mappings.advance(chunk.outro);
575
575
  });
576
+ if (this.outro) {
577
+ mappings.advance(this.outro);
578
+ }
576
579
  return {
577
580
  file: options.file ? options.file.split(/[/\\]/).pop() : void 0,
578
581
  sources: [
@@ -930,10 +933,13 @@ var init_magic_string_es = __esm({
930
933
  _split(index) {
931
934
  if (this.byStart[index] || this.byEnd[index]) return;
932
935
  let chunk = this.lastSearchedChunk;
936
+ let previousChunk = chunk;
933
937
  const searchForward = index > chunk.end;
934
938
  while (chunk) {
935
939
  if (chunk.contains(index)) return this._splitChunk(chunk, index);
936
940
  chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
941
+ if (chunk === previousChunk) return;
942
+ previousChunk = chunk;
937
943
  }
938
944
  }
939
945
  _splitChunk(chunk, index) {
@@ -1080,7 +1086,12 @@ var init_magic_string_es = __esm({
1080
1086
  const { original } = this;
1081
1087
  const index = original.indexOf(string2);
1082
1088
  if (index !== -1) {
1083
- this.overwrite(index, index + string2.length, replacement);
1089
+ if (typeof replacement === "function") {
1090
+ replacement = replacement(string2, index, original);
1091
+ }
1092
+ if (string2 !== replacement) {
1093
+ this.overwrite(index, index + string2.length, replacement);
1094
+ }
1084
1095
  }
1085
1096
  return this;
1086
1097
  }
@@ -1095,7 +1106,11 @@ var init_magic_string_es = __esm({
1095
1106
  const stringLength = string2.length;
1096
1107
  for (let index = original.indexOf(string2); index !== -1; index = original.indexOf(string2, index + stringLength)) {
1097
1108
  const previous = original.slice(index, index + stringLength);
1098
- if (previous !== replacement) this.overwrite(index, index + stringLength, replacement);
1109
+ let _replacement = replacement;
1110
+ if (typeof replacement === "function") {
1111
+ _replacement = replacement(previous, index, original);
1112
+ }
1113
+ if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);
1099
1114
  }
1100
1115
  return this;
1101
1116
  }
@@ -1,4 +1,4 @@
1
- export { default as Gringow } from './index.mjs';
1
+ export { default as Gringow, rebuild } from './index.mjs';
2
2
  import './config.mjs';
3
3
  import './constants/default-config.mjs';
4
4
  import 'zod';
package/dist/gringow.mjs CHANGED
@@ -58,12 +58,12 @@ var configSchema = z.object({
58
58
  model: z.string().nullable(),
59
59
  temperature: z.number().optional(),
60
60
  sleep: z.number().optional(),
61
- prePrompt: z.string().optional(),
62
- postPrompt: z.string().optional(),
61
+ prePrompt: z.string().max(128).optional(),
62
+ postPrompt: z.string().max(128).optional(),
63
63
  prePromptReplace: z.string().optional(),
64
64
  postPromptReplace: z.string().optional(),
65
65
  prePromptAppend: z.string().optional(),
66
- postPromptAppend: z.string().optional()
66
+ postPromptPrepend: z.string().optional()
67
67
  }),
68
68
  globby: z.string().regex(/^\.\/.*/).optional()
69
69
  }).refine(
@@ -89,8 +89,16 @@ async function loadUserConfig() {
89
89
  try {
90
90
  const mergedConfig = merge({}, defaultConfig, result?.config);
91
91
  const parsedConfig = await configSchema.parseAsync(mergedConfig);
92
- parsedConfig.llm.prePrompt = prePrompt(parsedConfig);
93
- parsedConfig.llm.postPrompt = postPrompt(parsedConfig);
92
+ parsedConfig.llm.prePrompt = prePrompt(
93
+ parsedConfig,
94
+ parsedConfig.llm.prePromptAppend ?? "",
95
+ parsedConfig.llm.prePromptReplace ?? ""
96
+ );
97
+ parsedConfig.llm.postPrompt = postPrompt(
98
+ parsedConfig,
99
+ parsedConfig.llm.postPromptPrepend ?? "",
100
+ parsedConfig.llm.postPromptReplace ?? ""
101
+ );
94
102
  return parsedConfig;
95
103
  } catch (error) {
96
104
  console.warn(`${error?.message}, using default configuration`);
@@ -139,16 +147,16 @@ function defaultPostPrompt(_config) {
139
147
  [/POST-MESSAGE]
140
148
  `;
141
149
  }
142
- function prePrompt(config) {
150
+ function prePrompt(config, append, replace) {
143
151
  return [
144
- config.llm.prePromptReplace ? `${config.llm.prePromptReplace}` : defaultPrePrompt(config),
145
- config.llm.prePromptAppend ? ` ${config.llm.prePromptAppend}` : ""
152
+ ...append ? ["[SPECIFIC_INPUTS]", String(append), "[/SPECIFIC_INPUTS]"] : [],
153
+ replace ? String(replace) : defaultPrePrompt(config)
146
154
  ].join(" ").trim();
147
155
  }
148
- function postPrompt(config) {
156
+ function postPrompt(config, prepend, replace) {
149
157
  return [
150
- config?.llm?.postPromptReplace ? `${config.llm.postPromptReplace}` : defaultPostPrompt(),
151
- config.llm.postPromptAppend ? ` ${config.llm.postPromptAppend}` : ""
158
+ ...prepend ? ["[SPECIFIC_INPUTS]", String(prepend), "[/SPECIFIC_INPUTS]"] : [],
159
+ replace ? String(replace) : defaultPostPrompt()
152
160
  ].join(" ").trim();
153
161
  }
154
162
  var optsArg = (opts) => {
@@ -480,7 +488,7 @@ function flatTemplateString(givenStrings, givenValues) {
480
488
  }, "");
481
489
  return flatted;
482
490
  }
483
- async function askAnthropic(message) {
491
+ async function askAnthropic(prompt, prePrompt2, postPrompt2) {
484
492
  const config = await awaitedConfig;
485
493
  if (Number(config.llm.sleep)) {
486
494
  await new Promise((resolve2) => setTimeout(resolve2, config.llm.sleep ?? 1));
@@ -492,19 +500,20 @@ async function askAnthropic(message) {
492
500
  apiKey: config.keys.anthropicApiKey,
493
501
  dangerouslyAllowBrowser: true
494
502
  });
503
+ const fullPrompt = String(`${prePrompt2}
504
+
505
+
506
+ ${prompt}
507
+
508
+
509
+ ${postPrompt2}`).trim();
495
510
  const response = await anthropic.messages.create({
496
511
  model: config.llm.model,
497
512
  max_tokens: 1024,
498
513
  messages: [
499
514
  {
500
515
  role: "user",
501
- content: `${config.llm.prePrompt}
502
-
503
-
504
- ${message}
505
-
506
-
507
- ${config.llm.postPrompt}`
516
+ content: fullPrompt
508
517
  }
509
518
  ]
510
519
  });
@@ -528,7 +537,7 @@ function parseAnthropic(unparsed) {
528
537
  const parsed = JSON.parse(unparsed);
529
538
  return parsed;
530
539
  }
531
- async function generateResponse(message, temperature = 1) {
540
+ async function generateResponse(prompt, temperature = 1) {
532
541
  const config = await awaitedConfig;
533
542
  if (!config.keys.geminiApiKey) {
534
543
  throw new Error("Gemini API key is not set in the config");
@@ -540,20 +549,13 @@ async function generateResponse(message, temperature = 1) {
540
549
  temperature
541
550
  }
542
551
  });
543
- const prompt = String(`${config.llm.prePrompt}
544
-
545
-
546
- ${message}
547
-
548
-
549
- ${config.llm.postPrompt}`).trim();
550
552
  if (config.debug) {
551
553
  console.log("Gemini model prompt:", JSON.stringify({ prompt }));
552
554
  }
553
555
  const response = await model.generateContent([prompt]);
554
556
  return response;
555
557
  }
556
- async function askGemini(message) {
558
+ async function askGemini(prompt, prePrompt2, postPrompt2) {
557
559
  const config = await awaitedConfig;
558
560
  if (Number(config.llm.sleep)) {
559
561
  await new Promise((resolve2) => setTimeout(resolve2, config.llm.sleep ?? 1));
@@ -562,11 +564,18 @@ async function askGemini(message) {
562
564
  throw new Error("Gemini API key is not set in the config");
563
565
  }
564
566
  if (config.debug) {
565
- console.log("\nAsking Gemini model:", JSON.stringify({ model: config.llm.model, message }));
567
+ console.log("\nAsking Gemini model:", JSON.stringify({ model: config.llm.model, message: prompt }));
566
568
  }
569
+ const fullPrompt = String(`${prePrompt2}
570
+
571
+
572
+ ${prompt}
573
+
574
+
575
+ ${postPrompt2}`).trim();
567
576
  let response;
568
577
  for (let i = 0; i < 3; i++) {
569
- const maybeResponse = await generateResponse(message, config.llm.temperature);
578
+ const maybeResponse = await generateResponse(fullPrompt, config.llm.temperature);
570
579
  if (!String(maybeResponse.response.candidates?.[0]?.content?.parts?.[0]?.text ?? "").includes("```json")) {
571
580
  response = maybeResponse;
572
581
  break;
@@ -600,7 +609,7 @@ function parseGemini(unparsed) {
600
609
  return parsed;
601
610
  }
602
611
 
603
- // src/io/huggingface/languagesMap.ts
612
+ // src/io/huggingface/languages-map.ts
604
613
  var languagesMap = {
605
614
  "en-US": "eng_Latn",
606
615
  "en-GB": "eng_Latn",
@@ -886,23 +895,49 @@ var llmChoices = {
886
895
  parse: parseHuggingface
887
896
  }
888
897
  };
889
- async function processLLMChoice(llmChoice, prompt) {
890
- const response = await llmChoice.ask(prompt);
898
+ async function processLLMChoice(llmChoice, prompt, prePrompt2, postPrompt2) {
899
+ const response = await llmChoice.ask(prompt, prePrompt2, postPrompt2);
891
900
  const unparsed = llmChoice.commitResponse(response);
892
901
  const parsed = llmChoice.parse(unparsed);
893
902
  return parsed;
894
903
  }
895
- async function askLLM(prompt) {
904
+ async function askLLM(prompt, prePrompt2, postPrompt2) {
896
905
  const config = await awaitedConfig;
897
906
  const llmChoiceName = config.llm.choice;
898
907
  const llmChoice = llmChoices[llmChoiceName];
899
908
  if (!llmChoice) {
900
909
  throw new Error("LLMChoice not found");
901
910
  }
902
- return processLLMChoice(llmChoice, prompt);
911
+ return processLLMChoice(llmChoice, prompt, prePrompt2, postPrompt2);
903
912
  }
904
913
 
905
914
  // src/gringow.ts
915
+ function getPrependAndAppend(config, cached) {
916
+ const prepend = prePrompt(
917
+ config,
918
+ cached?.prepend ?? config.llm.prePromptAppend ?? "",
919
+ config.llm.prePromptReplace ?? ""
920
+ );
921
+ const append = postPrompt(config, cached?.append ?? config.llm.postPrompt ?? "", config.llm.postPromptReplace ?? "");
922
+ return { prepend, append };
923
+ }
924
+ async function rebuild(cacheId) {
925
+ const config = await awaitedConfig;
926
+ const cached = await checkCache(cacheId);
927
+ if (!cached) throw new Error("Cache item not found");
928
+ const { prepend, append } = getPrependAndAppend(config, cached);
929
+ const translation = await askLLM(cached.original, prepend, append);
930
+ const output = {
931
+ ...translation,
932
+ prepend: cached?.prepend ?? void 0,
933
+ append: cached?.append ?? void 0
934
+ };
935
+ console.log("output:", output);
936
+ if (config.cache.write) {
937
+ await writeCacheToDisk(cacheId, output);
938
+ }
939
+ return { cacheId, translation: output };
940
+ }
906
941
  async function Gringow(strings, ...values) {
907
942
  const config = await awaitedConfig;
908
943
  let flatten;
@@ -913,14 +948,20 @@ async function Gringow(strings, ...values) {
913
948
  }
914
949
  const cacheId = createCacheId(flatten);
915
950
  const cached = await checkCache(cacheId);
916
- if (cached !== void 0 && cached.original !== "undefined") {
951
+ if (cached !== void 0 && cached.original !== "undefined" && !cached.rebuild) {
917
952
  return { cacheId, translation: cached };
918
953
  }
919
- const translation = await askLLM(flatten);
954
+ const { prepend, append } = getPrependAndAppend(config, cached);
955
+ const translation = await askLLM(flatten, prepend, append);
956
+ const output = {
957
+ ...translation,
958
+ prepend: cached?.prepend ?? void 0,
959
+ append: cached?.append ?? void 0
960
+ };
920
961
  if (config.cache.write) {
921
- await writeCacheToDisk(cacheId, translation);
962
+ await writeCacheToDisk(cacheId, output);
922
963
  }
923
- return { cacheId, translation };
964
+ return { cacheId, translation: output };
924
965
  }
925
966
 
926
- export { Gringow };
967
+ export { Gringow, rebuild };
package/dist/index.d.mts CHANGED
@@ -56,6 +56,9 @@ type GringowTranslation = {
56
56
  type GringowCacheItem = {
57
57
  original: string;
58
58
  translation: GringowTranslation;
59
+ append?: string;
60
+ prepend?: string;
61
+ rebuild?: boolean;
59
62
  };
60
63
  type GringowCache = {
61
64
  [key: string]: GringowCacheItem;
@@ -69,6 +72,7 @@ type GringowError = Error & {
69
72
  cause?: Error;
70
73
  };
71
74
 
75
+ declare function rebuild(cacheId: string): Promise<GringowResponse>;
72
76
  /**
73
77
  * Gringow is a function that translates a string or a template string into a
74
78
  * translated string.
@@ -79,4 +83,4 @@ type GringowError = Error & {
79
83
  */
80
84
  declare function Gringow(strings: TemplateStringsArray | string, ...values: Array<unknown>): Promise<GringowResponse>;
81
85
 
82
- export { type GringowCache, type GringowCacheItem, type GringowError, type GringowResponse, type GringowTranslation, checkCache, Gringow as default, deleteCacheItem, getOrCreateCache, writeCacheToDisk };
86
+ export { type GringowCache, type GringowCacheItem, type GringowError, type GringowResponse, type GringowTranslation, checkCache, Gringow as default, deleteCacheItem, getOrCreateCache, rebuild, writeCacheToDisk };