@jjlmoya/utils-developer 1.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.
Files changed (228) hide show
  1. package/package.json +64 -0
  2. package/src/category/i18n/en.ts +34 -0
  3. package/src/category/i18n/es.ts +34 -0
  4. package/src/category/i18n/fr.ts +34 -0
  5. package/src/category/index.ts +31 -0
  6. package/src/category/seo.astro +15 -0
  7. package/src/components/PreviewNavSidebar.astro +116 -0
  8. package/src/components/PreviewToolbar.astro +143 -0
  9. package/src/data.ts +11 -0
  10. package/src/env.d.ts +5 -0
  11. package/src/index.ts +78 -0
  12. package/src/layouts/PreviewLayout.astro +117 -0
  13. package/src/pages/[locale]/[slug].astro +146 -0
  14. package/src/pages/[locale].astro +251 -0
  15. package/src/pages/index.astro +4 -0
  16. package/src/tests/css_specificity_logic.test.ts +39 -0
  17. package/src/tests/faq_count.test.ts +19 -0
  18. package/src/tests/locale_completeness.test.ts +42 -0
  19. package/src/tests/mocks/astro_mock.js +2 -0
  20. package/src/tests/no_h1_in_components.test.ts +48 -0
  21. package/src/tests/schemas_fulfillment.test.ts +23 -0
  22. package/src/tests/seo_length.test.ts +22 -0
  23. package/src/tests/title_quality.test.ts +55 -0
  24. package/src/tests/tool_validation.test.ts +17 -0
  25. package/src/tool/aspectRatio/bibliography.astro +14 -0
  26. package/src/tool/aspectRatio/component.astro +468 -0
  27. package/src/tool/aspectRatio/i18n/en.ts +177 -0
  28. package/src/tool/aspectRatio/i18n/es.ts +177 -0
  29. package/src/tool/aspectRatio/i18n/fr.ts +177 -0
  30. package/src/tool/aspectRatio/index.ts +34 -0
  31. package/src/tool/aspectRatio/seo.astro +14 -0
  32. package/src/tool/aspectRatio/ui.ts +12 -0
  33. package/src/tool/calculadoraTiempoDatos/bibliography.astro +14 -0
  34. package/src/tool/calculadoraTiempoDatos/component.astro +829 -0
  35. package/src/tool/calculadoraTiempoDatos/i18n/en.ts +150 -0
  36. package/src/tool/calculadoraTiempoDatos/i18n/es.ts +163 -0
  37. package/src/tool/calculadoraTiempoDatos/i18n/fr.ts +150 -0
  38. package/src/tool/calculadoraTiempoDatos/index.ts +33 -0
  39. package/src/tool/calculadoraTiempoDatos/seo.astro +14 -0
  40. package/src/tool/calculadoraTiempoDatos/ui.ts +24 -0
  41. package/src/tool/colorConverter/bibliography.astro +14 -0
  42. package/src/tool/colorConverter/component.astro +504 -0
  43. package/src/tool/colorConverter/i18n/en.ts +126 -0
  44. package/src/tool/colorConverter/i18n/es.ts +126 -0
  45. package/src/tool/colorConverter/i18n/fr.ts +126 -0
  46. package/src/tool/colorConverter/index.ts +33 -0
  47. package/src/tool/colorConverter/seo.astro +14 -0
  48. package/src/tool/colorConverter/ui.ts +16 -0
  49. package/src/tool/conversorExcelCsvHtml/bibliography.astro +14 -0
  50. package/src/tool/conversorExcelCsvHtml/component.astro +595 -0
  51. package/src/tool/conversorExcelCsvHtml/i18n/en.ts +129 -0
  52. package/src/tool/conversorExcelCsvHtml/i18n/es.ts +129 -0
  53. package/src/tool/conversorExcelCsvHtml/i18n/fr.ts +129 -0
  54. package/src/tool/conversorExcelCsvHtml/index.ts +33 -0
  55. package/src/tool/conversorExcelCsvHtml/seo.astro +14 -0
  56. package/src/tool/conversorExcelCsvHtml/ui.ts +14 -0
  57. package/src/tool/cronGenerator/bibliography.astro +14 -0
  58. package/src/tool/cronGenerator/component.astro +667 -0
  59. package/src/tool/cronGenerator/i18n/en.ts +191 -0
  60. package/src/tool/cronGenerator/i18n/es.ts +191 -0
  61. package/src/tool/cronGenerator/i18n/fr.ts +191 -0
  62. package/src/tool/cronGenerator/index.ts +34 -0
  63. package/src/tool/cronGenerator/seo.astro +14 -0
  64. package/src/tool/cronGenerator/ui.ts +45 -0
  65. package/src/tool/cssSpecificityCalculator/bibliography.astro +14 -0
  66. package/src/tool/cssSpecificityCalculator/component.astro +292 -0
  67. package/src/tool/cssSpecificityCalculator/i18n/en.ts +168 -0
  68. package/src/tool/cssSpecificityCalculator/i18n/es.ts +168 -0
  69. package/src/tool/cssSpecificityCalculator/i18n/fr.ts +168 -0
  70. package/src/tool/cssSpecificityCalculator/index.ts +34 -0
  71. package/src/tool/cssSpecificityCalculator/logic.ts +100 -0
  72. package/src/tool/cssSpecificityCalculator/seo.astro +14 -0
  73. package/src/tool/cssSpecificityCalculator/ui-controller.ts +57 -0
  74. package/src/tool/cssSpecificityCalculator/ui.ts +11 -0
  75. package/src/tool/cssToInlineConverter/bibliography.astro +14 -0
  76. package/src/tool/cssToInlineConverter/component.astro +308 -0
  77. package/src/tool/cssToInlineConverter/i18n/en.ts +160 -0
  78. package/src/tool/cssToInlineConverter/i18n/es.ts +160 -0
  79. package/src/tool/cssToInlineConverter/i18n/fr.ts +160 -0
  80. package/src/tool/cssToInlineConverter/index.ts +34 -0
  81. package/src/tool/cssToInlineConverter/seo.astro +14 -0
  82. package/src/tool/cssToInlineConverter/ui.ts +12 -0
  83. package/src/tool/duplicateCssRemover/bibliography.astro +14 -0
  84. package/src/tool/duplicateCssRemover/component.astro +353 -0
  85. package/src/tool/duplicateCssRemover/i18n/en.ts +167 -0
  86. package/src/tool/duplicateCssRemover/i18n/es.ts +167 -0
  87. package/src/tool/duplicateCssRemover/i18n/fr.ts +167 -0
  88. package/src/tool/duplicateCssRemover/index.ts +34 -0
  89. package/src/tool/duplicateCssRemover/seo.astro +14 -0
  90. package/src/tool/duplicateCssRemover/ui.ts +12 -0
  91. package/src/tool/generadorSecurityTxt/bibliography.astro +14 -0
  92. package/src/tool/generadorSecurityTxt/component.astro +473 -0
  93. package/src/tool/generadorSecurityTxt/i18n/en.ts +173 -0
  94. package/src/tool/generadorSecurityTxt/i18n/es.ts +173 -0
  95. package/src/tool/generadorSecurityTxt/i18n/fr.ts +173 -0
  96. package/src/tool/generadorSecurityTxt/index.ts +33 -0
  97. package/src/tool/generadorSecurityTxt/seo.astro +14 -0
  98. package/src/tool/generadorSecurityTxt/ui.ts +27 -0
  99. package/src/tool/hashGenerator/bibliography.astro +14 -0
  100. package/src/tool/hashGenerator/component.astro +367 -0
  101. package/src/tool/hashGenerator/i18n/en.ts +118 -0
  102. package/src/tool/hashGenerator/i18n/es.ts +118 -0
  103. package/src/tool/hashGenerator/i18n/fr.ts +118 -0
  104. package/src/tool/hashGenerator/index.ts +33 -0
  105. package/src/tool/hashGenerator/md5.ts +138 -0
  106. package/src/tool/hashGenerator/seo.astro +14 -0
  107. package/src/tool/hashGenerator/ui.ts +11 -0
  108. package/src/tool/inspectorCertificadosSsl/bibliography.astro +14 -0
  109. package/src/tool/inspectorCertificadosSsl/component.astro +580 -0
  110. package/src/tool/inspectorCertificadosSsl/i18n/en.ts +214 -0
  111. package/src/tool/inspectorCertificadosSsl/i18n/es.ts +214 -0
  112. package/src/tool/inspectorCertificadosSsl/i18n/fr.ts +214 -0
  113. package/src/tool/inspectorCertificadosSsl/index.ts +33 -0
  114. package/src/tool/inspectorCertificadosSsl/seo.astro +14 -0
  115. package/src/tool/inspectorCertificadosSsl/ui.ts +29 -0
  116. package/src/tool/jsonFormatter/bibliography.astro +14 -0
  117. package/src/tool/jsonFormatter/component.astro +590 -0
  118. package/src/tool/jsonFormatter/i18n/en.ts +156 -0
  119. package/src/tool/jsonFormatter/i18n/es.ts +156 -0
  120. package/src/tool/jsonFormatter/i18n/fr.ts +156 -0
  121. package/src/tool/jsonFormatter/index.ts +34 -0
  122. package/src/tool/jsonFormatter/seo.astro +14 -0
  123. package/src/tool/jsonFormatter/ui.ts +15 -0
  124. package/src/tool/keycode/bibliography.astro +14 -0
  125. package/src/tool/keycode/component.astro +540 -0
  126. package/src/tool/keycode/i18n/en.ts +160 -0
  127. package/src/tool/keycode/i18n/es.ts +160 -0
  128. package/src/tool/keycode/i18n/fr.ts +160 -0
  129. package/src/tool/keycode/index.ts +34 -0
  130. package/src/tool/keycode/seo.astro +14 -0
  131. package/src/tool/keycode/ui.ts +10 -0
  132. package/src/tool/llmCostCalculator/bibliography.astro +14 -0
  133. package/src/tool/llmCostCalculator/component.astro +488 -0
  134. package/src/tool/llmCostCalculator/data.ts +99 -0
  135. package/src/tool/llmCostCalculator/i18n/en.ts +165 -0
  136. package/src/tool/llmCostCalculator/i18n/es.ts +165 -0
  137. package/src/tool/llmCostCalculator/i18n/fr.ts +165 -0
  138. package/src/tool/llmCostCalculator/index.ts +34 -0
  139. package/src/tool/llmCostCalculator/seo.astro +14 -0
  140. package/src/tool/llmCostCalculator/ui.ts +11 -0
  141. package/src/tool/mobileMockupGenerator/app.ts +614 -0
  142. package/src/tool/mobileMockupGenerator/bibliography.astro +14 -0
  143. package/src/tool/mobileMockupGenerator/component.astro +1044 -0
  144. package/src/tool/mobileMockupGenerator/constants.ts +48 -0
  145. package/src/tool/mobileMockupGenerator/i18n/en.ts +121 -0
  146. package/src/tool/mobileMockupGenerator/i18n/es.ts +121 -0
  147. package/src/tool/mobileMockupGenerator/i18n/fr.ts +121 -0
  148. package/src/tool/mobileMockupGenerator/index.ts +33 -0
  149. package/src/tool/mobileMockupGenerator/rendering.ts +189 -0
  150. package/src/tool/mobileMockupGenerator/seo.astro +14 -0
  151. package/src/tool/mobileMockupGenerator/store.ts +145 -0
  152. package/src/tool/mobileMockupGenerator/types.ts +41 -0
  153. package/src/tool/mobileMockupGenerator/ui.ts +48 -0
  154. package/src/tool/musicalTypography/bibliography.astro +14 -0
  155. package/src/tool/musicalTypography/component.astro +480 -0
  156. package/src/tool/musicalTypography/i18n/en.ts +179 -0
  157. package/src/tool/musicalTypography/i18n/es.ts +179 -0
  158. package/src/tool/musicalTypography/i18n/fr.ts +179 -0
  159. package/src/tool/musicalTypography/index.ts +33 -0
  160. package/src/tool/musicalTypography/seo.astro +14 -0
  161. package/src/tool/musicalTypography/ui.ts +25 -0
  162. package/src/tool/placeholderGenerator/bibliography.astro +14 -0
  163. package/src/tool/placeholderGenerator/component.astro +499 -0
  164. package/src/tool/placeholderGenerator/i18n/en.ts +176 -0
  165. package/src/tool/placeholderGenerator/i18n/es.ts +176 -0
  166. package/src/tool/placeholderGenerator/i18n/fr.ts +176 -0
  167. package/src/tool/placeholderGenerator/index.ts +34 -0
  168. package/src/tool/placeholderGenerator/seo.astro +14 -0
  169. package/src/tool/placeholderGenerator/ui.ts +14 -0
  170. package/src/tool/promptLibrary/bibliography.astro +14 -0
  171. package/src/tool/promptLibrary/component.astro +1131 -0
  172. package/src/tool/promptLibrary/controller.ts +49 -0
  173. package/src/tool/promptLibrary/i18n/en.ts +131 -0
  174. package/src/tool/promptLibrary/i18n/es.ts +131 -0
  175. package/src/tool/promptLibrary/i18n/fr.ts +126 -0
  176. package/src/tool/promptLibrary/index.ts +33 -0
  177. package/src/tool/promptLibrary/seo.astro +14 -0
  178. package/src/tool/promptLibrary/ui.ts +29 -0
  179. package/src/tool/readabilityCalculator/bibliography.astro +14 -0
  180. package/src/tool/readabilityCalculator/component.astro +534 -0
  181. package/src/tool/readabilityCalculator/i18n/en.ts +133 -0
  182. package/src/tool/readabilityCalculator/i18n/es.ts +133 -0
  183. package/src/tool/readabilityCalculator/i18n/fr.ts +133 -0
  184. package/src/tool/readabilityCalculator/index.ts +33 -0
  185. package/src/tool/readabilityCalculator/seo.astro +14 -0
  186. package/src/tool/readabilityCalculator/ui.ts +27 -0
  187. package/src/tool/svgSanitizer/bibliography.astro +14 -0
  188. package/src/tool/svgSanitizer/component.astro +554 -0
  189. package/src/tool/svgSanitizer/i18n/en.ts +125 -0
  190. package/src/tool/svgSanitizer/i18n/es.ts +125 -0
  191. package/src/tool/svgSanitizer/i18n/fr.ts +125 -0
  192. package/src/tool/svgSanitizer/index.ts +33 -0
  193. package/src/tool/svgSanitizer/seo.astro +14 -0
  194. package/src/tool/svgSanitizer/ui.ts +18 -0
  195. package/src/tool/svgToCss/bibliography.astro +14 -0
  196. package/src/tool/svgToCss/component.astro +381 -0
  197. package/src/tool/svgToCss/i18n/en.ts +174 -0
  198. package/src/tool/svgToCss/i18n/es.ts +174 -0
  199. package/src/tool/svgToCss/i18n/fr.ts +174 -0
  200. package/src/tool/svgToCss/index.ts +34 -0
  201. package/src/tool/svgToCss/seo.astro +14 -0
  202. package/src/tool/svgToCss/ui.ts +13 -0
  203. package/src/tool/urlCleaner/bibliography.astro +14 -0
  204. package/src/tool/urlCleaner/component.astro +458 -0
  205. package/src/tool/urlCleaner/i18n/en.ts +116 -0
  206. package/src/tool/urlCleaner/i18n/es.ts +116 -0
  207. package/src/tool/urlCleaner/i18n/fr.ts +116 -0
  208. package/src/tool/urlCleaner/index.ts +33 -0
  209. package/src/tool/urlCleaner/seo.astro +14 -0
  210. package/src/tool/urlCleaner/ui.ts +12 -0
  211. package/src/tool/urlEncoderDecoder/bibliography.astro +14 -0
  212. package/src/tool/urlEncoderDecoder/component.astro +291 -0
  213. package/src/tool/urlEncoderDecoder/i18n/en.ts +162 -0
  214. package/src/tool/urlEncoderDecoder/i18n/es.ts +162 -0
  215. package/src/tool/urlEncoderDecoder/i18n/fr.ts +162 -0
  216. package/src/tool/urlEncoderDecoder/index.ts +34 -0
  217. package/src/tool/urlEncoderDecoder/seo.astro +14 -0
  218. package/src/tool/urlEncoderDecoder/ui.ts +11 -0
  219. package/src/tool/utmGenerator/bibliography.astro +14 -0
  220. package/src/tool/utmGenerator/component.astro +270 -0
  221. package/src/tool/utmGenerator/i18n/en.ts +117 -0
  222. package/src/tool/utmGenerator/i18n/es.ts +117 -0
  223. package/src/tool/utmGenerator/i18n/fr.ts +117 -0
  224. package/src/tool/utmGenerator/index.ts +33 -0
  225. package/src/tool/utmGenerator/seo.astro +14 -0
  226. package/src/tool/utmGenerator/ui.ts +13 -0
  227. package/src/tools.ts +27 -0
  228. package/src/types.ts +72 -0
