@trazum/core 1.8.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/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/advisories.d.ts +23 -0
- package/dist/advisories.d.ts.map +1 -0
- package/dist/advisories.js +376 -0
- package/dist/advisories.js.map +1 -0
- package/dist/aws-sigv4.d.ts +88 -0
- package/dist/aws-sigv4.d.ts.map +1 -0
- package/dist/aws-sigv4.js +117 -0
- package/dist/aws-sigv4.js.map +1 -0
- package/dist/baseline.d.ts +171 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +273 -0
- package/dist/baseline.js.map +1 -0
- package/dist/cache.d.ts +26 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +28 -0
- package/dist/cache.js.map +1 -0
- package/dist/changes.d.ts +29 -0
- package/dist/changes.d.ts.map +1 -0
- package/dist/changes.js +142 -0
- package/dist/changes.js.map +1 -0
- package/dist/compare.d.ts +65 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +58 -0
- package/dist/compare.js.map +1 -0
- package/dist/config-schema.d.ts +118 -0
- package/dist/config-schema.d.ts.map +1 -0
- package/dist/config-schema.js +315 -0
- package/dist/config-schema.js.map +1 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +112 -0
- package/dist/config.js.map +1 -0
- package/dist/detect.d.ts +70 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +228 -0
- package/dist/detect.js.map +1 -0
- package/dist/evaluate.d.ts +98 -0
- package/dist/evaluate.d.ts.map +1 -0
- package/dist/evaluate.js +110 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/extract.d.ts +81 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +280 -0
- package/dist/extract.js.map +1 -0
- package/dist/gcp-auth.d.ts +58 -0
- package/dist/gcp-auth.d.ts.map +1 -0
- package/dist/gcp-auth.js +113 -0
- package/dist/gcp-auth.js.map +1 -0
- package/dist/glob.d.ts +49 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +154 -0
- package/dist/glob.js.map +1 -0
- package/dist/host.d.ts +30 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +69 -0
- package/dist/host.js.map +1 -0
- package/dist/i18n/en.d.ts +4 -0
- package/dist/i18n/en.d.ts.map +1 -0
- package/dist/i18n/en.js +168 -0
- package/dist/i18n/en.js.map +1 -0
- package/dist/i18n/es.d.ts +4 -0
- package/dist/i18n/es.d.ts.map +1 -0
- package/dist/i18n/es.js +168 -0
- package/dist/i18n/es.js.map +1 -0
- package/dist/i18n/index.d.ts +36 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +50 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/types.d.ts +180 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +11 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/llm.d.ts +226 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +485 -0
- package/dist/llm.js.map +1 -0
- package/dist/nearest.d.ts +20 -0
- package/dist/nearest.d.ts.map +1 -0
- package/dist/nearest.js +54 -0
- package/dist/nearest.js.map +1 -0
- package/dist/net.d.ts +90 -0
- package/dist/net.d.ts.map +1 -0
- package/dist/net.js +203 -0
- package/dist/net.js.map +1 -0
- package/dist/node.d.ts +32 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +33 -0
- package/dist/node.js.map +1 -0
- package/dist/openrouter.d.ts +25 -0
- package/dist/openrouter.d.ts.map +1 -0
- package/dist/openrouter.js +72 -0
- package/dist/openrouter.js.map +1 -0
- package/dist/optimize.d.ts +38 -0
- package/dist/optimize.d.ts.map +1 -0
- package/dist/optimize.js +183 -0
- package/dist/optimize.js.map +1 -0
- package/dist/otlp.d.ts +91 -0
- package/dist/otlp.d.ts.map +1 -0
- package/dist/otlp.js +102 -0
- package/dist/otlp.js.map +1 -0
- package/dist/phrases.d.ts +169 -0
- package/dist/phrases.d.ts.map +1 -0
- package/dist/phrases.js +939 -0
- package/dist/phrases.js.map +1 -0
- package/dist/pricing-overlay.d.ts +55 -0
- package/dist/pricing-overlay.d.ts.map +1 -0
- package/dist/pricing-overlay.js +241 -0
- package/dist/pricing-overlay.js.map +1 -0
- package/dist/pricing.d.ts +115 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +400 -0
- package/dist/pricing.js.map +1 -0
- package/dist/profile.d.ts +71 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +55 -0
- package/dist/profile.js.map +1 -0
- package/dist/promptfoo.d.ts +58 -0
- package/dist/promptfoo.d.ts.map +1 -0
- package/dist/promptfoo.js +149 -0
- package/dist/promptfoo.js.map +1 -0
- package/dist/prune.d.ts +91 -0
- package/dist/prune.d.ts.map +1 -0
- package/dist/prune.js +110 -0
- package/dist/prune.js.map +1 -0
- package/dist/reorder.d.ts +82 -0
- package/dist/reorder.d.ts.map +1 -0
- package/dist/reorder.js +215 -0
- package/dist/reorder.js.map +1 -0
- package/dist/review.d.ts +54 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +131 -0
- package/dist/review.js.map +1 -0
- package/dist/rules.d.ts +5 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +279 -0
- package/dist/rules.js.map +1 -0
- package/dist/savings.d.ts +36 -0
- package/dist/savings.d.ts.map +1 -0
- package/dist/savings.js +83 -0
- package/dist/savings.js.map +1 -0
- package/dist/segment.d.ts +8 -0
- package/dist/segment.d.ts.map +1 -0
- package/dist/segment.js +74 -0
- package/dist/segment.js.map +1 -0
- package/dist/shared-prefix.d.ts +63 -0
- package/dist/shared-prefix.d.ts.map +1 -0
- package/dist/shared-prefix.js +151 -0
- package/dist/shared-prefix.js.map +1 -0
- package/dist/similarity.d.ts +13 -0
- package/dist/similarity.d.ts.map +1 -0
- package/dist/similarity.js +30 -0
- package/dist/similarity.js.map +1 -0
- package/dist/structure.d.ts +144 -0
- package/dist/structure.d.ts.map +1 -0
- package/dist/structure.js +455 -0
- package/dist/structure.js.map +1 -0
- package/dist/suggest.d.ts +100 -0
- package/dist/suggest.d.ts.map +1 -0
- package/dist/suggest.js +151 -0
- package/dist/suggest.js.map +1 -0
- package/dist/tokenizer.d.ts +57 -0
- package/dist/tokenizer.d.ts.map +1 -0
- package/dist/tokenizer.js +157 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/types.d.ts +296 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/walk.d.ts +40 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +95 -0
- package/dist/walk.js.map +1 -0
- package/package.json +56 -0
- package/src/advisories.ts +431 -0
- package/src/aws-sigv4.ts +174 -0
- package/src/baseline.ts +390 -0
- package/src/cache.ts +54 -0
- package/src/changes.ts +158 -0
- package/src/compare.ts +131 -0
- package/src/config-schema.ts +451 -0
- package/src/config.ts +161 -0
- package/src/detect.ts +312 -0
- package/src/evaluate.ts +188 -0
- package/src/extract.ts +336 -0
- package/src/gcp-auth.ts +166 -0
- package/src/glob.ts +160 -0
- package/src/host.ts +90 -0
- package/src/i18n/en.ts +236 -0
- package/src/i18n/es.ts +236 -0
- package/src/i18n/index.ts +68 -0
- package/src/i18n/types.ts +230 -0
- package/src/index.ts +228 -0
- package/src/llm.ts +708 -0
- package/src/nearest.ts +61 -0
- package/src/net.ts +233 -0
- package/src/node.ts +63 -0
- package/src/openrouter.ts +125 -0
- package/src/optimize.ts +228 -0
- package/src/otlp.ts +179 -0
- package/src/phrases.ts +1047 -0
- package/src/pricing-overlay.ts +319 -0
- package/src/pricing.ts +468 -0
- package/src/profile.ts +124 -0
- package/src/promptfoo.ts +213 -0
- package/src/prune.ts +211 -0
- package/src/reorder.ts +307 -0
- package/src/review.ts +180 -0
- package/src/rules.ts +324 -0
- package/src/savings.ts +121 -0
- package/src/segment.ts +106 -0
- package/src/shared-prefix.ts +198 -0
- package/src/similarity.ts +28 -0
- package/src/structure.ts +652 -0
- package/src/suggest.ts +254 -0
- package/src/tokenizer.ts +190 -0
- package/src/types.ts +323 -0
- package/src/walk.ts +117 -0
package/src/phrases.ts
ADDED
|
@@ -0,0 +1,1047 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phrase dictionaries.
|
|
3
|
+
*
|
|
4
|
+
* These lists are DATA, not user interface: they are the vocabulary Trazum
|
|
5
|
+
* looks for inside the prompts it optimises. Real prompts mix languages, so
|
|
6
|
+
* the dictionaries deliberately cover English and Spanish at the same time and
|
|
7
|
+
* a single prompt can trigger entries from both.
|
|
8
|
+
*
|
|
9
|
+
* Adding a language here means adding entries to these lists — it is unrelated
|
|
10
|
+
* to the report language, which lives in `src/i18n/`.
|
|
11
|
+
*
|
|
12
|
+
* Every entry earns its place by preserving meaning. Anything whose removal
|
|
13
|
+
* could change what the prompt asks for belongs in the `aggressive` level, or
|
|
14
|
+
* does not belong here at all.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Languages the trimming dictionaries below actually cover.
|
|
19
|
+
*
|
|
20
|
+
* Exported because the report has to be able to say so. Until this existed,
|
|
21
|
+
* a French or German prompt came back with `No rule found anything to trim` —
|
|
22
|
+
* which reads as "your prompt is already efficient" and meant "I do not speak
|
|
23
|
+
* your language". Same class of mistake as the one `--reorder` had: the tool
|
|
24
|
+
* knew something it was not telling the reader.
|
|
25
|
+
*
|
|
26
|
+
* `phrases.test.js` asserts this list matches the languages the dictionaries are
|
|
27
|
+
* actually grouped under, so adding a dictionary without listing it — or listing
|
|
28
|
+
* one without the entries — fails rather than misleads.
|
|
29
|
+
*/
|
|
30
|
+
export const PHRASE_LANGUAGES: readonly string[] = ['en', 'es', 'fr', 'de', 'pt', 'it', 'nl'];
|
|
31
|
+
|
|
32
|
+
/** Long phrases and their shorter equivalent. */
|
|
33
|
+
export const VERBOSE_PHRASES: ReadonlyArray<readonly [string, string]> = [
|
|
34
|
+
// English
|
|
35
|
+
['in order to', 'to'],
|
|
36
|
+
['for the purpose of', 'to'],
|
|
37
|
+
['due to the fact that', 'because'],
|
|
38
|
+
['owing to the fact that', 'because'],
|
|
39
|
+
['in view of the fact that', 'because'],
|
|
40
|
+
['in the event that', 'if'],
|
|
41
|
+
['at this point in time', 'now'],
|
|
42
|
+
['at the present time', 'now'],
|
|
43
|
+
['in the near future', 'soon'],
|
|
44
|
+
['a large number of', 'many'],
|
|
45
|
+
['a great deal of', 'much'],
|
|
46
|
+
['the majority of', 'most'],
|
|
47
|
+
['make use of', 'use'],
|
|
48
|
+
['utilize', 'use'],
|
|
49
|
+
['in spite of the fact that', 'although'],
|
|
50
|
+
['despite the fact that', 'although'],
|
|
51
|
+
['with regard to', 'about'],
|
|
52
|
+
['with respect to', 'about'],
|
|
53
|
+
['in relation to', 'about'],
|
|
54
|
+
['each and every', 'every'],
|
|
55
|
+
['is able to', 'can'],
|
|
56
|
+
['are able to', 'can'],
|
|
57
|
+
['has the ability to', 'can'],
|
|
58
|
+
['have the ability to', 'can'],
|
|
59
|
+
['prior to', 'before'],
|
|
60
|
+
['subsequent to', 'after'],
|
|
61
|
+
['in a timely manner', 'promptly'],
|
|
62
|
+
['at all times', 'always'],
|
|
63
|
+
['on a regular basis', 'regularly'],
|
|
64
|
+
['a sufficient number of', 'enough'],
|
|
65
|
+
['in the process of', ''],
|
|
66
|
+
|
|
67
|
+
// Spanish
|
|
68
|
+
['con el fin de', 'para'],
|
|
69
|
+
['con el objetivo de', 'para'],
|
|
70
|
+
['con el propósito de', 'para'],
|
|
71
|
+
['a fin de', 'para'],
|
|
72
|
+
['debido al hecho de que', 'porque'],
|
|
73
|
+
['dado el hecho de que', 'porque'],
|
|
74
|
+
['por el hecho de que', 'porque'],
|
|
75
|
+
['en el caso de que', 'si'],
|
|
76
|
+
['en caso de que', 'si'],
|
|
77
|
+
['en el momento en que', 'cuando'],
|
|
78
|
+
['una gran cantidad de', 'muchos'],
|
|
79
|
+
['un gran número de', 'muchos'],
|
|
80
|
+
['la mayor parte de', 'la mayoría de'],
|
|
81
|
+
['hacer uso de', 'usar'],
|
|
82
|
+
['llevar a cabo', 'realizar'],
|
|
83
|
+
['en relación con', 'sobre'],
|
|
84
|
+
['con respecto a', 'sobre'],
|
|
85
|
+
['a pesar de que', 'aunque'],
|
|
86
|
+
['así como también', 'y'],
|
|
87
|
+
['todos y cada uno de los', 'todos los'],
|
|
88
|
+
['cada uno de los', 'cada'],
|
|
89
|
+
['en este momento', 'ahora'],
|
|
90
|
+
['en la actualidad', 'ahora'],
|
|
91
|
+
['hoy en día', 'hoy'],
|
|
92
|
+
['de forma regular', 'regularmente'],
|
|
93
|
+
['en todo momento', 'siempre'],
|
|
94
|
+
['tiene la capacidad de', 'puede'],
|
|
95
|
+
['es capaz de', 'puede'],
|
|
96
|
+
['con anterioridad a', 'antes de'],
|
|
97
|
+
['con posterioridad a', 'después de'],
|
|
98
|
+
['un número suficiente de', 'suficientes'],
|
|
99
|
+
|
|
100
|
+
// French
|
|
101
|
+
['afin de', 'pour'],
|
|
102
|
+
['dans le but de', 'pour'],
|
|
103
|
+
['en vue de', 'pour'],
|
|
104
|
+
['du fait que', 'car'],
|
|
105
|
+
['étant donné que', 'car'],
|
|
106
|
+
['dans le cas où', 'si'],
|
|
107
|
+
["à l'heure actuelle", 'maintenant'],
|
|
108
|
+
['dans un avenir proche', 'bientôt'],
|
|
109
|
+
['un grand nombre de', 'beaucoup de'],
|
|
110
|
+
['la majorité des', 'la plupart des'],
|
|
111
|
+
['faire usage de', 'utiliser'],
|
|
112
|
+
['en ce qui concerne', 'sur'],
|
|
113
|
+
['par rapport à', 'sur'],
|
|
114
|
+
['est en mesure de', 'peut'],
|
|
115
|
+
['il est nécessaire de', 'il faut'],
|
|
116
|
+
|
|
117
|
+
// German
|
|
118
|
+
['um zu können', 'um zu'],
|
|
119
|
+
['zu dem Zweck', 'um'],
|
|
120
|
+
['aufgrund der Tatsache, dass', 'weil'],
|
|
121
|
+
['aus dem Grund, dass', 'weil'],
|
|
122
|
+
['in dem Fall, dass', 'wenn'],
|
|
123
|
+
['zum jetzigen Zeitpunkt', 'jetzt'],
|
|
124
|
+
['in naher Zukunft', 'bald'],
|
|
125
|
+
['eine große Anzahl von', 'viele'],
|
|
126
|
+
['die Mehrheit der', 'die meisten'],
|
|
127
|
+
['Gebrauch machen von', 'nutzen'],
|
|
128
|
+
['in Bezug auf', 'zu'],
|
|
129
|
+
['ist in der Lage zu', 'kann'],
|
|
130
|
+
['es ist notwendig, dass', 'es muss'],
|
|
131
|
+
|
|
132
|
+
// Portuguese
|
|
133
|
+
['a fim de', 'para'],
|
|
134
|
+
['com o objetivo de', 'para'],
|
|
135
|
+
['devido ao fato de que', 'porque'],
|
|
136
|
+
['no caso de que', 'se'],
|
|
137
|
+
['neste momento', 'agora'],
|
|
138
|
+
['num futuro próximo', 'em breve'],
|
|
139
|
+
['um grande número de', 'muitos'],
|
|
140
|
+
['a maioria dos', 'a maior parte dos'],
|
|
141
|
+
['fazer uso de', 'usar'],
|
|
142
|
+
['no que se refere a', 'sobre'],
|
|
143
|
+
['em relação a', 'sobre'],
|
|
144
|
+
['é capaz de', 'pode'],
|
|
145
|
+
['é necessário que', 'deve'],
|
|
146
|
+
|
|
147
|
+
// Italian
|
|
148
|
+
['al fine di', 'per'],
|
|
149
|
+
['con lo scopo di', 'per'],
|
|
150
|
+
['a causa del fatto che', 'perché'],
|
|
151
|
+
['nel caso in cui', 'se'],
|
|
152
|
+
['in questo momento', 'ora'],
|
|
153
|
+
['nel prossimo futuro', 'presto'],
|
|
154
|
+
['un gran numero di', 'molti'],
|
|
155
|
+
['la maggior parte dei', 'la maggioranza dei'],
|
|
156
|
+
['fare uso di', 'usare'],
|
|
157
|
+
['per quanto riguarda', 'su'],
|
|
158
|
+
['in relazione a', 'su'],
|
|
159
|
+
['è in grado di', 'può'],
|
|
160
|
+
['è necessario che', 'deve'],
|
|
161
|
+
|
|
162
|
+
// Dutch
|
|
163
|
+
['met het doel om', 'om'],
|
|
164
|
+
['vanwege het feit dat', 'omdat'],
|
|
165
|
+
['in het geval dat', 'als'],
|
|
166
|
+
['op dit moment', 'nu'],
|
|
167
|
+
['in de nabije toekomst', 'binnenkort'],
|
|
168
|
+
['een groot aantal', 'veel'],
|
|
169
|
+
['de meerderheid van', 'de meeste'],
|
|
170
|
+
['gebruik maken van', 'gebruiken'],
|
|
171
|
+
['met betrekking tot', 'over'],
|
|
172
|
+
['is in staat om', 'kan'],
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
/** Courtesy: adds nothing for the model and costs tokens on every call. */
|
|
176
|
+
export const POLITENESS: readonly string[] = [
|
|
177
|
+
// English
|
|
178
|
+
'please',
|
|
179
|
+
'thanks in advance',
|
|
180
|
+
'thank you very much',
|
|
181
|
+
'thank you',
|
|
182
|
+
'thanks',
|
|
183
|
+
'kindly',
|
|
184
|
+
"if you don't mind",
|
|
185
|
+
'if you would be so kind',
|
|
186
|
+
'much appreciated',
|
|
187
|
+
|
|
188
|
+
// Spanish
|
|
189
|
+
'por favor',
|
|
190
|
+
'muchas gracias',
|
|
191
|
+
'gracias de antemano',
|
|
192
|
+
'te lo agradezco',
|
|
193
|
+
'te agradecería',
|
|
194
|
+
'si eres tan amable',
|
|
195
|
+
'si no te importa',
|
|
196
|
+
'gracias',
|
|
197
|
+
|
|
198
|
+
// French
|
|
199
|
+
"s'il vous plaît",
|
|
200
|
+
"s'il te plaît",
|
|
201
|
+
'merci beaucoup',
|
|
202
|
+
'merci d\'avance',
|
|
203
|
+
'merci',
|
|
204
|
+
'je vous remercie',
|
|
205
|
+
'si cela ne vous dérange pas',
|
|
206
|
+
|
|
207
|
+
// German
|
|
208
|
+
'bitte',
|
|
209
|
+
'vielen Dank',
|
|
210
|
+
'danke im Voraus',
|
|
211
|
+
'danke',
|
|
212
|
+
'ich danke Ihnen',
|
|
213
|
+
'wenn es Ihnen nichts ausmacht',
|
|
214
|
+
|
|
215
|
+
// Portuguese
|
|
216
|
+
'por gentileza',
|
|
217
|
+
'muito obrigado',
|
|
218
|
+
'muito obrigada',
|
|
219
|
+
'obrigado',
|
|
220
|
+
'obrigada',
|
|
221
|
+
'agradeço desde já',
|
|
222
|
+
|
|
223
|
+
// Italian
|
|
224
|
+
'per favore',
|
|
225
|
+
'per cortesia',
|
|
226
|
+
'grazie mille',
|
|
227
|
+
'grazie in anticipo',
|
|
228
|
+
'grazie',
|
|
229
|
+
'ti ringrazio',
|
|
230
|
+
|
|
231
|
+
// Dutch
|
|
232
|
+
'alsjeblieft',
|
|
233
|
+
'alstublieft',
|
|
234
|
+
'hartelijk dank',
|
|
235
|
+
'bedankt',
|
|
236
|
+
'dank je',
|
|
237
|
+
'dank u',
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
/** Filler and throat-clearing with no content. */
|
|
241
|
+
export const FILLER: readonly string[] = [
|
|
242
|
+
// English
|
|
243
|
+
'basically',
|
|
244
|
+
'essentially',
|
|
245
|
+
'as you know',
|
|
246
|
+
'as you may know',
|
|
247
|
+
'it is important to note that',
|
|
248
|
+
"it's important to note that",
|
|
249
|
+
'it is worth noting that',
|
|
250
|
+
"it's worth noting that",
|
|
251
|
+
'needless to say',
|
|
252
|
+
'in essence',
|
|
253
|
+
'at the end of the day',
|
|
254
|
+
'as a matter of fact',
|
|
255
|
+
|
|
256
|
+
// Spanish
|
|
257
|
+
'básicamente',
|
|
258
|
+
'basicamente',
|
|
259
|
+
'en realidad',
|
|
260
|
+
'como ya sabes',
|
|
261
|
+
'como sabrás',
|
|
262
|
+
'cabe destacar que',
|
|
263
|
+
'cabe mencionar que',
|
|
264
|
+
'es importante destacar que',
|
|
265
|
+
'es importante mencionar que',
|
|
266
|
+
'vale la pena mencionar que',
|
|
267
|
+
'por así decirlo',
|
|
268
|
+
'dicho esto',
|
|
269
|
+
|
|
270
|
+
// French
|
|
271
|
+
'il est important de noter que',
|
|
272
|
+
'il convient de noter que',
|
|
273
|
+
'il faut noter que',
|
|
274
|
+
'comme vous le savez',
|
|
275
|
+
'essentiellement',
|
|
276
|
+
'fondamentalement',
|
|
277
|
+
'en fait',
|
|
278
|
+
|
|
279
|
+
// German
|
|
280
|
+
'es ist wichtig zu beachten, dass',
|
|
281
|
+
'es sei darauf hingewiesen, dass',
|
|
282
|
+
'wie Sie wissen',
|
|
283
|
+
'im Grunde',
|
|
284
|
+
'im Wesentlichen',
|
|
285
|
+
'eigentlich',
|
|
286
|
+
|
|
287
|
+
// Portuguese
|
|
288
|
+
'é importante notar que',
|
|
289
|
+
'vale a pena notar que',
|
|
290
|
+
'como você sabe',
|
|
291
|
+
'basicamente',
|
|
292
|
+
'essencialmente',
|
|
293
|
+
|
|
294
|
+
// Italian
|
|
295
|
+
'è importante notare che',
|
|
296
|
+
'vale la pena notare che',
|
|
297
|
+
'come sai',
|
|
298
|
+
'fondamentalmente',
|
|
299
|
+
'essenzialmente',
|
|
300
|
+
|
|
301
|
+
// Dutch
|
|
302
|
+
'het is belangrijk om op te merken dat',
|
|
303
|
+
'zoals je weet',
|
|
304
|
+
'eigenlijk',
|
|
305
|
+
'in principe',
|
|
306
|
+
];
|
|
307
|
+
|
|
308
|
+
/** Intensifiers: they rarely change the task and almost always add tokens. */
|
|
309
|
+
/**
|
|
310
|
+
* Words that add emphasis and nothing else, so dropping one cannot change what
|
|
311
|
+
* the prompt asks for.
|
|
312
|
+
*
|
|
313
|
+
* **A quantifier is not an intensifier**, and the distinction is not visible in
|
|
314
|
+
* a dictionary translated word by word. Spanish gets `muy` and deliberately not
|
|
315
|
+
* `mucho`; the first draft of the other five languages did not keep that line
|
|
316
|
+
* and shipped `muito`, `molto` and `heel`, each of which does both jobs:
|
|
317
|
+
*
|
|
318
|
+
* Hai molto tempo per rispondere. → Hai tempo per rispondere.
|
|
319
|
+
*
|
|
320
|
+
* "You have much time" became "you have time". Caught by running the five
|
|
321
|
+
* languages through the rules rather than by reading the list, and pinned by a
|
|
322
|
+
* test that keeps those three words out.
|
|
323
|
+
*/
|
|
324
|
+
export const INTENSIFIERS: readonly string[] = [
|
|
325
|
+
// English
|
|
326
|
+
'very',
|
|
327
|
+
'really',
|
|
328
|
+
'extremely',
|
|
329
|
+
'incredibly',
|
|
330
|
+
'absolutely',
|
|
331
|
+
'totally',
|
|
332
|
+
'quite',
|
|
333
|
+
|
|
334
|
+
// Spanish
|
|
335
|
+
'muy',
|
|
336
|
+
'realmente',
|
|
337
|
+
'sumamente',
|
|
338
|
+
'extremadamente',
|
|
339
|
+
'increíblemente',
|
|
340
|
+
'absolutamente',
|
|
341
|
+
'totalmente',
|
|
342
|
+
|
|
343
|
+
// French
|
|
344
|
+
'très',
|
|
345
|
+
'vraiment',
|
|
346
|
+
'extrêmement',
|
|
347
|
+
'absolument',
|
|
348
|
+
'tout à fait',
|
|
349
|
+
|
|
350
|
+
// German
|
|
351
|
+
'sehr',
|
|
352
|
+
'wirklich',
|
|
353
|
+
'äußerst',
|
|
354
|
+
'absolut',
|
|
355
|
+
'völlig',
|
|
356
|
+
|
|
357
|
+
// Portuguese
|
|
358
|
+
'realmente',
|
|
359
|
+
'extremamente',
|
|
360
|
+
'absolutamente',
|
|
361
|
+
'totalmente',
|
|
362
|
+
|
|
363
|
+
// Italian
|
|
364
|
+
'davvero',
|
|
365
|
+
'estremamente',
|
|
366
|
+
'assolutamente',
|
|
367
|
+
'totalmente',
|
|
368
|
+
|
|
369
|
+
// Dutch
|
|
370
|
+
'zeer',
|
|
371
|
+
'echt',
|
|
372
|
+
'uiterst',
|
|
373
|
+
'absoluut',
|
|
374
|
+
];
|
|
375
|
+
|
|
376
|
+
/** Hedges that weaken the instruction without adding information. */
|
|
377
|
+
export const HEDGES: readonly string[] = [
|
|
378
|
+
// English
|
|
379
|
+
'i think',
|
|
380
|
+
'i believe',
|
|
381
|
+
'it seems that',
|
|
382
|
+
'in my opinion',
|
|
383
|
+
'arguably',
|
|
384
|
+
|
|
385
|
+
// Spanish
|
|
386
|
+
'creo que',
|
|
387
|
+
'me parece que',
|
|
388
|
+
'diría que',
|
|
389
|
+
'en mi opinión',
|
|
390
|
+
|
|
391
|
+
// French
|
|
392
|
+
'peut-être',
|
|
393
|
+
'probablement',
|
|
394
|
+
'en quelque sorte',
|
|
395
|
+
'je pense que',
|
|
396
|
+
|
|
397
|
+
// German
|
|
398
|
+
'vielleicht',
|
|
399
|
+
'wahrscheinlich',
|
|
400
|
+
'irgendwie',
|
|
401
|
+
'ich denke, dass',
|
|
402
|
+
|
|
403
|
+
// Portuguese
|
|
404
|
+
'talvez',
|
|
405
|
+
'provavelmente',
|
|
406
|
+
'de certa forma',
|
|
407
|
+
'eu acho que',
|
|
408
|
+
|
|
409
|
+
// Italian
|
|
410
|
+
'forse',
|
|
411
|
+
'probabilmente',
|
|
412
|
+
'in un certo senso',
|
|
413
|
+
'penso che',
|
|
414
|
+
|
|
415
|
+
// Dutch
|
|
416
|
+
'misschien',
|
|
417
|
+
'waarschijnlijk',
|
|
418
|
+
'ik denk dat',
|
|
419
|
+
];
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Self-verification instructions.
|
|
423
|
+
*
|
|
424
|
+
* On current models these trigger over-verification: the model already checks
|
|
425
|
+
* its own work, and asking explicitly fires extra steps paid for in output
|
|
426
|
+
* tokens. Aggressive level because some workflows do want explicit
|
|
427
|
+
* verification.
|
|
428
|
+
*
|
|
429
|
+
* The full forms come first on purpose: removing only the core phrase would
|
|
430
|
+
* leave a dangling fragment such as "Before answering." — worse than leaving
|
|
431
|
+
* the sentence alone.
|
|
432
|
+
*
|
|
433
|
+
* That includes whatever introduces the instruction. "You MUST double-check
|
|
434
|
+
* your answer before responding" reduced to "You must." for exactly this
|
|
435
|
+
* reason: the phrase matched, the subject and modal in front of it did not,
|
|
436
|
+
* and what survived was a sentence that says nothing. Anything that can open
|
|
437
|
+
* one of these instructions belongs in the list, ahead of the bare form.
|
|
438
|
+
*/
|
|
439
|
+
export const SELF_CHECK: readonly string[] = [
|
|
440
|
+
// English — openers first, so the whole instruction goes rather than
|
|
441
|
+
// leaving the subject and modal stranded in front of the removal.
|
|
442
|
+
'you must double-check your answer before responding',
|
|
443
|
+
'you must double check your answer before responding',
|
|
444
|
+
'you should double-check your answer before responding',
|
|
445
|
+
'you must verify your answer before responding',
|
|
446
|
+
'you should verify your answer before responding',
|
|
447
|
+
'always double-check your answer before responding',
|
|
448
|
+
'always verify your answer before responding',
|
|
449
|
+
'be sure to double-check your answer before responding',
|
|
450
|
+
'make sure to double-check your answer before responding',
|
|
451
|
+
'make sure to verify your answer before responding',
|
|
452
|
+
'you must double-check your answer',
|
|
453
|
+
'you should double-check your answer',
|
|
454
|
+
'you must verify your answer',
|
|
455
|
+
'you should verify your answer',
|
|
456
|
+
'always double-check your work',
|
|
457
|
+
'be sure to double-check your work',
|
|
458
|
+
'make sure to check your work',
|
|
459
|
+
|
|
460
|
+
// English — bare forms
|
|
461
|
+
'double-check your answer before responding',
|
|
462
|
+
'double check your answer before responding',
|
|
463
|
+
'double-check your work before responding',
|
|
464
|
+
'verify your answer before responding',
|
|
465
|
+
'double-check your answer',
|
|
466
|
+
'double check your answer',
|
|
467
|
+
'double-check your work',
|
|
468
|
+
'double check your work',
|
|
469
|
+
'verify your answer',
|
|
470
|
+
're-verify before responding',
|
|
471
|
+
'check your work twice',
|
|
472
|
+
|
|
473
|
+
// Spanish — openers first, same reason as above
|
|
474
|
+
'debes verificar tu respuesta antes de contestar',
|
|
475
|
+
'debes verificar tu respuesta antes de responder',
|
|
476
|
+
'debes revisar tu respuesta antes de contestar',
|
|
477
|
+
'siempre verifica tu respuesta antes de contestar',
|
|
478
|
+
'asegúrate de verificar tu respuesta antes de contestar',
|
|
479
|
+
'asegúrate de revisar tu respuesta',
|
|
480
|
+
'debes verificar tu respuesta',
|
|
481
|
+
'debes revisar tu respuesta',
|
|
482
|
+
|
|
483
|
+
// Spanish — bare forms
|
|
484
|
+
'verifica tu respuesta antes de contestar',
|
|
485
|
+
'verifica tu respuesta antes de responder',
|
|
486
|
+
'revisa tu respuesta antes de contestar',
|
|
487
|
+
'revisa tu respuesta antes de responder',
|
|
488
|
+
'comprueba tu trabajo antes de responder',
|
|
489
|
+
'verifica tu respuesta',
|
|
490
|
+
'revisa tu respuesta',
|
|
491
|
+
'comprueba tu trabajo',
|
|
492
|
+
'revisa dos veces',
|
|
493
|
+
'vuelve a comprobarlo',
|
|
494
|
+
'asegúrate de revisar tu trabajo',
|
|
495
|
+
|
|
496
|
+
// French
|
|
497
|
+
'vérifiez votre réponse avant de répondre',
|
|
498
|
+
'relisez votre réponse',
|
|
499
|
+
'assurez-vous que votre réponse est correcte',
|
|
500
|
+
'réfléchissez étape par étape avant de répondre',
|
|
501
|
+
|
|
502
|
+
// German
|
|
503
|
+
'überprüfen Sie Ihre Antwort, bevor Sie antworten',
|
|
504
|
+
'lesen Sie Ihre Antwort noch einmal',
|
|
505
|
+
'stellen Sie sicher, dass Ihre Antwort korrekt ist',
|
|
506
|
+
'denken Sie Schritt für Schritt nach',
|
|
507
|
+
|
|
508
|
+
// Portuguese
|
|
509
|
+
'verifique sua resposta antes de responder',
|
|
510
|
+
'releia sua resposta',
|
|
511
|
+
'certifique-se de que sua resposta está correta',
|
|
512
|
+
'pense passo a passo antes de responder',
|
|
513
|
+
|
|
514
|
+
// Italian
|
|
515
|
+
'verifica la tua risposta prima di rispondere',
|
|
516
|
+
'rileggi la tua risposta',
|
|
517
|
+
'assicurati che la tua risposta sia corretta',
|
|
518
|
+
'pensa passo per passo prima di rispondere',
|
|
519
|
+
|
|
520
|
+
// Dutch
|
|
521
|
+
'controleer je antwoord voordat je antwoordt',
|
|
522
|
+
'lees je antwoord nog eens',
|
|
523
|
+
'denk stap voor stap na',
|
|
524
|
+
];
|
|
525
|
+
|
|
526
|
+
/** Words shouted in capitals that cost fewer tokens in lowercase. */
|
|
527
|
+
export const SHOUTED_WORDS: readonly string[] = [
|
|
528
|
+
// English
|
|
529
|
+
'MUST',
|
|
530
|
+
'NEVER',
|
|
531
|
+
'ALWAYS',
|
|
532
|
+
'CRITICAL',
|
|
533
|
+
'IMPORTANT',
|
|
534
|
+
'REQUIRED',
|
|
535
|
+
'MANDATORY',
|
|
536
|
+
'SHOULD',
|
|
537
|
+
'DO NOT',
|
|
538
|
+
|
|
539
|
+
// Spanish
|
|
540
|
+
'DEBES',
|
|
541
|
+
'NUNCA',
|
|
542
|
+
'SIEMPRE',
|
|
543
|
+
'OBLIGATORIO',
|
|
544
|
+
'IMPRESCINDIBLE',
|
|
545
|
+
'IMPORTANTE',
|
|
546
|
+
'CRÍTICO',
|
|
547
|
+
];
|
|
548
|
+
|
|
549
|
+
/** Emphasis prefixes at the start of a line. */
|
|
550
|
+
export const EMPHASIS_PREFIXES: readonly string[] = [
|
|
551
|
+
// English
|
|
552
|
+
'CRITICAL',
|
|
553
|
+
'IMPORTANT',
|
|
554
|
+
'WARNING',
|
|
555
|
+
'NOTE',
|
|
556
|
+
|
|
557
|
+
// Spanish
|
|
558
|
+
'ATENCIÓN',
|
|
559
|
+
'ATENCION',
|
|
560
|
+
'IMPORTANTE',
|
|
561
|
+
'CRÍTICO',
|
|
562
|
+
'CRITICO',
|
|
563
|
+
'AVISO',
|
|
564
|
+
'NOTA',
|
|
565
|
+
];
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Vocabulary suggesting the task needs a more capable model.
|
|
569
|
+
* Multilingual for the same reason as the dictionaries above.
|
|
570
|
+
*/
|
|
571
|
+
export const COMPLEX_SIGNALS: readonly string[] = [
|
|
572
|
+
// English
|
|
573
|
+
'analyze',
|
|
574
|
+
'reason',
|
|
575
|
+
'prove',
|
|
576
|
+
'design',
|
|
577
|
+
'architecture',
|
|
578
|
+
'refactor',
|
|
579
|
+
'debug',
|
|
580
|
+
'agent',
|
|
581
|
+
'tool use',
|
|
582
|
+
'multi-step',
|
|
583
|
+
'step by step',
|
|
584
|
+
'strategy',
|
|
585
|
+
'investigate',
|
|
586
|
+
'audit',
|
|
587
|
+
'migrate',
|
|
588
|
+
|
|
589
|
+
// Spanish
|
|
590
|
+
'analiza',
|
|
591
|
+
'razona',
|
|
592
|
+
'demuestra',
|
|
593
|
+
'diseña',
|
|
594
|
+
'arquitectura',
|
|
595
|
+
'refactoriza',
|
|
596
|
+
'depura',
|
|
597
|
+
'optimiza',
|
|
598
|
+
'estrategia',
|
|
599
|
+
'agente',
|
|
600
|
+
'herramienta',
|
|
601
|
+
'paso a paso',
|
|
602
|
+
'investiga',
|
|
603
|
+
'audita',
|
|
604
|
+
'migra',
|
|
605
|
+
];
|
|
606
|
+
|
|
607
|
+
/** Vocabulary suggesting a cheaper model would do. */
|
|
608
|
+
export const SIMPLE_SIGNALS: readonly string[] = [
|
|
609
|
+
// English
|
|
610
|
+
'classify',
|
|
611
|
+
'translate',
|
|
612
|
+
'extract',
|
|
613
|
+
'summarize',
|
|
614
|
+
'label',
|
|
615
|
+
'sentiment',
|
|
616
|
+
'format as',
|
|
617
|
+
'yes or no',
|
|
618
|
+
'tag the',
|
|
619
|
+
|
|
620
|
+
// Spanish
|
|
621
|
+
'clasifica',
|
|
622
|
+
'traduce',
|
|
623
|
+
'extrae',
|
|
624
|
+
'resume',
|
|
625
|
+
'etiqueta',
|
|
626
|
+
'sentimiento',
|
|
627
|
+
'formatea',
|
|
628
|
+
'corrige la ortografía',
|
|
629
|
+
'sí o no',
|
|
630
|
+
];
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Phrases that refer *backwards* to something earlier in the prompt, by language.
|
|
634
|
+
*
|
|
635
|
+
* These are what makes reordering unsafe. "Summarise the text above" is correct
|
|
636
|
+
* where it sits and nonsense if moved in front of the text it points at, so a
|
|
637
|
+
* block containing one of these must stay where it is — and so must everything
|
|
638
|
+
* after it, because moving a later block past a pinned one changes their order
|
|
639
|
+
* relative to each other.
|
|
640
|
+
*
|
|
641
|
+
* Deliberately generous. A false positive costs a saving that was available; a
|
|
642
|
+
* false negative silently changes what the prompt asks for, which is the one
|
|
643
|
+
* thing this project will not trade for tokens.
|
|
644
|
+
*
|
|
645
|
+
* **Grouped by language rather than kept as one flat list, because the flat list
|
|
646
|
+
* hid a hole.** It held English and Spanish and was applied to every prompt, so
|
|
647
|
+
* a French, German or Japanese author ran `--reorder` with no protection at all:
|
|
648
|
+
* every refusal this module is built on silently did not apply to them, and
|
|
649
|
+
* "Résumez le texte ci-dessus" was hoisted above the text and reported as a
|
|
650
|
+
* saving. A list per language makes the coverage a thing you can look at, and
|
|
651
|
+
* lets `UNCOVERED_SCRIPTS` below refuse what is still missing rather than
|
|
652
|
+
* pretending.
|
|
653
|
+
*
|
|
654
|
+
* Every language is matched against every prompt. Language detection would be
|
|
655
|
+
* one more thing to get wrong, and the cost of checking a French prompt for
|
|
656
|
+
* German phrases is a missed saving, which is the direction this module errs in
|
|
657
|
+
* anyway.
|
|
658
|
+
*/
|
|
659
|
+
export interface BackwardReferenceSet {
|
|
660
|
+
/**
|
|
661
|
+
* Whether a match must sit on a word boundary.
|
|
662
|
+
*
|
|
663
|
+
* True for anything written with spaces, so "aboveboard" does not pin a block.
|
|
664
|
+
* False for Japanese and Chinese, which have no word boundaries at all — the
|
|
665
|
+
* boundary test asks whether the neighbouring character is a letter, and in
|
|
666
|
+
* 上記のテキスト it always is, so a boundary-matched CJK phrase would never
|
|
667
|
+
* fire. A list that cannot match is worse than no list: it reads like cover.
|
|
668
|
+
*/
|
|
669
|
+
wordBoundaries: boolean;
|
|
670
|
+
phrases: readonly string[];
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
export const BACKWARD_REFERENCES_BY_LANGUAGE: Readonly<Record<string, BackwardReferenceSet>> = {
|
|
674
|
+
en: {
|
|
675
|
+
wordBoundaries: true,
|
|
676
|
+
phrases: [
|
|
677
|
+
'above',
|
|
678
|
+
'below',
|
|
679
|
+
'the following',
|
|
680
|
+
'as follows',
|
|
681
|
+
'previous',
|
|
682
|
+
'previously',
|
|
683
|
+
'earlier',
|
|
684
|
+
'aforementioned',
|
|
685
|
+
'that said',
|
|
686
|
+
'given this',
|
|
687
|
+
'given the above',
|
|
688
|
+
'based on this',
|
|
689
|
+
'based on the above',
|
|
690
|
+
'from the text',
|
|
691
|
+
'in the text',
|
|
692
|
+
'the text provided',
|
|
693
|
+
'the input above',
|
|
694
|
+
'the message above',
|
|
695
|
+
'this input',
|
|
696
|
+
'this message',
|
|
697
|
+
'this text',
|
|
698
|
+
'these examples',
|
|
699
|
+
'the examples above',
|
|
700
|
+
],
|
|
701
|
+
},
|
|
702
|
+
|
|
703
|
+
es: {
|
|
704
|
+
wordBoundaries: true,
|
|
705
|
+
phrases: [
|
|
706
|
+
'arriba',
|
|
707
|
+
'anterior',
|
|
708
|
+
'anteriormente',
|
|
709
|
+
'antes',
|
|
710
|
+
'a continuación',
|
|
711
|
+
'lo siguiente',
|
|
712
|
+
'lo anterior',
|
|
713
|
+
'mencionado',
|
|
714
|
+
'dicho esto',
|
|
715
|
+
'segun lo anterior',
|
|
716
|
+
'según lo anterior',
|
|
717
|
+
'del texto',
|
|
718
|
+
'en el texto',
|
|
719
|
+
'el texto anterior',
|
|
720
|
+
'el mensaje anterior',
|
|
721
|
+
'este texto',
|
|
722
|
+
'este mensaje',
|
|
723
|
+
'esta entrada',
|
|
724
|
+
'estos ejemplos',
|
|
725
|
+
],
|
|
726
|
+
},
|
|
727
|
+
|
|
728
|
+
fr: {
|
|
729
|
+
wordBoundaries: true,
|
|
730
|
+
phrases: [
|
|
731
|
+
'ci-dessus',
|
|
732
|
+
'ci-dessous',
|
|
733
|
+
'précédent',
|
|
734
|
+
'précédente',
|
|
735
|
+
'précédemment',
|
|
736
|
+
'susmentionné',
|
|
737
|
+
'mentionné',
|
|
738
|
+
'plus haut',
|
|
739
|
+
'suivant',
|
|
740
|
+
'ce qui suit',
|
|
741
|
+
'cela dit',
|
|
742
|
+
'à partir de ce',
|
|
743
|
+
'du texte',
|
|
744
|
+
'dans le texte',
|
|
745
|
+
'le texte ci-dessus',
|
|
746
|
+
'le message ci-dessus',
|
|
747
|
+
'ce texte',
|
|
748
|
+
'ce message',
|
|
749
|
+
'cette entrée',
|
|
750
|
+
'ces exemples',
|
|
751
|
+
],
|
|
752
|
+
},
|
|
753
|
+
|
|
754
|
+
de: {
|
|
755
|
+
wordBoundaries: true,
|
|
756
|
+
phrases: [
|
|
757
|
+
'oben',
|
|
758
|
+
'unten',
|
|
759
|
+
'obige',
|
|
760
|
+
'obigen',
|
|
761
|
+
'obenstehend',
|
|
762
|
+
'vorherige',
|
|
763
|
+
'vorherigen',
|
|
764
|
+
'vorher',
|
|
765
|
+
'zuvor',
|
|
766
|
+
'genannt',
|
|
767
|
+
'oben genannten',
|
|
768
|
+
'folgendes',
|
|
769
|
+
'wie folgt',
|
|
770
|
+
'aus dem text',
|
|
771
|
+
'im text',
|
|
772
|
+
'der obige text',
|
|
773
|
+
'diese eingabe',
|
|
774
|
+
'dieser text',
|
|
775
|
+
'diese nachricht',
|
|
776
|
+
'diese beispiele',
|
|
777
|
+
],
|
|
778
|
+
},
|
|
779
|
+
|
|
780
|
+
pt: {
|
|
781
|
+
wordBoundaries: true,
|
|
782
|
+
phrases: [
|
|
783
|
+
'acima',
|
|
784
|
+
'abaixo',
|
|
785
|
+
'anterior',
|
|
786
|
+
'anteriormente',
|
|
787
|
+
'antes',
|
|
788
|
+
'mencionado',
|
|
789
|
+
'supracitado',
|
|
790
|
+
'a seguir',
|
|
791
|
+
'o seguinte',
|
|
792
|
+
'dito isto',
|
|
793
|
+
'do texto',
|
|
794
|
+
'no texto',
|
|
795
|
+
'o texto acima',
|
|
796
|
+
'a mensagem acima',
|
|
797
|
+
'este texto',
|
|
798
|
+
'esta mensagem',
|
|
799
|
+
'esta entrada',
|
|
800
|
+
'estes exemplos',
|
|
801
|
+
],
|
|
802
|
+
},
|
|
803
|
+
|
|
804
|
+
it: {
|
|
805
|
+
wordBoundaries: true,
|
|
806
|
+
phrases: [
|
|
807
|
+
'sopra',
|
|
808
|
+
'sotto',
|
|
809
|
+
'precedente',
|
|
810
|
+
'precedentemente',
|
|
811
|
+
'in precedenza',
|
|
812
|
+
'suddetto',
|
|
813
|
+
'menzionato',
|
|
814
|
+
'quanto segue',
|
|
815
|
+
'come segue',
|
|
816
|
+
'detto questo',
|
|
817
|
+
'dal testo',
|
|
818
|
+
'nel testo',
|
|
819
|
+
'il testo sopra',
|
|
820
|
+
'il messaggio sopra',
|
|
821
|
+
'questo testo',
|
|
822
|
+
'questo messaggio',
|
|
823
|
+
'questi esempi',
|
|
824
|
+
],
|
|
825
|
+
},
|
|
826
|
+
|
|
827
|
+
nl: {
|
|
828
|
+
wordBoundaries: true,
|
|
829
|
+
phrases: [
|
|
830
|
+
'hierboven',
|
|
831
|
+
'hieronder',
|
|
832
|
+
'bovenstaande',
|
|
833
|
+
'vorige',
|
|
834
|
+
'eerder',
|
|
835
|
+
'genoemde',
|
|
836
|
+
'het volgende',
|
|
837
|
+
'als volgt',
|
|
838
|
+
'uit de tekst',
|
|
839
|
+
'in de tekst',
|
|
840
|
+
'deze tekst',
|
|
841
|
+
'dit bericht',
|
|
842
|
+
'deze invoer',
|
|
843
|
+
'deze voorbeelden',
|
|
844
|
+
],
|
|
845
|
+
},
|
|
846
|
+
|
|
847
|
+
ja: {
|
|
848
|
+
// No word boundaries: see `wordBoundaries` above.
|
|
849
|
+
wordBoundaries: false,
|
|
850
|
+
phrases: [
|
|
851
|
+
'上記',
|
|
852
|
+
'下記',
|
|
853
|
+
'前述',
|
|
854
|
+
'先ほど',
|
|
855
|
+
'以上の',
|
|
856
|
+
'上のテキスト',
|
|
857
|
+
'このテキスト',
|
|
858
|
+
'このメッセージ',
|
|
859
|
+
'この入力',
|
|
860
|
+
'これらの例',
|
|
861
|
+
'次のとおり',
|
|
862
|
+
],
|
|
863
|
+
},
|
|
864
|
+
|
|
865
|
+
zh: {
|
|
866
|
+
wordBoundaries: false,
|
|
867
|
+
phrases: [
|
|
868
|
+
'上述',
|
|
869
|
+
'上面',
|
|
870
|
+
'前面',
|
|
871
|
+
'以上',
|
|
872
|
+
'前述',
|
|
873
|
+
'如下',
|
|
874
|
+
'下面',
|
|
875
|
+
'上文',
|
|
876
|
+
'该文本',
|
|
877
|
+
'这段文本',
|
|
878
|
+
'这条消息',
|
|
879
|
+
'这些示例',
|
|
880
|
+
],
|
|
881
|
+
},
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Every phrase, flattened. Kept for callers that only need the words.
|
|
886
|
+
*/
|
|
887
|
+
export const BACKWARD_REFERENCES: readonly string[] = Object.values(
|
|
888
|
+
BACKWARD_REFERENCES_BY_LANGUAGE,
|
|
889
|
+
).flatMap((set) => set.phrases);
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* Scripts this module has no backward-reference phrases for.
|
|
893
|
+
*
|
|
894
|
+
* The point of naming them is that the alternative is what used to happen:
|
|
895
|
+
* rearranging a Russian or Arabic prompt with nothing to stop it, and calling
|
|
896
|
+
* the result a saving. `reorderForCache` refuses when it sees one of these,
|
|
897
|
+
* which turns a silent hazard into a message somebody can act on — and into a
|
|
898
|
+
* short list of pull requests, since adding a language is adding an array.
|
|
899
|
+
*
|
|
900
|
+
* Matched on the script, not the language: the question is not "which language
|
|
901
|
+
* is this" but "is there any chance my phrase lists apply to it".
|
|
902
|
+
*/
|
|
903
|
+
export const UNCOVERED_SCRIPTS: ReadonlyArray<{ name: string; pattern: RegExp }> = [
|
|
904
|
+
{ name: 'Cyrillic', pattern: /\p{Script=Cyrillic}/u },
|
|
905
|
+
{ name: 'Arabic', pattern: /\p{Script=Arabic}/u },
|
|
906
|
+
{ name: 'Hebrew', pattern: /\p{Script=Hebrew}/u },
|
|
907
|
+
{ name: 'Hangul', pattern: /\p{Script=Hangul}/u },
|
|
908
|
+
{ name: 'Devanagari', pattern: /\p{Script=Devanagari}/u },
|
|
909
|
+
{ name: 'Thai', pattern: /\p{Script=Thai}/u },
|
|
910
|
+
{ name: 'Greek', pattern: /\p{Script=Greek}/u },
|
|
911
|
+
];
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Phrases that mark a block as the *output contract* rather than as data.
|
|
915
|
+
*
|
|
916
|
+
* Needed because a fenced JSON block in a prompt is one of two completely
|
|
917
|
+
* different things, and confusing them is the one way this analysis could do
|
|
918
|
+
* harm. `Output format: {...}` describes what the model must return, and a
|
|
919
|
+
* provider that accepts a response schema takes it as a request parameter
|
|
920
|
+
* instead — those tokens leave the prompt on every call. `Input: {...}` inside a
|
|
921
|
+
* few-shot example is *data the prompt needs*, and advising anyone to move it
|
|
922
|
+
* would break their prompt.
|
|
923
|
+
*
|
|
924
|
+
* Nothing here guesses. A schema block with no such phrase before it is left
|
|
925
|
+
* alone, because "probably an output format" is not good enough when being wrong
|
|
926
|
+
* costs somebody a working prompt.
|
|
927
|
+
*
|
|
928
|
+
* Seven languages, the same set the rules cover. A prompt in a language absent
|
|
929
|
+
* here raises nothing, which is a false negative and states itself as one — the
|
|
930
|
+
* alternative is matching an English cue inside Japanese prose and calling the
|
|
931
|
+
* result a saving.
|
|
932
|
+
*/
|
|
933
|
+
export const OUTPUT_CUES_BY_LANGUAGE: Readonly<Record<string, readonly string[]>> = {
|
|
934
|
+
en: [
|
|
935
|
+
'output format',
|
|
936
|
+
'response format',
|
|
937
|
+
'output schema',
|
|
938
|
+
'respond with',
|
|
939
|
+
'reply with',
|
|
940
|
+
'answer with',
|
|
941
|
+
'return only',
|
|
942
|
+
'return a json',
|
|
943
|
+
'return json',
|
|
944
|
+
'must return',
|
|
945
|
+
'your output',
|
|
946
|
+
'your response must',
|
|
947
|
+
'format your',
|
|
948
|
+
'in this format',
|
|
949
|
+
'following format',
|
|
950
|
+
'following shape',
|
|
951
|
+
'json format',
|
|
952
|
+
],
|
|
953
|
+
es: [
|
|
954
|
+
'formato de salida',
|
|
955
|
+
'formato de respuesta',
|
|
956
|
+
'esquema de salida',
|
|
957
|
+
'responde con',
|
|
958
|
+
'responda con',
|
|
959
|
+
'contesta con',
|
|
960
|
+
'devuelve solo',
|
|
961
|
+
'devuelve un json',
|
|
962
|
+
'devuelve json',
|
|
963
|
+
'debe devolver',
|
|
964
|
+
'tu respuesta',
|
|
965
|
+
'tu salida',
|
|
966
|
+
'con este formato',
|
|
967
|
+
'siguiente formato',
|
|
968
|
+
'formato json',
|
|
969
|
+
],
|
|
970
|
+
fr: [
|
|
971
|
+
'format de sortie',
|
|
972
|
+
'format de réponse',
|
|
973
|
+
'schéma de sortie',
|
|
974
|
+
'réponds avec',
|
|
975
|
+
'répondez avec',
|
|
976
|
+
'renvoie uniquement',
|
|
977
|
+
'renvoie un json',
|
|
978
|
+
'doit renvoyer',
|
|
979
|
+
'ta réponse',
|
|
980
|
+
'votre réponse',
|
|
981
|
+
'ce format',
|
|
982
|
+
'format suivant',
|
|
983
|
+
'format json',
|
|
984
|
+
],
|
|
985
|
+
de: [
|
|
986
|
+
'ausgabeformat',
|
|
987
|
+
'antwortformat',
|
|
988
|
+
'ausgabeschema',
|
|
989
|
+
'antworte mit',
|
|
990
|
+
'antworten sie mit',
|
|
991
|
+
'gib nur',
|
|
992
|
+
'gib ein json',
|
|
993
|
+
'muss zurückgeben',
|
|
994
|
+
'deine antwort',
|
|
995
|
+
'ihre antwort',
|
|
996
|
+
'diesem format',
|
|
997
|
+
'folgendes format',
|
|
998
|
+
'json-format',
|
|
999
|
+
],
|
|
1000
|
+
pt: [
|
|
1001
|
+
'formato de saída',
|
|
1002
|
+
'formato de resposta',
|
|
1003
|
+
'esquema de saída',
|
|
1004
|
+
'responda com',
|
|
1005
|
+
'responde com',
|
|
1006
|
+
'retorne apenas',
|
|
1007
|
+
'retorne um json',
|
|
1008
|
+
'deve retornar',
|
|
1009
|
+
'sua resposta',
|
|
1010
|
+
'sua saída',
|
|
1011
|
+
'este formato',
|
|
1012
|
+
'formato seguinte',
|
|
1013
|
+
'formato json',
|
|
1014
|
+
],
|
|
1015
|
+
it: [
|
|
1016
|
+
'formato di output',
|
|
1017
|
+
'formato di risposta',
|
|
1018
|
+
'schema di output',
|
|
1019
|
+
'rispondi con',
|
|
1020
|
+
'risponda con',
|
|
1021
|
+
'restituisci solo',
|
|
1022
|
+
'restituisci un json',
|
|
1023
|
+
'deve restituire',
|
|
1024
|
+
'la tua risposta',
|
|
1025
|
+
'il tuo output',
|
|
1026
|
+
'questo formato',
|
|
1027
|
+
'formato seguente',
|
|
1028
|
+
'formato json',
|
|
1029
|
+
],
|
|
1030
|
+
nl: [
|
|
1031
|
+
'uitvoerformaat',
|
|
1032
|
+
'antwoordformaat',
|
|
1033
|
+
'uitvoerschema',
|
|
1034
|
+
'antwoord met',
|
|
1035
|
+
'geef alleen',
|
|
1036
|
+
'geef een json',
|
|
1037
|
+
'moet teruggeven',
|
|
1038
|
+
'je antwoord',
|
|
1039
|
+
'uw antwoord',
|
|
1040
|
+
'dit formaat',
|
|
1041
|
+
'volgende formaat',
|
|
1042
|
+
'json-formaat',
|
|
1043
|
+
],
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
/** Every output cue, flattened. Order is not significant. */
|
|
1047
|
+
export const OUTPUT_CUES: readonly string[] = Object.values(OUTPUT_CUES_BY_LANGUAGE).flat();
|