gencode-ai 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/README.md +15 -17
  2. package/dist/agent/agent.d.ts +43 -0
  3. package/dist/agent/agent.d.ts.map +1 -1
  4. package/dist/agent/agent.js +107 -4
  5. package/dist/agent/agent.js.map +1 -1
  6. package/dist/agent/index.d.ts +1 -0
  7. package/dist/agent/index.d.ts.map +1 -1
  8. package/dist/agent/types.d.ts +20 -1
  9. package/dist/agent/types.d.ts.map +1 -1
  10. package/dist/checkpointing/checkpoint-manager.d.ts +87 -0
  11. package/dist/checkpointing/checkpoint-manager.d.ts.map +1 -0
  12. package/dist/checkpointing/checkpoint-manager.js +281 -0
  13. package/dist/checkpointing/checkpoint-manager.js.map +1 -0
  14. package/dist/checkpointing/index.d.ts +29 -0
  15. package/dist/checkpointing/index.d.ts.map +1 -0
  16. package/dist/checkpointing/index.js +29 -0
  17. package/dist/checkpointing/index.js.map +1 -0
  18. package/dist/checkpointing/types.d.ts +98 -0
  19. package/dist/checkpointing/types.d.ts.map +1 -0
  20. package/dist/checkpointing/types.js +7 -0
  21. package/dist/checkpointing/types.js.map +1 -0
  22. package/dist/cli/components/App.d.ts.map +1 -1
  23. package/dist/cli/components/App.js +193 -7
  24. package/dist/cli/components/App.js.map +1 -1
  25. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
  26. package/dist/cli/components/CommandSuggestions.js +5 -0
  27. package/dist/cli/components/CommandSuggestions.js.map +1 -1
  28. package/dist/cli/components/Messages.d.ts +7 -1
  29. package/dist/cli/components/Messages.d.ts.map +1 -1
  30. package/dist/cli/components/Messages.js +28 -2
  31. package/dist/cli/components/Messages.js.map +1 -1
  32. package/dist/cli/components/ModeIndicator.d.ts +42 -0
  33. package/dist/cli/components/ModeIndicator.d.ts.map +1 -0
  34. package/dist/cli/components/ModeIndicator.js +52 -0
  35. package/dist/cli/components/ModeIndicator.js.map +1 -0
  36. package/dist/cli/components/PlanApproval.d.ts +36 -0
  37. package/dist/cli/components/PlanApproval.d.ts.map +1 -0
  38. package/dist/cli/components/PlanApproval.js +154 -0
  39. package/dist/cli/components/PlanApproval.js.map +1 -0
  40. package/dist/cli/components/QuestionPrompt.d.ts +23 -0
  41. package/dist/cli/components/QuestionPrompt.d.ts.map +1 -0
  42. package/dist/cli/components/QuestionPrompt.js +231 -0
  43. package/dist/cli/components/QuestionPrompt.js.map +1 -0
  44. package/dist/cli/components/index.d.ts +1 -0
  45. package/dist/cli/components/index.d.ts.map +1 -1
  46. package/dist/cli/components/index.js +1 -0
  47. package/dist/cli/components/index.js.map +1 -1
  48. package/dist/cli/components/theme.d.ts +9 -0
  49. package/dist/cli/components/theme.d.ts.map +1 -1
  50. package/dist/cli/components/theme.js +14 -1
  51. package/dist/cli/components/theme.js.map +1 -1
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +2 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/permissions/types.d.ts.map +1 -1
  57. package/dist/permissions/types.js +2 -0
  58. package/dist/permissions/types.js.map +1 -1
  59. package/dist/planning/index.d.ts +13 -0
  60. package/dist/planning/index.d.ts.map +1 -0
  61. package/dist/planning/index.js +15 -0
  62. package/dist/planning/index.js.map +1 -0
  63. package/dist/planning/plan-file.d.ts +59 -0
  64. package/dist/planning/plan-file.d.ts.map +1 -0
  65. package/dist/planning/plan-file.js +278 -0
  66. package/dist/planning/plan-file.js.map +1 -0
  67. package/dist/planning/state.d.ts +127 -0
  68. package/dist/planning/state.d.ts.map +1 -0
  69. package/dist/planning/state.js +261 -0
  70. package/dist/planning/state.js.map +1 -0
  71. package/dist/planning/tools/enter-plan-mode.d.ts +25 -0
  72. package/dist/planning/tools/enter-plan-mode.d.ts.map +1 -0
  73. package/dist/planning/tools/enter-plan-mode.js +98 -0
  74. package/dist/planning/tools/enter-plan-mode.js.map +1 -0
  75. package/dist/planning/tools/exit-plan-mode.d.ts +24 -0
  76. package/dist/planning/tools/exit-plan-mode.d.ts.map +1 -0
  77. package/dist/planning/tools/exit-plan-mode.js +149 -0
  78. package/dist/planning/tools/exit-plan-mode.js.map +1 -0
  79. package/dist/planning/types.d.ts +100 -0
  80. package/dist/planning/types.d.ts.map +1 -0
  81. package/dist/planning/types.js +28 -0
  82. package/dist/planning/types.js.map +1 -0
  83. package/dist/pricing/calculator.d.ts +21 -0
  84. package/dist/pricing/calculator.d.ts.map +1 -0
  85. package/dist/pricing/calculator.js +59 -0
  86. package/dist/pricing/calculator.js.map +1 -0
  87. package/dist/pricing/index.d.ts +7 -0
  88. package/dist/pricing/index.d.ts.map +1 -0
  89. package/dist/pricing/index.js +7 -0
  90. package/dist/pricing/index.js.map +1 -0
  91. package/dist/pricing/models.d.ts +20 -0
  92. package/dist/pricing/models.d.ts.map +1 -0
  93. package/dist/pricing/models.js +322 -0
  94. package/dist/pricing/models.js.map +1 -0
  95. package/dist/pricing/types.d.ts +30 -0
  96. package/dist/pricing/types.d.ts.map +1 -0
  97. package/dist/pricing/types.js +5 -0
  98. package/dist/pricing/types.js.map +1 -0
  99. package/dist/providers/anthropic.d.ts.map +1 -1
  100. package/dist/providers/anthropic.js +17 -10
  101. package/dist/providers/anthropic.js.map +1 -1
  102. package/dist/providers/gemini.d.ts.map +1 -1
  103. package/dist/providers/gemini.js +21 -14
  104. package/dist/providers/gemini.js.map +1 -1
  105. package/dist/providers/openai.d.ts.map +1 -1
  106. package/dist/providers/openai.js +12 -8
  107. package/dist/providers/openai.js.map +1 -1
  108. package/dist/providers/types.d.ts +2 -0
  109. package/dist/providers/types.d.ts.map +1 -1
  110. package/dist/providers/vertex-ai.d.ts.map +1 -1
  111. package/dist/providers/vertex-ai.js +17 -10
  112. package/dist/providers/vertex-ai.js.map +1 -1
  113. package/dist/session/manager.d.ts +4 -0
  114. package/dist/session/manager.d.ts.map +1 -1
  115. package/dist/session/manager.js +8 -0
  116. package/dist/session/manager.js.map +1 -1
  117. package/dist/tools/builtin/ask-user.d.ts +64 -0
  118. package/dist/tools/builtin/ask-user.d.ts.map +1 -0
  119. package/dist/tools/builtin/ask-user.js +148 -0
  120. package/dist/tools/builtin/ask-user.js.map +1 -0
  121. package/dist/tools/index.d.ts +19 -1
  122. package/dist/tools/index.d.ts.map +1 -1
  123. package/dist/tools/index.js +11 -0
  124. package/dist/tools/index.js.map +1 -1
  125. package/dist/tools/registry.d.ts +13 -0
  126. package/dist/tools/registry.d.ts.map +1 -1
  127. package/dist/tools/registry.js +79 -2
  128. package/dist/tools/registry.js.map +1 -1
  129. package/dist/tools/types.d.ts +17 -0
  130. package/dist/tools/types.d.ts.map +1 -1
  131. package/dist/tools/types.js.map +1 -1
  132. package/docs/cost-tracking-comparison.md +904 -0
  133. package/docs/operating-modes.md +96 -0
  134. package/docs/proposals/0012-ask-user-question.md +66 -1
  135. package/docs/proposals/0025-cost-tracking.md +60 -2
  136. package/docs/proposals/README.md +2 -2
  137. package/examples/test-ask-user.ts +167 -0
  138. package/examples/test-checkpointing.ts +121 -0
  139. package/examples/test-cost-tracking.ts +77 -0
  140. package/examples/test-interrupt-cleanup.ts +94 -0
  141. package/package.json +1 -1
  142. package/src/agent/agent.ts +130 -4
  143. package/src/agent/index.ts +1 -0
  144. package/src/agent/types.ts +19 -1
  145. package/src/checkpointing/checkpoint-manager.ts +327 -0
  146. package/src/checkpointing/index.ts +45 -0
  147. package/src/checkpointing/types.ts +104 -0
  148. package/src/cli/components/App.tsx +259 -8
  149. package/src/cli/components/CommandSuggestions.tsx +5 -0
  150. package/src/cli/components/Messages.tsx +66 -4
  151. package/src/cli/components/ModeIndicator.tsx +174 -0
  152. package/src/cli/components/PlanApproval.tsx +327 -0
  153. package/src/cli/components/QuestionPrompt.tsx +462 -0
  154. package/src/cli/components/index.ts +1 -0
  155. package/src/cli/components/theme.ts +14 -1
  156. package/src/index.ts +15 -0
  157. package/src/permissions/types.ts +2 -0
  158. package/src/planning/index.ts +53 -0
  159. package/src/planning/plan-file.ts +326 -0
  160. package/src/planning/state.ts +305 -0
  161. package/src/planning/tools/enter-plan-mode.ts +111 -0
  162. package/src/planning/tools/exit-plan-mode.ts +170 -0
  163. package/src/planning/types.ts +150 -0
  164. package/src/pricing/calculator.ts +71 -0
  165. package/src/pricing/index.ts +7 -0
  166. package/src/pricing/models.ts +334 -0
  167. package/src/pricing/types.ts +32 -0
  168. package/src/prompts/system/base.txt +42 -0
  169. package/src/prompts/tools/ask-user.txt +110 -0
  170. package/src/providers/anthropic.ts +21 -10
  171. package/src/providers/gemini.ts +25 -14
  172. package/src/providers/openai.ts +17 -8
  173. package/src/providers/types.ts +3 -0
  174. package/src/providers/vertex-ai.ts +21 -10
  175. package/src/session/manager.ts +9 -0
  176. package/src/tools/builtin/ask-user.ts +185 -0
  177. package/src/tools/index.ts +23 -0
  178. package/src/tools/registry.ts +95 -2
  179. package/src/tools/types.ts +18 -0
  180. package/.gencode/settings.local.json +0 -7
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Model pricing database
3
+ * Prices are per 1M tokens in USD
4
+ * Updated: January 2025
5
+ */
6
+
7
+ import { ModelPricing } from './types.js';
8
+
9
+ /**
10
+ * Pricing data for all supported models
11
+ * Source: Official provider pricing pages as of January 2025
12
+ */
13
+ export const MODEL_PRICING: ModelPricing[] = [
14
+ // Anthropic Claude Models
15
+ {
16
+ provider: 'anthropic',
17
+ model: 'claude-opus-4-5',
18
+ inputPer1M: 15.0,
19
+ outputPer1M: 75.0,
20
+ effectiveDate: '2025-01-01',
21
+ },
22
+ {
23
+ provider: 'anthropic',
24
+ model: 'claude-opus-4',
25
+ inputPer1M: 15.0,
26
+ outputPer1M: 75.0,
27
+ effectiveDate: '2024-11-01',
28
+ },
29
+ {
30
+ provider: 'anthropic',
31
+ model: 'claude-sonnet-4-5',
32
+ inputPer1M: 3.0,
33
+ outputPer1M: 15.0,
34
+ effectiveDate: '2025-01-01',
35
+ },
36
+ {
37
+ provider: 'anthropic',
38
+ model: 'claude-sonnet-4',
39
+ inputPer1M: 3.0,
40
+ outputPer1M: 15.0,
41
+ effectiveDate: '2024-10-22',
42
+ },
43
+ {
44
+ provider: 'anthropic',
45
+ model: 'claude-3-5-sonnet-20241022',
46
+ inputPer1M: 3.0,
47
+ outputPer1M: 15.0,
48
+ effectiveDate: '2024-10-22',
49
+ },
50
+ {
51
+ provider: 'anthropic',
52
+ model: 'claude-3-5-sonnet-20240620',
53
+ inputPer1M: 3.0,
54
+ outputPer1M: 15.0,
55
+ effectiveDate: '2024-06-20',
56
+ },
57
+ {
58
+ provider: 'anthropic',
59
+ model: 'claude-haiku-3-5',
60
+ inputPer1M: 0.8,
61
+ outputPer1M: 4.0,
62
+ effectiveDate: '2024-11-01',
63
+ },
64
+ {
65
+ provider: 'anthropic',
66
+ model: 'claude-3-5-haiku-20241022',
67
+ inputPer1M: 0.8,
68
+ outputPer1M: 4.0,
69
+ effectiveDate: '2024-10-22',
70
+ },
71
+ {
72
+ provider: 'anthropic',
73
+ model: 'claude-3-haiku-20240307',
74
+ inputPer1M: 0.25,
75
+ outputPer1M: 1.25,
76
+ effectiveDate: '2024-03-07',
77
+ },
78
+ {
79
+ provider: 'anthropic',
80
+ model: 'claude-3-opus-20240229',
81
+ inputPer1M: 15.0,
82
+ outputPer1M: 75.0,
83
+ effectiveDate: '2024-02-29',
84
+ },
85
+
86
+ // OpenAI Models
87
+ {
88
+ provider: 'openai',
89
+ model: 'gpt-4o',
90
+ inputPer1M: 2.5,
91
+ outputPer1M: 10.0,
92
+ effectiveDate: '2024-08-06',
93
+ },
94
+ {
95
+ provider: 'openai',
96
+ model: 'gpt-4o-2024-11-20',
97
+ inputPer1M: 2.5,
98
+ outputPer1M: 10.0,
99
+ effectiveDate: '2024-11-20',
100
+ },
101
+ {
102
+ provider: 'openai',
103
+ model: 'gpt-4o-2024-08-06',
104
+ inputPer1M: 2.5,
105
+ outputPer1M: 10.0,
106
+ effectiveDate: '2024-08-06',
107
+ },
108
+ {
109
+ provider: 'openai',
110
+ model: 'gpt-4o-2024-05-13',
111
+ inputPer1M: 5.0,
112
+ outputPer1M: 15.0,
113
+ effectiveDate: '2024-05-13',
114
+ },
115
+ {
116
+ provider: 'openai',
117
+ model: 'gpt-4o-mini',
118
+ inputPer1M: 0.15,
119
+ outputPer1M: 0.6,
120
+ effectiveDate: '2024-07-18',
121
+ },
122
+ {
123
+ provider: 'openai',
124
+ model: 'gpt-4o-mini-2024-07-18',
125
+ inputPer1M: 0.15,
126
+ outputPer1M: 0.6,
127
+ effectiveDate: '2024-07-18',
128
+ },
129
+ {
130
+ provider: 'openai',
131
+ model: 'gpt-4-turbo',
132
+ inputPer1M: 10.0,
133
+ outputPer1M: 30.0,
134
+ effectiveDate: '2024-04-09',
135
+ },
136
+ {
137
+ provider: 'openai',
138
+ model: 'gpt-4-turbo-2024-04-09',
139
+ inputPer1M: 10.0,
140
+ outputPer1M: 30.0,
141
+ effectiveDate: '2024-04-09',
142
+ },
143
+ {
144
+ provider: 'openai',
145
+ model: 'gpt-4',
146
+ inputPer1M: 30.0,
147
+ outputPer1M: 60.0,
148
+ effectiveDate: '2023-03-14',
149
+ },
150
+ {
151
+ provider: 'openai',
152
+ model: 'gpt-3.5-turbo',
153
+ inputPer1M: 0.5,
154
+ outputPer1M: 1.5,
155
+ effectiveDate: '2023-11-06',
156
+ },
157
+ {
158
+ provider: 'openai',
159
+ model: 'o1',
160
+ inputPer1M: 15.0,
161
+ outputPer1M: 60.0,
162
+ effectiveDate: '2024-12-17',
163
+ },
164
+ {
165
+ provider: 'openai',
166
+ model: 'o1-2024-12-17',
167
+ inputPer1M: 15.0,
168
+ outputPer1M: 60.0,
169
+ effectiveDate: '2024-12-17',
170
+ },
171
+ {
172
+ provider: 'openai',
173
+ model: 'o1-preview',
174
+ inputPer1M: 15.0,
175
+ outputPer1M: 60.0,
176
+ effectiveDate: '2024-09-12',
177
+ },
178
+ {
179
+ provider: 'openai',
180
+ model: 'o1-preview-2024-09-12',
181
+ inputPer1M: 15.0,
182
+ outputPer1M: 60.0,
183
+ effectiveDate: '2024-09-12',
184
+ },
185
+ {
186
+ provider: 'openai',
187
+ model: 'o1-mini',
188
+ inputPer1M: 3.0,
189
+ outputPer1M: 12.0,
190
+ effectiveDate: '2024-09-12',
191
+ },
192
+ {
193
+ provider: 'openai',
194
+ model: 'o1-mini-2024-09-12',
195
+ inputPer1M: 3.0,
196
+ outputPer1M: 12.0,
197
+ effectiveDate: '2024-09-12',
198
+ },
199
+
200
+ // Google Gemini Models
201
+ {
202
+ provider: 'gemini',
203
+ model: 'gemini-2.0-flash-exp',
204
+ inputPer1M: 0.0,
205
+ outputPer1M: 0.0,
206
+ effectiveDate: '2024-12-11',
207
+ },
208
+ {
209
+ provider: 'gemini',
210
+ model: 'gemini-2.0-flash',
211
+ inputPer1M: 0.075,
212
+ outputPer1M: 0.3,
213
+ effectiveDate: '2025-01-01',
214
+ },
215
+ {
216
+ provider: 'gemini',
217
+ model: 'gemini-exp-1206',
218
+ inputPer1M: 0.0,
219
+ outputPer1M: 0.0,
220
+ effectiveDate: '2024-12-06',
221
+ },
222
+ {
223
+ provider: 'gemini',
224
+ model: 'gemini-1.5-pro',
225
+ inputPer1M: 1.25,
226
+ outputPer1M: 5.0,
227
+ effectiveDate: '2024-05-14',
228
+ },
229
+ {
230
+ provider: 'gemini',
231
+ model: 'gemini-1.5-pro-002',
232
+ inputPer1M: 1.25,
233
+ outputPer1M: 5.0,
234
+ effectiveDate: '2024-09-24',
235
+ },
236
+ {
237
+ provider: 'gemini',
238
+ model: 'gemini-1.5-flash',
239
+ inputPer1M: 0.075,
240
+ outputPer1M: 0.3,
241
+ effectiveDate: '2024-05-14',
242
+ },
243
+ {
244
+ provider: 'gemini',
245
+ model: 'gemini-1.5-flash-002',
246
+ inputPer1M: 0.075,
247
+ outputPer1M: 0.3,
248
+ effectiveDate: '2024-09-24',
249
+ },
250
+ {
251
+ provider: 'gemini',
252
+ model: 'gemini-1.5-flash-8b',
253
+ inputPer1M: 0.0375,
254
+ outputPer1M: 0.15,
255
+ effectiveDate: '2024-10-03',
256
+ },
257
+
258
+ // Google Vertex AI (same pricing as Gemini)
259
+ {
260
+ provider: 'vertex-ai',
261
+ model: 'gemini-2.0-flash-exp',
262
+ inputPer1M: 0.0,
263
+ outputPer1M: 0.0,
264
+ effectiveDate: '2024-12-11',
265
+ },
266
+ {
267
+ provider: 'vertex-ai',
268
+ model: 'gemini-2.0-flash',
269
+ inputPer1M: 0.075,
270
+ outputPer1M: 0.3,
271
+ effectiveDate: '2025-01-01',
272
+ },
273
+ {
274
+ provider: 'vertex-ai',
275
+ model: 'gemini-exp-1206',
276
+ inputPer1M: 0.0,
277
+ outputPer1M: 0.0,
278
+ effectiveDate: '2024-12-06',
279
+ },
280
+ {
281
+ provider: 'vertex-ai',
282
+ model: 'gemini-1.5-pro',
283
+ inputPer1M: 1.25,
284
+ outputPer1M: 5.0,
285
+ effectiveDate: '2024-05-14',
286
+ },
287
+ {
288
+ provider: 'vertex-ai',
289
+ model: 'gemini-1.5-pro-002',
290
+ inputPer1M: 1.25,
291
+ outputPer1M: 5.0,
292
+ effectiveDate: '2024-09-24',
293
+ },
294
+ {
295
+ provider: 'vertex-ai',
296
+ model: 'gemini-1.5-flash',
297
+ inputPer1M: 0.075,
298
+ outputPer1M: 0.3,
299
+ effectiveDate: '2024-05-14',
300
+ },
301
+ {
302
+ provider: 'vertex-ai',
303
+ model: 'gemini-1.5-flash-002',
304
+ inputPer1M: 0.075,
305
+ outputPer1M: 0.3,
306
+ effectiveDate: '2024-09-24',
307
+ },
308
+ {
309
+ provider: 'vertex-ai',
310
+ model: 'gemini-1.5-flash-8b',
311
+ inputPer1M: 0.0375,
312
+ outputPer1M: 0.15,
313
+ effectiveDate: '2024-10-03',
314
+ },
315
+ ];
316
+
317
+ /**
318
+ * Get pricing for a specific model
319
+ */
320
+ export function getModelPricing(
321
+ provider: string,
322
+ model: string
323
+ ): ModelPricing | undefined {
324
+ return MODEL_PRICING.find(
325
+ (p) => p.provider === provider && p.model === model
326
+ );
327
+ }
328
+
329
+ /**
330
+ * Get all pricing for a provider
331
+ */
332
+ export function getProviderPricing(provider: string): ModelPricing[] {
333
+ return MODEL_PRICING.filter((p) => p.provider === provider);
334
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Pricing and cost tracking types
3
+ */
4
+
5
+ /**
6
+ * Token usage information
7
+ */
8
+ export interface TokenUsage {
9
+ inputTokens: number;
10
+ outputTokens: number;
11
+ }
12
+
13
+ /**
14
+ * Cost estimate in USD
15
+ */
16
+ export interface CostEstimate {
17
+ inputCost: number;
18
+ outputCost: number;
19
+ totalCost: number;
20
+ currency: string; // 'USD'
21
+ }
22
+
23
+ /**
24
+ * Model pricing per 1M tokens (USD)
25
+ */
26
+ export interface ModelPricing {
27
+ provider: string;
28
+ model: string;
29
+ inputPer1M: number; // USD per 1M input tokens
30
+ outputPer1M: number; // USD per 1M output tokens
31
+ effectiveDate?: string; // When this pricing became effective
32
+ }
@@ -61,6 +61,48 @@ When making changes to files, first understand the file's code conventions. Mimi
61
61
  - Do not add docstrings, type annotations, or comments to code you didn't change
62
62
  - Keep solutions simple and focused. Only make changes directly requested or clearly necessary.
63
63
 
64
+ # Asking Questions
65
+
66
+ You have access to the AskUserQuestion tool to ask the user questions during execution.
67
+
68
+ CRITICAL: You MUST use the AskUserQuestion tool for ALL questions with choices. NEVER write numbered lists, bullet points, or "which do you prefer" questions as plain text.
69
+
70
+ ## Wrong - Plain Text Questions (DO NOT DO THIS)
71
+
72
+ <bad-example>
73
+ user: Set up a new database
74
+ assistant: I can set up a database for you. Which one would you prefer?
75
+ 1. PostgreSQL - relational database
76
+ 2. MongoDB - document database
77
+ 3. SQLite - embedded database
78
+ </bad-example>
79
+
80
+ <bad-example>
81
+ user: Create a new project
82
+ assistant: What type of project?
83
+ - Web app
84
+ - CLI tool
85
+ - API server
86
+ </bad-example>
87
+
88
+ ## Correct - Use AskUserQuestion Tool
89
+
90
+ <example>
91
+ user: Set up a new database
92
+ assistant: [uses AskUserQuestion tool with questions: [{question: "Which database?", header: "Database", options: [{label: "PostgreSQL", description: "Relational DB"}, {label: "MongoDB", description: "Document DB"}], multiSelect: false}]]
93
+ </example>
94
+
95
+ <example>
96
+ user: Create a new project
97
+ assistant: [uses AskUserQuestion tool to ask about project type, framework preferences, etc.]
98
+ </example>
99
+
100
+ Use AskUserQuestion when you need to:
101
+ - Gather user preferences (database choice, framework, etc.)
102
+ - Clarify ambiguous instructions with specific options
103
+ - Get decisions on implementation approaches
104
+ - Offer choices about direction to take
105
+
64
106
  # Task Management
65
107
 
66
108
  You have access to the TodoWrite tool to manage tasks.
@@ -0,0 +1,110 @@
1
+ Use this tool when you need to ask the user questions during execution.
2
+
3
+ CRITICAL: You MUST use this tool for ANY question with 2+ choices. NEVER present options as plain text, numbered lists, or bullet points.
4
+
5
+ WRONG (never do this):
6
+ - "Which do you prefer? 1. Option A 2. Option B"
7
+ - "What type? - Web - CLI - API"
8
+ - Writing any numbered or bulleted choices in your response
9
+
10
+ CORRECT: Call this tool with structured questions and options.
11
+
12
+ This allows you to:
13
+ 1. Gather user preferences or requirements
14
+ 2. Clarify ambiguous instructions
15
+ 3. Get decisions on implementation choices as you work
16
+ 4. Offer choices to the user about what direction to take
17
+
18
+ ## When to Use This Tool
19
+
20
+ Use when you encounter:
21
+ - Ambiguous requirements that could be interpreted multiple ways
22
+ - Technology choices where user preference matters (database, framework, etc.)
23
+ - Implementation approaches with different trade-offs
24
+ - Features or options that should be user-selected
25
+
26
+ ## When NOT to Use This Tool
27
+
28
+ Don't use for:
29
+ - Asking "Is my plan ready?" or "Should I proceed?" - just proceed or use planning tools
30
+ - Simple yes/no confirmations - just make a reasonable choice
31
+ - Questions you can answer by reading the codebase
32
+ - Trivial implementation details
33
+
34
+ ## Usage Guidelines
35
+
36
+ - Keep headers short (max 12 chars): "Database", "Auth", "Features"
37
+ - Provide 2-4 options per question
38
+ - Put recommended option FIRST and add "(Recommended)" to its label
39
+ - Use multiSelect: true for non-mutually-exclusive options
40
+ - "Other" option is automatically added - don't include it manually
41
+ - Keep option labels concise (1-5 words)
42
+ - Descriptions should explain trade-offs or implications
43
+
44
+ ## Examples
45
+
46
+ ### Single Choice - Technology Selection
47
+ ```json
48
+ {
49
+ "questions": [{
50
+ "question": "Which database should we use?",
51
+ "header": "Database",
52
+ "options": [
53
+ { "label": "PostgreSQL (Recommended)", "description": "Robust relational DB" },
54
+ { "label": "MongoDB", "description": "Document-based NoSQL" },
55
+ { "label": "SQLite", "description": "Lightweight embedded DB" }
56
+ ],
57
+ "multiSelect": false
58
+ }]
59
+ }
60
+ ```
61
+
62
+ ### Multi-Select - Feature Selection
63
+ ```json
64
+ {
65
+ "questions": [{
66
+ "question": "Which features should we enable?",
67
+ "header": "Features",
68
+ "options": [
69
+ { "label": "TypeScript", "description": "Type safety" },
70
+ { "label": "ESLint", "description": "Code linting" },
71
+ { "label": "Testing", "description": "Unit tests" },
72
+ { "label": "Tailwind", "description": "CSS framework" }
73
+ ],
74
+ "multiSelect": true
75
+ }]
76
+ }
77
+ ```
78
+
79
+ ### Multiple Questions
80
+ ```json
81
+ {
82
+ "questions": [
83
+ {
84
+ "question": "Which auth method?",
85
+ "header": "Auth",
86
+ "options": [
87
+ { "label": "OAuth 2.0 (Recommended)", "description": "Industry standard" },
88
+ { "label": "JWT", "description": "Stateless tokens" }
89
+ ],
90
+ "multiSelect": false
91
+ },
92
+ {
93
+ "question": "Which providers to support?",
94
+ "header": "Providers",
95
+ "options": [
96
+ { "label": "Google", "description": "Most common" },
97
+ { "label": "GitHub", "description": "Developer-focused" }
98
+ ],
99
+ "multiSelect": true
100
+ }
101
+ ]
102
+ }
103
+ ```
104
+
105
+ ## Constraints
106
+
107
+ - Maximum 4 questions per call
108
+ - Maximum 4 options per question
109
+ - Header: max 12 characters
110
+ - multiSelect must be explicitly set (required, not optional)
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import Anthropic from '@anthropic-ai/sdk';
7
+ import { calculateCost } from '../pricing/calculator.js';
7
8
  import type {
8
9
  LLMProvider,
9
10
  CompletionOptions,
@@ -45,7 +46,7 @@ export class AnthropicProvider implements LLMProvider {
45
46
  temperature: options.temperature,
46
47
  });
47
48
 
48
- return this.convertResponse(response);
49
+ return this.convertResponse(response, options.model);
49
50
  }