@@ -0,0 +1,165 @@
1
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { LlmCostCalculatorUI } from '../ui';
4
+
5
+ const slug = 'llm-cost-calculator';
6
+ const title = 'LLM Cost Calculator. AI Model Pricing Estimator';
7
+ const description =
8
+ 'Free online tool to estimate the cost of calling LLM APIs. Compare GPT-4o, Claude, Gemini, Llama and more with real token prices per million tokens.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'How is the LLM API cost calculated?',
13
+ answer:
14
+ 'LLM APIs charge separately for input tokens (the prompt) and output tokens (the response). The total cost per request is: (input tokens × input price + output tokens × output price) / 1,000,000. Multiply by the number of requests to get the total monthly cost.',
15
+ },
16
+ {
17
+ question: 'What are tokens and how do they relate to words?',
18
+ answer:
19
+ 'A token is the basic unit of text that a language model processes. On average, 1 token equals about 0.75 words in English, so 1,000 tokens ≈ 750 words. Prices are listed per million tokens ($/1M), which is the standard pricing unit across providers.',
20
+ },
21
+ {
22
+ question: 'Why are output tokens more expensive than input tokens?',
23
+ answer:
24
+ 'Generating text (output) requires the model to compute each token sequentially, which is computationally more intensive than reading the input. Most providers charge 3–5x more for output tokens than input tokens.',
25
+ },
26
+ {
27
+ question: 'How can I reduce my LLM API costs?',
28
+ answer:
29
+ 'Use the smallest model that meets your quality requirements. Cache repeated prompts when possible. Minimize system prompt length and avoid unnecessary context. For simple classification or extraction tasks, smaller models like GPT-4o mini or Gemini Flash offer significant savings.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Select a model',
36
+ text: 'Choose the AI model you plan to use from the grouped dropdown. Models are organized by provider.',
37
+ },
38
+ {
39
+ name: 'Enter token counts',
40
+ text: 'Enter the expected number of input tokens (your prompt) and output tokens (the response). Word estimates appear below each field.',
41
+ },
42
+ {
43
+ name: 'Set the number of requests',
44
+ text: 'Use the slider or number input to enter how many API calls you expect. The total cost updates in real time.',
45
+ },
46
+ ];
47
+
48
+ const faqSchema: WithContext<FAQPage> = {
49
+ '@context': 'https://schema.org',
50
+ '@type': 'FAQPage',
51
+ mainEntity: faqData.map((item) => ({
52
+ '@type': 'Question',
53
+ name: item.question,
54
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
55
+ })),
56
+ };
57
+
58
+ const howToSchema: WithContext<HowToThing> = {
59
+ '@context': 'https://schema.org',
60
+ '@type': 'HowTo',
61
+ name: title,
62
+ description,
63
+ step: howToData.map((step, i) => ({
64
+ '@type': 'HowToStep',
65
+ position: i + 1,
66
+ name: step.name,
67
+ text: step.text,
68
+ })),
69
+ };
70
+
71
+ const appSchema: WithContext<SoftwareApplication> = {
72
+ '@context': 'https://schema.org',
73
+ '@type': 'SoftwareApplication',
74
+ name: title,
75
+ description,
76
+ applicationCategory: 'DeveloperApplication',
77
+ operatingSystem: 'All',
78
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
79
+ inLanguage: 'en',
80
+ };
81
+
82
+ const ui: LlmCostCalculatorUI = {
83
+ labelModel: 'LLM Model',
84
+ labelInputTokens: 'Input Tokens',
85
+ labelOutputTokens: 'Output Tokens',
86
+ labelRequests: 'Number of Requests',
87
+ unitWords: 'words',
88
+ labelCostPerRequest: 'Cost per Request',
89
+ labelTotal: 'Estimated Total Cost',
90
+ labelInput: 'Input',
91
+ labelOutput: 'Output',
92
+ };
93
+
94
+ export const content: ToolLocaleContent<LlmCostCalculatorUI> = {
95
+ slug,
96
+ title,
97
+ description,
98
+ ui,
99
+ faqTitle: 'Frequently Asked Questions',
100
+ faq: faqData,
101
+ bibliographyTitle: 'References and Pricing Sources',
102
+ bibliography: [
103
+ {
104
+ name: 'OpenAI API Pricing',
105
+ url: 'https://openai.com/pricing',
106
+ },
107
+ {
108
+ name: 'Anthropic API Pricing',
109
+ url: 'https://www.anthropic.com/pricing',
110
+ },
111
+ {
112
+ name: 'Google AI Studio Pricing',
113
+ url: 'https://ai.google.dev/pricing',
114
+ },
115
+ {
116
+ name: 'OpenAI Tokenizer',
117
+ url: 'https://platform.openai.com/tokenizer',
118
+ },
119
+ ],
120
+ howTo: howToData,
121
+ schemas: [faqSchema, howToSchema, appSchema],
122
+ seo: [
123
+ {
124
+ type: 'title',
125
+ text: 'Understanding LLM API pricing',
126
+ level: 2,
127
+ },
128
+ {
129
+ type: 'paragraph',
130
+ html: 'Large Language Model APIs charge based on token usage, not time or requests. Every API call has two costs: the <strong>input cost</strong> (processing your prompt) and the <strong>output cost</strong> (generating the response). Understanding this split is key to estimating your monthly bill accurately.',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'Input tokens vs output tokens',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'grid',
139
+ columns: 2,
140
+ },
141
+ {
142
+ type: 'card',
143
+ title: 'Input tokens',
144
+ html: '<p>Input tokens represent everything sent <strong>to</strong> the model: your system prompt, conversation history, and user message. They are cheaper because the model processes them in parallel. A typical system prompt of 200 words costs roughly 267 input tokens.</p>',
145
+ },
146
+ {
147
+ type: 'card',
148
+ title: 'Output tokens',
149
+ html: '<p>Output tokens are generated one by one in sequence, making them more computationally expensive. Most providers charge <strong>3–5× more</strong> for output tokens. A 300-word response generates roughly 400 output tokens. Keeping responses concise is one of the most effective cost-saving strategies.</p>',
150
+ },
151
+ {
152
+ type: 'title',
153
+ text: 'Choosing the right model for your budget',
154
+ level: 3,
155
+ },
156
+ {
157
+ type: 'tip',
158
+ html: 'Start with a capable mid-tier model like <code>GPT-4o mini</code> or <code>Gemini 1.5 Flash</code> and only upgrade if quality falls short. The cost difference between a small and large model can be 10–100×.',
159
+ },
160
+ {
161
+ type: 'paragraph',
162
+ html: 'Not all tasks require the same model quality. Classification, extraction, and summarization tasks often perform well with smaller, cheaper models. Reserve large frontier models like <code>claude-3-opus</code> or <code>o1</code> for complex reasoning tasks where quality directly affects outcomes.',
163
+ },
164
+ ],
165
+ };
@@ -0,0 +1,165 @@
1
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { LlmCostCalculatorUI } from '../ui';
4
+
5
+ const slug = 'llm-cost-calculator';
6
+ const title = 'Calculadora de Costes de LLMs. Estimador de Precios de APIs de IA';
7
+ const description =
8
+ 'Herramienta online gratuita para estimar el coste de llamadas a APIs de modelos de lenguaje. Compara GPT-4o, Claude, Gemini, Llama y más con precios reales por millón de tokens.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: '¿Cómo se calcula el coste de una API de LLM?',
13
+ answer:
14
+ 'Las APIs de LLM cobran de forma separada por los tokens de entrada (el prompt) y los tokens de salida (la respuesta). El coste total por petición es: (tokens entrada × precio entrada + tokens salida × precio salida) / 1.000.000. Multiplica por el número de peticiones para obtener el coste mensual total.',
15
+ },
16
+ {
17
+ question: '¿Qué son los tokens y cómo se relacionan con las palabras?',
18
+ answer:
19
+ 'Un token es la unidad básica de texto que procesa un modelo de lenguaje. En promedio, 1 token equivale a aproximadamente 0,75 palabras en inglés, es decir, 1.000 tokens ≈ 750 palabras. Los precios se indican por millón de tokens ($/1M), que es la unidad estándar en todos los proveedores.',
20
+ },
21
+ {
22
+ question: '¿Por qué los tokens de salida son más caros que los de entrada?',
23
+ answer:
24
+ 'Generar texto (salida) requiere que el modelo calcule cada token de forma secuencial, lo cual es computacionalmente más costoso que leer la entrada. La mayoría de los proveedores cobran entre 3 y 5 veces más por los tokens de salida que por los de entrada.',
25
+ },
26
+ {
27
+ question: '¿Cómo puedo reducir los costes de la API de un LLM?',
28
+ answer:
29
+ 'Usa el modelo más pequeño que cumpla tus requisitos de calidad. Cachea los prompts repetidos cuando sea posible. Minimiza la longitud del prompt de sistema y evita contexto innecesario. Para tareas simples de clasificación o extracción, modelos más pequeños como GPT-4o mini o Gemini Flash ofrecen un ahorro significativo.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Selecciona un modelo',
36
+ text: 'Elige el modelo de IA que planeas usar en el desplegable agrupado. Los modelos están organizados por proveedor.',
37
+ },
38
+ {
39
+ name: 'Introduce el número de tokens',
40
+ text: 'Introduce el número esperado de tokens de entrada (tu prompt) y de salida (la respuesta). Debajo de cada campo aparece una estimación en palabras.',
41
+ },
42
+ {
43
+ name: 'Ajusta el número de peticiones',
44
+ text: 'Usa el deslizador o el campo numérico para indicar cuántas llamadas a la API esperas. El coste total se actualiza en tiempo real.',
45
+ },
46
+ ];
47
+
48
+ const faqSchema: WithContext<FAQPage> = {
49
+ '@context': 'https://schema.org',
50
+ '@type': 'FAQPage',
51
+ mainEntity: faqData.map((item) => ({
52
+ '@type': 'Question',
53
+ name: item.question,
54
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
55
+ })),
56
+ };
57
+
58
+ const howToSchema: WithContext<HowToThing> = {
59
+ '@context': 'https://schema.org',
60
+ '@type': 'HowTo',
61
+ name: title,
62
+ description,
63
+ step: howToData.map((step, i) => ({
64
+ '@type': 'HowToStep',
65
+ position: i + 1,
66
+ name: step.name,
67
+ text: step.text,
68
+ })),
69
+ };
70
+
71
+ const appSchema: WithContext<SoftwareApplication> = {
72
+ '@context': 'https://schema.org',
73
+ '@type': 'SoftwareApplication',
74
+ name: title,
75
+ description,
76
+ applicationCategory: 'DeveloperApplication',
77
+ operatingSystem: 'All',
78
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
79
+ inLanguage: 'es',
80
+ };
81
+
82
+ const ui: LlmCostCalculatorUI = {
83
+ labelModel: 'Modelo LLM',
84
+ labelInputTokens: 'Tokens Entrada',
85
+ labelOutputTokens: 'Tokens Salida',
86
+ labelRequests: 'Número de Peticiones',
87
+ unitWords: 'palabras',
88
+ labelCostPerRequest: 'Coste por Petición',
89
+ labelTotal: 'Coste Total Estimado',
90
+ labelInput: 'Input',
91
+ labelOutput: 'Output',
92
+ };
93
+
94
+ export const content: ToolLocaleContent<LlmCostCalculatorUI> = {
95
+ slug,
96
+ title,
97
+ description,
98
+ ui,
99
+ faqTitle: 'Preguntas Frecuentes',
100
+ faq: faqData,
101
+ bibliographyTitle: 'Referencias y Fuentes de Precios',
102
+ bibliography: [
103
+ {
104
+ name: 'Precios de la API de OpenAI',
105
+ url: 'https://openai.com/pricing',
106
+ },
107
+ {
108
+ name: 'Precios de la API de Anthropic',
109
+ url: 'https://www.anthropic.com/pricing',
110
+ },
111
+ {
112
+ name: 'Precios de Google AI Studio',
113
+ url: 'https://ai.google.dev/pricing',
114
+ },
115
+ {
116
+ name: 'Tokenizador de OpenAI',
117
+ url: 'https://platform.openai.com/tokenizer',
118
+ },
119
+ ],
120
+ howTo: howToData,
121
+ schemas: [faqSchema, howToSchema, appSchema],
122
+ seo: [
123
+ {
124
+ type: 'title',
125
+ text: 'Cómo funciona el precio de las APIs de LLM',
126
+ level: 2,
127
+ },
128
+ {
129
+ type: 'paragraph',
130
+ html: 'Las APIs de modelos de lenguaje cobran en función del uso de tokens, no por tiempo ni por petición. Cada llamada tiene dos costes: el <strong>coste de entrada</strong> (procesar tu prompt) y el <strong>coste de salida</strong> (generar la respuesta). Entender esta diferencia es clave para estimar con precisión tu factura mensual.',
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: 'Tokens de entrada frente a tokens de salida',
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'grid',
139
+ columns: 2,
140
+ },
141
+ {
142
+ type: 'card',
143
+ title: 'Tokens de entrada',
144
+ html: '<p>Los tokens de entrada representan todo lo que se envía <strong>al</strong> modelo: tu prompt de sistema, el historial de conversación y el mensaje del usuario. Son más baratos porque el modelo los procesa en paralelo. Un prompt de sistema típico de 200 palabras genera aproximadamente 267 tokens de entrada.</p>',
145
+ },
146
+ {
147
+ type: 'card',
148
+ title: 'Tokens de salida',
149
+ html: '<p>Los tokens de salida se generan uno a uno de forma secuencial, lo que los hace computacionalmente más costosos. La mayoría de los proveedores cobran <strong>entre 3 y 5 veces más</strong> por los tokens de salida. Una respuesta de 300 palabras genera aproximadamente 400 tokens de salida. Mantener las respuestas concisas es una de las estrategias de ahorro más efectivas.</p>',
150
+ },
151
+ {
152
+ type: 'title',
153
+ text: 'Elegir el modelo adecuado para tu presupuesto',
154
+ level: 3,
155
+ },
156
+ {
157
+ type: 'tip',
158
+ html: 'Empieza con un modelo de gama media como <code>GPT-4o mini</code> o <code>Gemini 1.5 Flash</code> y solo escala si la calidad no es suficiente. La diferencia de coste entre un modelo pequeño y uno grande puede ser de 10 a 100 veces.',
159
+ },
160
+ {
161
+ type: 'paragraph',
162
+ html: 'No todas las tareas requieren el mismo nivel de modelo. Las tareas de clasificación, extracción y resumen suelen funcionar bien con modelos más pequeños y económicos. Reserva los modelos más grandes como <code>claude-3-opus</code> o <code>o1</code> para razonamientos complejos donde la calidad afecta directamente al resultado.',
163
+ },
164
+ ],
165
+ };
@@ -0,0 +1,165 @@
1
+ import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { LlmCostCalculatorUI } from '../ui';
4
+
5
+ const slug = 'llm-cost-calculator';
6
+ const title = 'Calculateur de Coûts LLM. Estimateur de Prix des APIs IA';
7
+ const description =
8
+ 'Outil en ligne gratuit pour estimer le coût des appels aux APIs de modèles de langage. Comparez GPT-4o, Claude, Gemini, Llama et plus avec les vrais prix par million de tokens.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: "Comment le coût d'une API LLM est-il calculé ?",
13
+ answer:
14
+ "Les APIs LLM facturent séparément les tokens d'entrée (le prompt) et les tokens de sortie (la réponse). Le coût total par requête est : (tokens entrée × prix entrée + tokens sortie × prix sortie) / 1 000 000. Multipliez par le nombre de requêtes pour obtenir le coût mensuel total.",
15
+ },
16
+ {
17
+ question: 'Que sont les tokens et comment se rapportent-ils aux mots ?',
18
+ answer:
19
+ "Un token est l'unité de base de texte qu'un modèle de langage traite. En moyenne, 1 token équivaut à environ 0,75 mot en anglais, soit 1 000 tokens ≈ 750 mots. Les prix sont indiqués par million de tokens ($/1M), qui est l'unité tarifaire standard chez tous les fournisseurs.",
20
+ },
21
+ {
22
+ question: "Pourquoi les tokens de sortie sont-ils plus chers que les tokens d'entrée ?",
23
+ answer:
24
+ "Générer du texte (sortie) oblige le modèle à calculer chaque token séquentiellement, ce qui est plus coûteux en calcul que de lire l'entrée. La plupart des fournisseurs facturent 3 à 5 fois plus pour les tokens de sortie que pour les tokens d'entrée.",
25
+ },
26
+ {
27
+ question: 'Comment réduire les coûts de mon API LLM ?',
28
+ answer:
29
+ "Utilisez le modèle le plus petit qui répond à vos exigences de qualité. Mettez en cache les prompts répétés si possible. Minimisez la longueur du prompt système et évitez le contexte inutile. Pour les tâches simples de classification ou d'extraction, des modèles plus petits comme GPT-4o mini ou Gemini Flash offrent des économies significatives.",
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Sélectionner un modèle',
36
+ text: "Choisissez le modèle IA que vous prévoyez d'utiliser dans la liste déroulante groupée. Les modèles sont organisés par fournisseur.",
37
+ },
38
+ {
39
+ name: 'Saisir le nombre de tokens',
40
+ text: "Entrez le nombre attendu de tokens d'entrée (votre prompt) et de sortie (la réponse). Une estimation en mots apparaît sous chaque champ.",
41
+ },
42
+ {
43
+ name: 'Définir le nombre de requêtes',
44
+ text: "Utilisez le curseur ou le champ numérique pour indiquer combien d'appels API vous prévoyez. Le coût total se met à jour en temps réel.",
45
+ },
46
+ ];
47
+
48
+ const faqSchema: WithContext<FAQPage> = {
49
+ '@context': 'https://schema.org',
50
+ '@type': 'FAQPage',
51
+ mainEntity: faqData.map((item) => ({
52
+ '@type': 'Question',
53
+ name: item.question,
54
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
55
+ })),
56
+ };
57
+
58
+ const howToSchema: WithContext<HowToThing> = {
59
+ '@context': 'https://schema.org',
60
+ '@type': 'HowTo',
61
+ name: title,
62
+ description,
63
+ step: howToData.map((step, i) => ({
64
+ '@type': 'HowToStep',
65
+ position: i + 1,
66
+ name: step.name,
67
+ text: step.text,
68
+ })),
69
+ };
70
+
71
+ const appSchema: WithContext<SoftwareApplication> = {
72
+ '@context': 'https://schema.org',
73
+ '@type': 'SoftwareApplication',
74
+ name: title,
75
+ description,
76
+ applicationCategory: 'DeveloperApplication',
77
+ operatingSystem: 'All',
78
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
79
+ inLanguage: 'fr',
80
+ };
81
+
82
+ const ui: LlmCostCalculatorUI = {
83
+ labelModel: 'Modèle LLM',
84
+ labelInputTokens: "Tokens d'entrée",
85
+ labelOutputTokens: 'Tokens de sortie',
86
+ labelRequests: 'Nombre de requêtes',
87
+ unitWords: 'mots',
88
+ labelCostPerRequest: 'Coût par requête',
89
+ labelTotal: 'Coût total estimé',
90
+ labelInput: 'Input',
91
+ labelOutput: 'Output',
92
+ };
93
+
94
+ export const content: ToolLocaleContent<LlmCostCalculatorUI> = {
95
+ slug,
96
+ title,
97
+ description,
98
+ ui,
99
+ faqTitle: 'Questions fréquentes',
100
+ faq: faqData,
101
+ bibliographyTitle: 'Références et Sources de Prix',
102
+ bibliography: [
103
+ {
104
+ name: "Tarification de l'API OpenAI",
105
+ url: 'https://openai.com/pricing',
106
+ },
107
+ {
108
+ name: "Tarification de l'API Anthropic",
109
+ url: 'https://www.anthropic.com/pricing',
110
+ },
111
+ {
112
+ name: 'Tarification Google AI Studio',
113
+ url: 'https://ai.google.dev/pricing',
114
+ },
115
+ {
116
+ name: 'Tokeniseur OpenAI',
117
+ url: 'https://platform.openai.com/tokenizer',
118
+ },
119
+ ],
120
+ howTo: howToData,
121
+ schemas: [faqSchema, howToSchema, appSchema],
122
+ seo: [
123
+ {
124
+ type: 'title',
125
+ text: 'Comprendre la tarification des APIs LLM',
126
+ level: 2,
127
+ },
128
+ {
129
+ type: 'paragraph',
130
+ html: "Les APIs de modèles de langage facturent en fonction de l'utilisation des tokens, et non du temps ou des requêtes. Chaque appel a deux coûts : le <strong>coût d'entrée</strong> (traitement de votre prompt) et le <strong>coût de sortie</strong> (génération de la réponse). Comprendre cette distinction est essentiel pour estimer avec précision votre facture mensuelle.",
131
+ },
132
+ {
133
+ type: 'title',
134
+ text: "Tokens d'entrée et tokens de sortie",
135
+ level: 3,
136
+ },
137
+ {
138
+ type: 'grid',
139
+ columns: 2,
140
+ },
141
+ {
142
+ type: 'card',
143
+ title: "Tokens d'entrée",
144
+ html: "<p>Les tokens d'entrée représentent tout ce qui est envoyé <strong>au</strong> modèle : votre prompt système, l'historique de la conversation et le message de l'utilisateur. Ils sont moins chers car le modèle les traite en parallèle. Un prompt système typique de 200 mots génère environ 267 tokens d'entrée.</p>",
145
+ },
146
+ {
147
+ type: 'card',
148
+ title: 'Tokens de sortie',
149
+ html: '<p>Les tokens de sortie sont générés un par un séquentiellement, ce qui les rend plus coûteux en calcul. La plupart des fournisseurs facturent <strong>3 à 5 fois plus</strong> pour les tokens de sortie. Une réponse de 300 mots génère environ 400 tokens de sortie. Garder les réponses concises est une des stratégies d\'économie les plus efficaces.</p>',
150
+ },
151
+ {
152
+ type: 'title',
153
+ text: 'Choisir le bon modèle pour votre budget',
154
+ level: 3,
155
+ },
156
+ {
157
+ type: 'tip',
158
+ html: 'Commencez avec un modèle de milieu de gamme comme <code>GPT-4o mini</code> ou <code>Gemini 1.5 Flash</code> et ne montez en gamme que si la qualité est insuffisante. La différence de coût entre un petit et un grand modèle peut être de 10 à 100 fois.',
159
+ },
160
+ {
161
+ type: 'paragraph',
162
+ html: "Toutes les tâches ne nécessitent pas le même niveau de modèle. Les tâches de classification, d'extraction et de résumé fonctionnent souvent bien avec des modèles plus petits et moins chers. Réservez les grands modèles comme <code>claude-3-opus</code> ou <code>o1</code> pour les raisonnements complexes où la qualité impacte directement les résultats.",
163
+ },
164
+ ],
165
+ };
@@ -0,0 +1,34 @@
1
+ import type { DeveloperToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
2
+ import LlmCostCalculatorComponent from './component.astro';
3
+ import LlmCostCalculatorSEO from './seo.astro';
4
+ import LlmCostCalculatorBibliography from './bibliography.astro';
5
+
6
+ import type { LlmCostCalculatorUI } from './ui';
7
+
8
+ export type LlmCostCalculatorLocaleContent = ToolLocaleContent<LlmCostCalculatorUI>;
9
+
10
+ import { content as es } from './i18n/es';
11
+ import { content as en } from './i18n/en';
12
+ import { content as fr } from './i18n/fr';
13
+
14
+ export const llmCostCalculator: DeveloperToolEntry<LlmCostCalculatorUI> = {
15
+ id: 'llm-cost-calculator',
16
+ icons: {
17
+ bg: 'mdi:currency-usd',
18
+ fg: 'mdi:robot-outline',
19
+ },
20
+ i18n: {
21
+ es: async () => es,
22
+ en: async () => en,
23
+ fr: async () => fr,
24
+ },
25
+ };
26
+
27
+ export { LlmCostCalculatorComponent, LlmCostCalculatorSEO, LlmCostCalculatorBibliography };
28
+
29
+ export const LLM_COST_CALCULATOR_TOOL: ToolDefinition = {
30
+ entry: llmCostCalculator,
31
+ Component: LlmCostCalculatorComponent,
32
+ SEOComponent: LlmCostCalculatorSEO,
33
+ BibliographyComponent: LlmCostCalculatorBibliography,
34
+ };
@@ -0,0 +1,14 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { llmCostCalculator } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'es' } = Astro.props;
11
+ const content = await llmCostCalculator.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -0,0 +1,11 @@
1
+ export interface LlmCostCalculatorUI extends Record<string, string> {
2
+ labelModel: string;
3
+ labelInputTokens: string;
4
+ labelOutputTokens: string;
5
+ labelRequests: string;
6
+ unitWords: string;
7
+ labelCostPerRequest: string;
8
+ labelTotal: string;
9
+ labelInput: string;
10
+ labelOutput: string;
11
+ }