50
51
 
51
52
  async *stream(options: CompletionOptions): AsyncGenerator<StreamChunk, void, unknown> {
@@ -94,15 +95,20 @@ export class AnthropicProvider implements LLMProvider {
94
95
  const finalMessage = await stream.finalMessage();
95
96
  const content = this.convertContent(finalMessage.content);
96
97
 
98
+ const usage = {
99
+ inputTokens: finalMessage.usage.input_tokens,
100
+ outputTokens: finalMessage.usage.output_tokens,
101
+ };
102
+
103
+ const cost = calculateCost(this.name, options.model, usage);
104
+
97
105
  yield {
98
106
  type: 'done',
99
107
  response: {
100
108
  content,
101
109
  stopReason: this.convertStopReason(finalMessage.stop_reason),
102
- usage: {
103
- inputTokens: finalMessage.usage.input_tokens,
104
- outputTokens: finalMessage.usage.output_tokens,
105
- },
110
+ usage,
111
+ cost,
106
112
  },
107
113
  };
108
114
  }
@@ -169,14 +175,19 @@ export class AnthropicProvider implements LLMProvider {
169
175
  }));
170
176
  }
171
177
 
172
- private convertResponse(response: Anthropic.Message): CompletionResponse {
178
+ private convertResponse(response: Anthropic.Message, model: string): CompletionResponse {
179
+ const usage = {
180
+ inputTokens: response.usage.input_tokens,
181
+ outputTokens: response.usage.output_tokens,
182
+ };
183
+
184
+ const cost = calculateCost(this.name, model, usage);
185
+
173
186
  return {
174
187
  content: this.convertContent(response.content),
175
188
  stopReason: this.convertStopReason(response.stop_reason),
176
- usage: {
177
- inputTokens: response.usage.input_tokens,
178
- outputTokens: response.usage.output_tokens,
179
- },
189
+ usage,
190
+ cost,
180
191
  };
181
192
  }
182
193
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { GoogleGenerativeAI, SchemaType } from '@google/generative-ai';
7
7
  import type { Content, Part, Tool, GenerateContentResult } from '@google/generative-ai';
8
+ import { calculateCost } from '../pricing/calculator.js';
8
9
  import type {
9
10
  LLMProvider,
10
11
  CompletionOptions,
@@ -47,7 +48,7 @@ export class GeminiProvider implements LLMProvider {
47
48
  const contents = this.convertMessages(options.messages);
48
49
  const result = await model.generateContent({ contents });
49
50
 
50
- return this.convertResponse(result);
51
+ return this.convertResponse(result, options.model);
51
52
  }
52
53
 
53
54
  async *stream(options: CompletionOptions): AsyncGenerator<StreamChunk, void, unknown> {
@@ -115,17 +116,22 @@ export class GeminiProvider implements LLMProvider {
115
116
  const finalResponse = await result.response;
116
117
  const stopReason = this.getStopReason(finalResponse, functionCalls.length > 0);
117
118
 
119
+ const usage = finalResponse.usageMetadata
120
+ ? {
121
+ inputTokens: finalResponse.usageMetadata.promptTokenCount ?? 0,
122
+ outputTokens: finalResponse.usageMetadata.candidatesTokenCount ?? 0,
123
+ }
124
+ : undefined;
125
+
126
+ const cost = usage ? calculateCost(this.name, options.model, usage) : undefined;
127
+
118
128
  yield {
119
129
  type: 'done',
120
130
  response: {
121
131
  content,
122
132
  stopReason,
123
- usage: finalResponse.usageMetadata
124
- ? {
125
- inputTokens: finalResponse.usageMetadata.promptTokenCount ?? 0,
126
- outputTokens: finalResponse.usageMetadata.candidatesTokenCount ?? 0,
127
- }
128
- : undefined,
133
+ usage,
134
+ cost,
129
135
  },
130
136
  };
131
137
  }
@@ -237,7 +243,7 @@ export class GeminiProvider implements LLMProvider {
237
243
  return result;
238
244
  }
239
245
 
240
- private convertResponse(result: GenerateContentResult): CompletionResponse {
246
+ private convertResponse(result: GenerateContentResult, model: string): CompletionResponse {
241
247
  const response = result.response;
242
248
  const parts = response.candidates?.[0]?.content?.parts ?? [];
243
249
  const content: MessageContent[] = [];
@@ -261,15 +267,20 @@ export class GeminiProvider implements LLMProvider {
261
267
 
262
268
  const hasFunctionCalls = parts.some((p) => 'functionCall' in p);
263
269
 
270
+ const usage = response.usageMetadata
271
+ ? {
272
+ inputTokens: response.usageMetadata.promptTokenCount ?? 0,
273
+ outputTokens: response.usageMetadata.candidatesTokenCount ?? 0,
274
+ }
275
+ : undefined;
276
+
277
+ const cost = usage ? calculateCost(this.name, model, usage) : undefined;
278
+
264
279
  return {
265
280
  content,
266
281
  stopReason: this.getStopReason(response, hasFunctionCalls),
267
- usage: response.usageMetadata
268
- ? {
269
- inputTokens: response.usageMetadata.promptTokenCount ?? 0,
270
- outputTokens: response.usageMetadata.candidatesTokenCount ?? 0,
271
- }
272
- : undefined,
282
+ usage,
283
+ cost,
273
284
  };
274
285
  }
275
286