csv-charts-ai 1.2.0 → 1.3.1

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/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { LanguageModel } from 'ai';
3
3
  import { z } from 'zod';
4
4
 
5
+ declare const VERSION: string;
6
+
5
7
  type ChartType = "bar" | "line" | "pie" | "scatter" | "area";
6
8
  type AggregationType = "sum" | "avg" | "count" | "min" | "max" | "none";
7
9
  interface TabularData {
@@ -159,6 +161,7 @@ declare function summarizeTabularData(data: TabularData): string;
159
161
  * ```
160
162
  */
161
163
  declare function createModel(config: AIConfig): Promise<LanguageModel>;
164
+ declare function resolveModel(input: ModelInput): Promise<LanguageModel>;
162
165
  interface SuggestChartsOptions {
163
166
  /** The AI model — either a simple config or a LanguageModel instance */
164
167
  model: ModelInput;
@@ -395,4 +398,4 @@ interface AnalyzeOptions {
395
398
  */
396
399
  declare function analyzeData(options: AnalyzeOptions): Promise<AnalysisResult>;
397
400
 
398
- export { type AIConfig, AIConfigSchema, type AggregationType, type AnalysisResult, type AnalyzeOptions, type AnomalyResult, type AskAboutDataOptions, COLORS, type ChartConfig, type ChartDataPoint, ChartDisplay, type ChartDisplayProps, type ChartTheme, ChartThemeProvider, ChartToolbar, type ChartType, type DataSummaryResult, type DetectAnomaliesOptions, type ModelInput, type ProcessedChartResult, type RepairChartOptions, SingleChart, type SingleChartProps, type SortOrder, type StreamAskAboutDataOptions, type SuggestChartsOptions, type SuggestCustomChartOptions, type SummarizeDataOptions, type TabularData, TabularDataSchema, analyzeData, askAboutData, createModel, defaultDarkTheme, defaultLightTheme, detectAnomalies, getAIErrorMessage, processChartData, processChartDataMultiSeries, repairChart, streamAskAboutData, suggestCharts, suggestCustomChart, summarizeData, summarizeTabularData, useChartTheme };
401
+ export { type AIConfig, AIConfigSchema, type AggregationType, type AnalysisResult, type AnalyzeOptions, type AnomalyResult, type AskAboutDataOptions, COLORS, type ChartConfig, type ChartDataPoint, ChartDisplay, type ChartDisplayProps, type ChartTheme, ChartThemeProvider, ChartToolbar, type ChartType, type DataSummaryResult, type DetectAnomaliesOptions, type ModelInput, type ProcessedChartResult, type RepairChartOptions, SingleChart, type SingleChartProps, type SortOrder, type StreamAskAboutDataOptions, type SuggestChartsOptions, type SuggestCustomChartOptions, type SummarizeDataOptions, type TabularData, TabularDataSchema, VERSION, analyzeData, askAboutData, createModel, defaultDarkTheme, defaultLightTheme, detectAnomalies, getAIErrorMessage, processChartData, processChartDataMultiSeries, repairChart, resolveModel, streamAskAboutData, suggestCharts, suggestCustomChart, summarizeData, summarizeTabularData, useChartTheme };
package/dist/index.js CHANGED
@@ -1,303 +1,66 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res) => function __init() {
4
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
- };
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
-
11
- // src/ai.ts
12
- var ai_exports = {};
13
- __export(ai_exports, {
14
- AIConfigSchema: () => AIConfigSchema,
15
- TabularDataSchema: () => TabularDataSchema,
16
- createModel: () => createModel,
17
- getAIErrorMessage: () => getAIErrorMessage,
18
- repairChart: () => repairChart,
19
- suggestCharts: () => suggestCharts,
20
- suggestCustomChart: () => suggestCustomChart,
21
- summarizeTabularData: () => summarizeTabularData
22
- });
23
- import { generateObject } from "ai";
24
- import { z } from "zod";
25
- function getAIErrorMessage(error) {
26
- if (error instanceof Error) {
27
- const message = error.message.toLowerCase();
28
- if (message.includes("rate limit") || message.includes("429")) {
29
- return "Rate limit exceeded. Please wait a moment and try again.";
1
+ // package.json
2
+ var package_default = {
3
+ name: "csv-charts-ai",
4
+ version: "1.3.1",
5
+ type: "module",
6
+ repository: {
7
+ type: "git",
8
+ url: "https://github.com/maxgfr/csv-ai-analyzer",
9
+ directory: "packages/csv-charts-ai"
10
+ },
11
+ main: "./dist/index.js",
12
+ types: "./dist/index.d.ts",
13
+ exports: {
14
+ ".": {
15
+ import: "./dist/index.js",
16
+ types: "./dist/index.d.ts"
30
17
  }
31
- if (message.includes("unauthorized") || message.includes("401") || message.includes("invalid api key") || message.includes("invalid_api_key")) {
32
- return "Invalid API key. Please check your API key configuration.";
33
- }
34
- if (message.includes("quota") || message.includes("insufficient_quota") || message.includes("billing")) {
35
- return "API quota exceeded or billing issue. Please check your account status.";
36
- }
37
- if (message.includes("network") || message.includes("timeout") || message.includes("econnrefused") || message.includes("fetch failed")) {
38
- return "Network error. Please check your internet connection and try again.";
39
- }
40
- if (message.includes("model") && (message.includes("not found") || message.includes("does not exist"))) {
41
- return "Model not available. Please select a different model.";
42
- }
43
- return error.message;
44
- }
45
- return "An unexpected error occurred. Please try again.";
46
- }
47
- function summarizeTabularData(data) {
48
- const lines = [];
49
- lines.push(`Dataset: ${data.rowCount} rows, ${data.headers.length} columns`);
50
- lines.push(`Columns: ${data.headers.join(", ")}`);
51
- lines.push("");
52
- for (const col of data.columns) {
53
- const idx = col.index;
54
- const values = data.rows.map((r) => r[idx] ?? "").filter((v) => v !== "");
55
- if (col.type === "number") {
56
- const nums = values.map(Number).filter((n) => !isNaN(n));
57
- if (nums.length > 0) {
58
- const min = Math.min(...nums);
59
- const max = Math.max(...nums);
60
- const avg = nums.reduce((a, b) => a + b, 0) / nums.length;
61
- lines.push(
62
- `- ${col.name} (${col.type}): min=${min}, max=${max}, avg=${avg.toFixed(2)}, ${nums.length} values`
63
- );
64
- } else {
65
- lines.push(`- ${col.name} (${col.type}): no valid numeric values`);
66
- }
67
- } else {
68
- const distinct = new Set(values).size;
69
- const sample = values.slice(0, 5).join(", ");
70
- lines.push(
71
- `- ${col.name} (${col.type}): ${distinct} distinct values, sample: [${sample}]`
72
- );
73
- }
74
- }
75
- return lines.join("\n");
76
- }
77
- function isLanguageModel(input) {
78
- return typeof input === "object" && input !== null && "doGenerate" in input && typeof input.doGenerate === "function";
79
- }
80
- async function createModel(config) {
81
- const parsed = AIConfigSchema.parse(config);
82
- if (parsed.baseURL || parsed.provider === "openai") {
83
- const { createOpenAI } = await import("@ai-sdk/openai");
84
- const openai = createOpenAI({
85
- apiKey: parsed.apiKey,
86
- ...parsed.baseURL && { baseURL: parsed.baseURL }
87
- });
88
- return openai(parsed.model);
89
- }
90
- switch (parsed.provider) {
91
- case "anthropic": {
92
- try {
93
- const { createAnthropic } = await import("@ai-sdk/anthropic");
94
- return createAnthropic({ apiKey: parsed.apiKey })(parsed.model);
95
- } catch {
96
- throw new Error(
97
- 'Provider "anthropic" requires @ai-sdk/anthropic. Install it: pnpm add @ai-sdk/anthropic'
98
- );
99
- }
100
- }
101
- case "google": {
102
- try {
103
- const { createGoogleGenerativeAI } = await import("@ai-sdk/google");
104
- return createGoogleGenerativeAI({ apiKey: parsed.apiKey })(
105
- parsed.model
106
- );
107
- } catch {
108
- throw new Error(
109
- 'Provider "google" requires @ai-sdk/google. Install it: pnpm add @ai-sdk/google'
110
- );
111
- }
112
- }
113
- case "mistral": {
114
- try {
115
- const { createMistral } = await import("@ai-sdk/mistral");
116
- return createMistral({ apiKey: parsed.apiKey })(parsed.model);
117
- } catch {
118
- throw new Error(
119
- 'Provider "mistral" requires @ai-sdk/mistral. Install it: pnpm add @ai-sdk/mistral'
120
- );
121
- }
122
- }
123
- default: {
124
- const { createOpenAI } = await import("@ai-sdk/openai");
125
- const openai = createOpenAI({
126
- apiKey: parsed.apiKey
127
- });
128
- return openai(parsed.model);
129
- }
130
- }
131
- }
132
- async function resolveModel(input) {
133
- if (isLanguageModel(input)) return input;
134
- return createModel(input);
135
- }
136
- function mapChartResult(raw, id) {
137
- return {
138
- id,
139
- type: raw.type,
140
- title: raw.title,
141
- description: raw.description,
142
- xAxis: raw.xColumn,
143
- yAxis: raw.yColumn,
144
- groupBy: raw.groupColumn,
145
- aggregation: raw.aggregation,
146
- dataConfig: {
147
- xColumn: raw.xColumn,
148
- yColumn: raw.yColumn,
149
- groupColumn: raw.groupColumn
18
+ },
19
+ files: [
20
+ "dist"
21
+ ],
22
+ scripts: {
23
+ build: "tsup",
24
+ dev: "tsup --watch"
25
+ },
26
+ peerDependencies: {
27
+ ai: "^5.0.0 || ^6.0.0",
28
+ "lucide-react": ">=0.400.0",
29
+ react: "^18.0.0 || ^19.0.0",
30
+ recharts: "^3.0.0",
31
+ zod: "^4.0.0"
32
+ },
33
+ peerDependenciesMeta: {
34
+ react: {
35
+ optional: true
36
+ },
37
+ recharts: {
38
+ optional: true
39
+ },
40
+ "lucide-react": {
41
+ optional: true
150
42
  }
151
- };
152
- }
153
- async function suggestCharts(options) {
154
- const { data, language, temperature = 0.5 } = options;
155
- const dataSummary = options.dataSummary ?? summarizeTabularData(data);
156
- TabularDataSchema.parse(data);
157
- try {
158
- const model = await resolveModel(options.model);
159
- const { object } = await generateObject({
160
- model,
161
- schema: ChartSuggestionsResponseSchema,
162
- system: getChartSystemPrompt(data.headers, language),
163
- prompt: `Analyze this CSV data and suggest the best charts:
164
-
165
- ${dataSummary}`,
166
- temperature
167
- });
168
- return object.charts.map(
169
- (s, i) => mapChartResult(s, `chart-${i}-${Date.now()}`)
170
- );
171
- } catch (error) {
172
- throw new Error(getAIErrorMessage(error));
173
- }
174
- }
175
- async function suggestCustomChart(options) {
176
- const { data, prompt, language, temperature = 0.5 } = options;
177
- const dataSummary = options.dataSummary ?? summarizeTabularData(data);
178
- TabularDataSchema.parse(data);
179
- try {
180
- const model = await resolveModel(options.model);
181
- const { object } = await generateObject({
182
- model,
183
- schema: SingleChartResponseSchema,
184
- system: getCustomChartPrompt(data.headers, language),
185
- prompt: `Data summary:
186
- ${dataSummary}
187
-
188
- User request: ${prompt}`,
189
- temperature
190
- });
191
- return mapChartResult(object.chart, `chart-custom-${Date.now()}`);
192
- } catch (error) {
193
- console.error("Custom chart generation failed:", getAIErrorMessage(error));
194
- return null;
43
+ },
44
+ devDependencies: {
45
+ "@types/react": "^19.2.7",
46
+ ai: "^6.0.134",
47
+ "lucide-react": "^0.556.0",
48
+ react: "^19.2.4",
49
+ recharts: "^3.5.1",
50
+ tsup: "^8.5.0",
51
+ typescript: "^5.9.3",
52
+ zod: "^4.1.13"
53
+ },
54
+ publishConfig: {
55
+ access: "public"
56
+ },
57
+ dependencies: {
58
+ "@ai-sdk/openai": "^3.0.47"
195
59
  }
196
- }
197
- async function repairChart(options) {
198
- const {
199
- failedChart,
200
- columns,
201
- errorContext,
202
- language,
203
- temperature = 0.3
204
- } = options;
205
- try {
206
- const model = await resolveModel(options.model);
207
- const { object } = await generateObject({
208
- model,
209
- schema: SingleChartResponseSchema,
210
- system: getCustomChartPrompt(columns, language),
211
- prompt: `The following chart configuration failed to render:
212
- ${JSON.stringify(failedChart, null, 2)}
213
-
214
- Error context: ${errorContext}
215
-
216
- Please fix the configuration to use valid columns and aggregation. Available columns: ${columns.join(", ")}`,
217
- temperature
218
- });
219
- return mapChartResult(object.chart, failedChart.id);
220
- } catch {
221
- return null;
222
- }
223
- }
224
- var AIConfigSchema, TabularDataSchema, ChartSuggestionSchema, ChartSuggestionsResponseSchema, SingleChartResponseSchema, getChartSystemPrompt, getCustomChartPrompt;
225
- var init_ai = __esm({
226
- "src/ai.ts"() {
227
- "use strict";
228
- AIConfigSchema = z.object({
229
- /** API key for authentication */
230
- apiKey: z.string(),
231
- /** Model identifier (e.g. "gpt-4o", "llama3", "mistral-large") */
232
- model: z.string(),
233
- /** Custom base URL for non-OpenAI providers (Ollama, vLLM, Mistral, etc.) */
234
- baseURL: z.string().optional(),
235
- /** Provider hint — used to dynamically load the right SDK. Defaults to "openai". */
236
- provider: z.enum(["openai", "anthropic", "google", "mistral"]).optional().default("openai")
237
- });
238
- TabularDataSchema = z.object({
239
- headers: z.array(z.string()).min(1, "Data must have at least one column"),
240
- rows: z.array(z.array(z.string())),
241
- columns: z.array(
242
- z.object({
243
- name: z.string(),
244
- type: z.enum(["string", "number", "date", "boolean"]),
245
- index: z.number()
246
- })
247
- ),
248
- rowCount: z.number()
249
- });
250
- ChartSuggestionSchema = z.object({
251
- type: z.enum(["bar", "line", "pie", "scatter", "area"]),
252
- title: z.string(),
253
- description: z.string(),
254
- xColumn: z.string().describe("The EXACT column name to use for X axis (categories/labels)"),
255
- yColumn: z.string().describe("The EXACT column name to use for Y axis (values)"),
256
- groupColumn: z.string().optional().describe("Optional column to group/segment the data"),
257
- aggregation: z.enum(["sum", "avg", "count", "min", "max", "none"]).describe("How to aggregate Y values when there are duplicates in X"),
258
- reasoning: z.string().describe("Brief explanation of why this chart is useful for this data")
259
- });
260
- ChartSuggestionsResponseSchema = z.object({
261
- charts: z.array(ChartSuggestionSchema)
262
- });
263
- SingleChartResponseSchema = z.object({
264
- chart: ChartSuggestionSchema
265
- });
266
- getChartSystemPrompt = (columns, language) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : ""}
267
-
268
- You will analyze CSV data and suggest the best charts to visualize it.
269
-
270
- AVAILABLE COLUMNS (use these EXACT names):
271
- ${columns.map((c) => `- "${c}"`).join("\n")}
272
-
273
- CRITICAL RULES:
274
- 1. xColumn and yColumn MUST be exact column names from the list above
275
- 2. For numeric analysis, yColumn should be a numeric column
276
- 3. For categorical comparisons, xColumn should be a categorical column
277
- 4. Only suggest charts that make sense for the data types
278
- 5. Use aggregation when there are multiple rows per category:
279
- - "sum" for totals (sales, revenue)
280
- - "avg" for averages (ratings, scores)
281
- - "count" for frequencies
282
- - "none" for unique values or time series
283
- 6. Suggest 2-4 charts maximum, focusing on the most insightful ones
284
-
285
- CHART TYPE GUIDELINES:
286
- - bar: Compare categories (xColumn=category, yColumn=numeric)
287
- - line: Show trends over time (xColumn=date/time, yColumn=numeric)
288
- - pie: Show proportions (xColumn=category, yColumn=numeric with sum/count)
289
- - scatter: Show correlations (xColumn=numeric, yColumn=numeric, aggregation=none)
290
- - area: Show cumulative trends (xColumn=date/time, yColumn=numeric)`;
291
- getCustomChartPrompt = (columns, language) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : ""}
292
-
293
- Create a chart configuration based on the user's request.
294
-
295
- AVAILABLE COLUMNS (use these EXACT names):
296
- ${columns.map((c) => `- "${c}"`).join("\n")}
60
+ };
297
61
 
298
- IMPORTANT: Column names MUST exactly match the list above.`;
299
- }
300
- });
62
+ // src/version.ts
63
+ var VERSION = package_default.version;
301
64
 
302
65
  // src/types.ts
303
66
  var defaultDarkTheme = {
@@ -1236,14 +999,280 @@ var COLORS = [
1236
999
  // Orange 500
1237
1000
  ];
1238
1001
 
1239
- // src/index.ts
1240
- init_ai();
1241
- init_ai();
1242
- init_ai();
1002
+ // src/ai.ts
1003
+ import { generateObject } from "ai";
1004
+ import { z } from "zod";
1005
+ var AIConfigSchema = z.object({
1006
+ /** API key for authentication */
1007
+ apiKey: z.string(),
1008
+ /** Model identifier (e.g. "gpt-4o", "llama3", "mistral-large") */
1009
+ model: z.string(),
1010
+ /** Custom base URL for non-OpenAI providers (Ollama, vLLM, Mistral, etc.) */
1011
+ baseURL: z.string().optional(),
1012
+ /** Provider hint — used to dynamically load the right SDK. Defaults to "openai". */
1013
+ provider: z.enum(["openai", "anthropic", "google", "mistral"]).optional().default("openai")
1014
+ });
1015
+ var TabularDataSchema = z.object({
1016
+ headers: z.array(z.string()).min(1, "Data must have at least one column"),
1017
+ rows: z.array(z.array(z.string())),
1018
+ columns: z.array(
1019
+ z.object({
1020
+ name: z.string(),
1021
+ type: z.enum(["string", "number", "date", "boolean"]),
1022
+ index: z.number()
1023
+ })
1024
+ ),
1025
+ rowCount: z.number()
1026
+ });
1027
+ var ChartSuggestionSchema = z.object({
1028
+ type: z.enum(["bar", "line", "pie", "scatter", "area"]),
1029
+ title: z.string(),
1030
+ description: z.string(),
1031
+ xColumn: z.string().describe("The EXACT column name to use for X axis (categories/labels)"),
1032
+ yColumn: z.string().describe("The EXACT column name to use for Y axis (values)"),
1033
+ groupColumn: z.string().optional().describe("Optional column to group/segment the data"),
1034
+ aggregation: z.enum(["sum", "avg", "count", "min", "max", "none"]).describe("How to aggregate Y values when there are duplicates in X"),
1035
+ reasoning: z.string().describe("Brief explanation of why this chart is useful for this data")
1036
+ });
1037
+ var ChartSuggestionsResponseSchema = z.object({
1038
+ charts: z.array(ChartSuggestionSchema)
1039
+ });
1040
+ var SingleChartResponseSchema = z.object({
1041
+ chart: ChartSuggestionSchema
1042
+ });
1043
+ function getAIErrorMessage(error) {
1044
+ if (error instanceof Error) {
1045
+ const message = error.message.toLowerCase();
1046
+ if (message.includes("rate limit") || message.includes("429")) {
1047
+ return "Rate limit exceeded. Please wait a moment and try again.";
1048
+ }
1049
+ if (message.includes("unauthorized") || message.includes("401") || message.includes("invalid api key") || message.includes("invalid_api_key")) {
1050
+ return "Invalid API key. Please check your API key configuration.";
1051
+ }
1052
+ if (message.includes("quota") || message.includes("insufficient_quota") || message.includes("billing")) {
1053
+ return "API quota exceeded or billing issue. Please check your account status.";
1054
+ }
1055
+ if (message.includes("network") || message.includes("timeout") || message.includes("econnrefused") || message.includes("fetch failed")) {
1056
+ return "Network error. Please check your internet connection and try again.";
1057
+ }
1058
+ if (message.includes("model") && (message.includes("not found") || message.includes("does not exist"))) {
1059
+ return "Model not available. Please select a different model.";
1060
+ }
1061
+ return error.message;
1062
+ }
1063
+ return "An unexpected error occurred. Please try again.";
1064
+ }
1065
+ function summarizeTabularData(data) {
1066
+ const lines = [];
1067
+ lines.push(`Dataset: ${data.rowCount} rows, ${data.headers.length} columns`);
1068
+ lines.push(`Columns: ${data.headers.join(", ")}`);
1069
+ lines.push("");
1070
+ for (const col of data.columns) {
1071
+ const idx = col.index;
1072
+ const values = data.rows.map((r) => r[idx] ?? "").filter((v) => v !== "");
1073
+ if (col.type === "number") {
1074
+ const nums = values.map(Number).filter((n) => !isNaN(n));
1075
+ if (nums.length > 0) {
1076
+ const min = Math.min(...nums);
1077
+ const max = Math.max(...nums);
1078
+ const avg = nums.reduce((a, b) => a + b, 0) / nums.length;
1079
+ lines.push(
1080
+ `- ${col.name} (${col.type}): min=${min}, max=${max}, avg=${avg.toFixed(2)}, ${nums.length} values`
1081
+ );
1082
+ } else {
1083
+ lines.push(`- ${col.name} (${col.type}): no valid numeric values`);
1084
+ }
1085
+ } else {
1086
+ const distinct = new Set(values).size;
1087
+ const sample = values.slice(0, 5).join(", ");
1088
+ lines.push(
1089
+ `- ${col.name} (${col.type}): ${distinct} distinct values, sample: [${sample}]`
1090
+ );
1091
+ }
1092
+ }
1093
+ return lines.join("\n");
1094
+ }
1095
+ function isLanguageModel(input) {
1096
+ return typeof input === "object" && input !== null && "doGenerate" in input && typeof input.doGenerate === "function";
1097
+ }
1098
+ async function createModel(config) {
1099
+ const parsed = AIConfigSchema.parse(config);
1100
+ if (parsed.baseURL || parsed.provider === "openai") {
1101
+ const { createOpenAI } = await import("@ai-sdk/openai");
1102
+ const openai = createOpenAI({
1103
+ apiKey: parsed.apiKey,
1104
+ ...parsed.baseURL && { baseURL: parsed.baseURL }
1105
+ });
1106
+ return openai(parsed.model);
1107
+ }
1108
+ switch (parsed.provider) {
1109
+ case "anthropic": {
1110
+ try {
1111
+ const { createAnthropic } = await import("@ai-sdk/anthropic");
1112
+ return createAnthropic({ apiKey: parsed.apiKey })(parsed.model);
1113
+ } catch {
1114
+ throw new Error(
1115
+ 'Provider "anthropic" requires @ai-sdk/anthropic. Install it: pnpm add @ai-sdk/anthropic'
1116
+ );
1117
+ }
1118
+ }
1119
+ case "google": {
1120
+ try {
1121
+ const { createGoogleGenerativeAI } = await import("@ai-sdk/google");
1122
+ return createGoogleGenerativeAI({ apiKey: parsed.apiKey })(
1123
+ parsed.model
1124
+ );
1125
+ } catch {
1126
+ throw new Error(
1127
+ 'Provider "google" requires @ai-sdk/google. Install it: pnpm add @ai-sdk/google'
1128
+ );
1129
+ }
1130
+ }
1131
+ case "mistral": {
1132
+ try {
1133
+ const { createMistral } = await import("@ai-sdk/mistral");
1134
+ return createMistral({ apiKey: parsed.apiKey })(parsed.model);
1135
+ } catch {
1136
+ throw new Error(
1137
+ 'Provider "mistral" requires @ai-sdk/mistral. Install it: pnpm add @ai-sdk/mistral'
1138
+ );
1139
+ }
1140
+ }
1141
+ default: {
1142
+ const { createOpenAI } = await import("@ai-sdk/openai");
1143
+ const openai = createOpenAI({
1144
+ apiKey: parsed.apiKey
1145
+ });
1146
+ return openai(parsed.model);
1147
+ }
1148
+ }
1149
+ }
1150
+ async function resolveModel(input) {
1151
+ if (isLanguageModel(input)) return input;
1152
+ return createModel(input);
1153
+ }
1154
+ var getChartSystemPrompt = (columns, language) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : ""}
1155
+
1156
+ You will analyze CSV data and suggest the best charts to visualize it.
1157
+
1158
+ AVAILABLE COLUMNS (use these EXACT names):
1159
+ ${columns.map((c) => `- "${c}"`).join("\n")}
1160
+
1161
+ CRITICAL RULES:
1162
+ 1. xColumn and yColumn MUST be exact column names from the list above
1163
+ 2. For numeric analysis, yColumn should be a numeric column
1164
+ 3. For categorical comparisons, xColumn should be a categorical column
1165
+ 4. Only suggest charts that make sense for the data types
1166
+ 5. Use aggregation when there are multiple rows per category:
1167
+ - "sum" for totals (sales, revenue)
1168
+ - "avg" for averages (ratings, scores)
1169
+ - "count" for frequencies
1170
+ - "none" for unique values or time series
1171
+ 6. Suggest 2-4 charts maximum, focusing on the most insightful ones
1172
+
1173
+ CHART TYPE GUIDELINES:
1174
+ - bar: Compare categories (xColumn=category, yColumn=numeric)
1175
+ - line: Show trends over time (xColumn=date/time, yColumn=numeric)
1176
+ - pie: Show proportions (xColumn=category, yColumn=numeric with sum/count)
1177
+ - scatter: Show correlations (xColumn=numeric, yColumn=numeric, aggregation=none)
1178
+ - area: Show cumulative trends (xColumn=date/time, yColumn=numeric)`;
1179
+ var getCustomChartPrompt = (columns, language) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : ""}
1180
+
1181
+ Create a chart configuration based on the user's request.
1182
+
1183
+ AVAILABLE COLUMNS (use these EXACT names):
1184
+ ${columns.map((c) => `- "${c}"`).join("\n")}
1185
+
1186
+ IMPORTANT: Column names MUST exactly match the list above.`;
1187
+ function mapChartResult(raw, id) {
1188
+ return {
1189
+ id,
1190
+ type: raw.type,
1191
+ title: raw.title,
1192
+ description: raw.description,
1193
+ xAxis: raw.xColumn,
1194
+ yAxis: raw.yColumn,
1195
+ groupBy: raw.groupColumn,
1196
+ aggregation: raw.aggregation,
1197
+ dataConfig: {
1198
+ xColumn: raw.xColumn,
1199
+ yColumn: raw.yColumn,
1200
+ groupColumn: raw.groupColumn
1201
+ }
1202
+ };
1203
+ }
1204
+ async function suggestCharts(options) {
1205
+ const { data, language, temperature = 0.5 } = options;
1206
+ const dataSummary = options.dataSummary ?? summarizeTabularData(data);
1207
+ TabularDataSchema.parse(data);
1208
+ try {
1209
+ const model = await resolveModel(options.model);
1210
+ const { object } = await generateObject({
1211
+ model,
1212
+ schema: ChartSuggestionsResponseSchema,
1213
+ system: getChartSystemPrompt(data.headers, language),
1214
+ prompt: `Analyze this CSV data and suggest the best charts:
1215
+
1216
+ ${dataSummary}`,
1217
+ temperature
1218
+ });
1219
+ return object.charts.map(
1220
+ (s, i) => mapChartResult(s, `chart-${i}-${Date.now()}`)
1221
+ );
1222
+ } catch (error) {
1223
+ throw new Error(getAIErrorMessage(error));
1224
+ }
1225
+ }
1226
+ async function suggestCustomChart(options) {
1227
+ const { data, prompt, language, temperature = 0.5 } = options;
1228
+ const dataSummary = options.dataSummary ?? summarizeTabularData(data);
1229
+ TabularDataSchema.parse(data);
1230
+ try {
1231
+ const model = await resolveModel(options.model);
1232
+ const { object } = await generateObject({
1233
+ model,
1234
+ schema: SingleChartResponseSchema,
1235
+ system: getCustomChartPrompt(data.headers, language),
1236
+ prompt: `Data summary:
1237
+ ${dataSummary}
1238
+
1239
+ User request: ${prompt}`,
1240
+ temperature
1241
+ });
1242
+ return mapChartResult(object.chart, `chart-custom-${Date.now()}`);
1243
+ } catch (error) {
1244
+ throw new Error(getAIErrorMessage(error));
1245
+ }
1246
+ }
1247
+ async function repairChart(options) {
1248
+ const {
1249
+ failedChart,
1250
+ columns,
1251
+ errorContext,
1252
+ language,
1253
+ temperature = 0.3
1254
+ } = options;
1255
+ try {
1256
+ const model = await resolveModel(options.model);
1257
+ const { object } = await generateObject({
1258
+ model,
1259
+ schema: SingleChartResponseSchema,
1260
+ system: getCustomChartPrompt(columns, language),
1261
+ prompt: `The following chart configuration failed to render:
1262
+ ${JSON.stringify(failedChart, null, 2)}
1263
+
1264
+ Error context: ${errorContext}
1265
+
1266
+ Please fix the configuration to use valid columns and aggregation. Available columns: ${columns.join(", ")}`,
1267
+ temperature
1268
+ });
1269
+ return mapChartResult(object.chart, failedChart.id);
1270
+ } catch (error) {
1271
+ throw new Error(getAIErrorMessage(error));
1272
+ }
1273
+ }
1243
1274
 
1244
1275
  // src/analyze.ts
1245
- init_ai();
1246
- init_ai();
1247
1276
  import { generateObject as generateObject2, generateText, streamText } from "ai";
1248
1277
  import { z as z2 } from "zod";
1249
1278
  var DataSummarySchema = z2.object({
@@ -1295,18 +1324,11 @@ function buildSampleCSV(data, maxRows = 50) {
1295
1324
  return `${header}
1296
1325
  ${rows}`;
1297
1326
  }
1298
- async function resolve(input) {
1299
- const { createModel: createModel2 } = await Promise.resolve().then(() => (init_ai(), ai_exports));
1300
- if (typeof input === "object" && "doGenerate" in input && typeof input.doGenerate === "function") {
1301
- return input;
1302
- }
1303
- return createModel2(input);
1304
- }
1305
1327
  async function summarizeData(options) {
1306
1328
  const { data, language, temperature = 0.5 } = options;
1307
1329
  const dataSummary = options.dataSummary ?? summarizeTabularData(data);
1308
1330
  try {
1309
- const model = await resolve(options.model);
1331
+ const model = await resolveModel(options.model);
1310
1332
  const { object } = await generateObject2({
1311
1333
  model,
1312
1334
  schema: DataSummarySchema,
@@ -1330,7 +1352,7 @@ async function detectAnomalies(options) {
1330
1352
  const dataSummary = options.dataSummary ?? summarizeTabularData(data);
1331
1353
  const sampleCSV = buildSampleCSV(data, maxRows);
1332
1354
  try {
1333
- const model = await resolve(options.model);
1355
+ const model = await resolveModel(options.model);
1334
1356
  const { object } = await generateObject2({
1335
1357
  model,
1336
1358
  schema: AnomaliesResponseSchema,
@@ -1351,7 +1373,7 @@ async function askAboutData(options) {
1351
1373
  const { data, question, history = [], language, temperature = 0.5 } = options;
1352
1374
  const dataSummary = options.dataSummary ?? summarizeTabularData(data);
1353
1375
  try {
1354
- const model = await resolve(options.model);
1376
+ const model = await resolveModel(options.model);
1355
1377
  const historyText = history.map((item) => `User: ${item.prompt}
1356
1378
  AI: ${item.response}`).join("\n\n");
1357
1379
  const contextPrompt = historyText ? `Previous conversation history:
@@ -1385,7 +1407,7 @@ async function streamAskAboutData(options) {
1385
1407
  } = options;
1386
1408
  const dataSummary = options.dataSummary ?? summarizeTabularData(data);
1387
1409
  try {
1388
- const model = await resolve(options.model);
1410
+ const model = await resolveModel(options.model);
1389
1411
  const historyText = history.map((item) => `User: ${item.prompt}
1390
1412
  AI: ${item.response}`).join("\n\n");
1391
1413
  const contextPrompt = historyText ? `Previous conversation history:
@@ -1444,6 +1466,7 @@ export {
1444
1466
  ChartToolbar,
1445
1467
  SingleChart,
1446
1468
  TabularDataSchema,
1469
+ VERSION,
1447
1470
  analyzeData,
1448
1471
  askAboutData,
1449
1472
  createModel,
@@ -1454,6 +1477,7 @@ export {
1454
1477
  processChartData,
1455
1478
  processChartDataMultiSeries,
1456
1479
  repairChart,
1480
+ resolveModel,
1457
1481
  streamAskAboutData,
1458
1482
  suggestCharts,
1459
1483
  suggestCustomChart,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ai.ts","../src/types.ts","../src/ThemeContext.tsx","../src/SingleChart.tsx","../src/processChartData.ts","../src/ChartToolbar.tsx","../src/ChartDisplay.tsx","../src/constants.ts","../src/index.ts","../src/analyze.ts"],"sourcesContent":["import { generateObject, type LanguageModel } from \"ai\";\nimport { z } from \"zod\";\nimport type { ChartConfig, TabularData } from \"./types\";\n\n// ============ Input Validation Schemas ============\n\n/** Zod schema for simple API config (OpenAI-compatible endpoints) */\nexport const AIConfigSchema = z.object({\n /** API key for authentication */\n apiKey: z.string(),\n /** Model identifier (e.g. \"gpt-4o\", \"llama3\", \"mistral-large\") */\n model: z.string(),\n /** Custom base URL for non-OpenAI providers (Ollama, vLLM, Mistral, etc.) */\n baseURL: z.string().optional(),\n /** Provider hint — used to dynamically load the right SDK. Defaults to \"openai\". */\n provider: z\n .enum([\"openai\", \"anthropic\", \"google\", \"mistral\"])\n .optional()\n .default(\"openai\"),\n});\n\nexport type AIConfig = z.infer<typeof AIConfigSchema>;\n\n/** Zod schema for TabularData validation */\nexport const TabularDataSchema = z.object({\n headers: z.array(z.string()).min(1, \"Data must have at least one column\"),\n rows: z.array(z.array(z.string())),\n columns: z.array(\n z.object({\n name: z.string(),\n type: z.enum([\"string\", \"number\", \"date\", \"boolean\"]),\n index: z.number(),\n }),\n ),\n rowCount: z.number(),\n});\n\n/** Model input: either a simple config object or a pre-built LanguageModel */\nexport type ModelInput = AIConfig | LanguageModel;\n\n// ============ Chart Output Schemas ============\n\nconst ChartSuggestionSchema = z.object({\n type: z.enum([\"bar\", \"line\", \"pie\", \"scatter\", \"area\"]),\n title: z.string(),\n description: z.string(),\n xColumn: z\n .string()\n .describe(\"The EXACT column name to use for X axis (categories/labels)\"),\n yColumn: z\n .string()\n .describe(\"The EXACT column name to use for Y axis (values)\"),\n groupColumn: z\n .string()\n .optional()\n .describe(\"Optional column to group/segment the data\"),\n aggregation: z\n .enum([\"sum\", \"avg\", \"count\", \"min\", \"max\", \"none\"])\n .describe(\"How to aggregate Y values when there are duplicates in X\"),\n reasoning: z\n .string()\n .describe(\"Brief explanation of why this chart is useful for this data\"),\n});\n\nconst ChartSuggestionsResponseSchema = z.object({\n charts: z.array(ChartSuggestionSchema),\n});\n\nconst SingleChartResponseSchema = z.object({\n chart: ChartSuggestionSchema,\n});\n\n// ============ Error Handling ============\n\n/**\n * Extracts a user-friendly error message from AI provider errors.\n * Exported so consumers can use it in their own error handling.\n */\nexport function getAIErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n if (message.includes(\"rate limit\") || message.includes(\"429\")) {\n return \"Rate limit exceeded. Please wait a moment and try again.\";\n }\n if (\n message.includes(\"unauthorized\") ||\n message.includes(\"401\") ||\n message.includes(\"invalid api key\") ||\n message.includes(\"invalid_api_key\")\n ) {\n return \"Invalid API key. Please check your API key configuration.\";\n }\n if (\n message.includes(\"quota\") ||\n message.includes(\"insufficient_quota\") ||\n message.includes(\"billing\")\n ) {\n return \"API quota exceeded or billing issue. Please check your account status.\";\n }\n if (\n message.includes(\"network\") ||\n message.includes(\"timeout\") ||\n message.includes(\"econnrefused\") ||\n message.includes(\"fetch failed\")\n ) {\n return \"Network error. Please check your internet connection and try again.\";\n }\n if (\n message.includes(\"model\") &&\n (message.includes(\"not found\") || message.includes(\"does not exist\"))\n ) {\n return \"Model not available. Please select a different model.\";\n }\n\n return error.message;\n }\n\n return \"An unexpected error occurred. Please try again.\";\n}\n\n// ============ Data Summary Generation ============\n\n/**\n * Generate a text summary of tabular data for AI consumption.\n * If the consumer doesn't provide a `dataSummary`, this is used automatically.\n */\nexport function summarizeTabularData(data: TabularData): string {\n const lines: string[] = [];\n lines.push(`Dataset: ${data.rowCount} rows, ${data.headers.length} columns`);\n lines.push(`Columns: ${data.headers.join(\", \")}`);\n lines.push(\"\");\n\n for (const col of data.columns) {\n const idx = col.index;\n const values = data.rows.map((r) => r[idx] ?? \"\").filter((v) => v !== \"\");\n\n if (col.type === \"number\") {\n const nums = values.map(Number).filter((n) => !isNaN(n));\n if (nums.length > 0) {\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const avg = nums.reduce((a, b) => a + b, 0) / nums.length;\n lines.push(\n `- ${col.name} (${col.type}): min=${min}, max=${max}, avg=${avg.toFixed(2)}, ${nums.length} values`,\n );\n } else {\n lines.push(`- ${col.name} (${col.type}): no valid numeric values`);\n }\n } else {\n const distinct = new Set(values).size;\n const sample = values.slice(0, 5).join(\", \");\n lines.push(\n `- ${col.name} (${col.type}): ${distinct} distinct values, sample: [${sample}]`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n// ============ Model Resolution ============\n\nfunction isLanguageModel(input: unknown): input is LanguageModel {\n return (\n typeof input === \"object\" &&\n input !== null &&\n \"doGenerate\" in input &&\n typeof (input as Record<string, unknown>).doGenerate === \"function\"\n );\n}\n\n/**\n * Create a LanguageModel from an AIConfig.\n * Exported so consumers can create a model once and reuse it.\n *\n * @example\n * ```ts\n * const model = await createModel({ apiKey: \"sk-...\", model: \"gpt-4o\" });\n * const charts1 = await suggestCharts({ model, data, dataSummary });\n * const charts2 = await suggestCustomChart({ model, data, dataSummary, prompt: \"...\" });\n * ```\n */\nexport async function createModel(config: AIConfig): Promise<LanguageModel> {\n const parsed = AIConfigSchema.parse(config);\n\n if (parsed.baseURL || parsed.provider === \"openai\") {\n const { createOpenAI } = await import(\"@ai-sdk/openai\");\n const openai = createOpenAI({\n apiKey: parsed.apiKey,\n ...(parsed.baseURL && { baseURL: parsed.baseURL }),\n }) as unknown as (model: string) => LanguageModel;\n return openai(parsed.model);\n }\n\n switch (parsed.provider) {\n case \"anthropic\": {\n try {\n const { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n return createAnthropic({ apiKey: parsed.apiKey })(parsed.model);\n } catch {\n throw new Error(\n 'Provider \"anthropic\" requires @ai-sdk/anthropic. Install it: pnpm add @ai-sdk/anthropic',\n );\n }\n }\n case \"google\": {\n try {\n const { createGoogleGenerativeAI } = await import(\"@ai-sdk/google\");\n return createGoogleGenerativeAI({ apiKey: parsed.apiKey })(\n parsed.model,\n );\n } catch {\n throw new Error(\n 'Provider \"google\" requires @ai-sdk/google. Install it: pnpm add @ai-sdk/google',\n );\n }\n }\n case \"mistral\": {\n try {\n const { createMistral } = await import(\"@ai-sdk/mistral\");\n return createMistral({ apiKey: parsed.apiKey })(parsed.model);\n } catch {\n throw new Error(\n 'Provider \"mistral\" requires @ai-sdk/mistral. Install it: pnpm add @ai-sdk/mistral',\n );\n }\n }\n default: {\n const { createOpenAI } = await import(\"@ai-sdk/openai\");\n const openai = createOpenAI({\n apiKey: parsed.apiKey,\n }) as unknown as (model: string) => LanguageModel;\n return openai(parsed.model);\n }\n }\n}\n\nasync function resolveModel(input: ModelInput): Promise<LanguageModel> {\n if (isLanguageModel(input)) return input;\n return createModel(input as AIConfig);\n}\n\n// ============ Prompts ============\n\nconst getChartSystemPrompt = (\n columns: string[],\n language?: string,\n) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : \"\"}\n\nYou will analyze CSV data and suggest the best charts to visualize it.\n\nAVAILABLE COLUMNS (use these EXACT names):\n${columns.map((c) => `- \"${c}\"`).join(\"\\n\")}\n\nCRITICAL RULES:\n1. xColumn and yColumn MUST be exact column names from the list above\n2. For numeric analysis, yColumn should be a numeric column\n3. For categorical comparisons, xColumn should be a categorical column\n4. Only suggest charts that make sense for the data types\n5. Use aggregation when there are multiple rows per category:\n - \"sum\" for totals (sales, revenue)\n - \"avg\" for averages (ratings, scores)\n - \"count\" for frequencies\n - \"none\" for unique values or time series\n6. Suggest 2-4 charts maximum, focusing on the most insightful ones\n\nCHART TYPE GUIDELINES:\n- bar: Compare categories (xColumn=category, yColumn=numeric)\n- line: Show trends over time (xColumn=date/time, yColumn=numeric)\n- pie: Show proportions (xColumn=category, yColumn=numeric with sum/count)\n- scatter: Show correlations (xColumn=numeric, yColumn=numeric, aggregation=none)\n- area: Show cumulative trends (xColumn=date/time, yColumn=numeric)`;\n\nconst getCustomChartPrompt = (\n columns: string[],\n language?: string,\n) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : \"\"}\n\nCreate a chart configuration based on the user's request.\n\nAVAILABLE COLUMNS (use these EXACT names):\n${columns.map((c) => `- \"${c}\"`).join(\"\\n\")}\n\nIMPORTANT: Column names MUST exactly match the list above.`;\n\n// ============ Helpers ============\n\nfunction mapChartResult(\n raw: z.infer<typeof ChartSuggestionSchema>,\n id: string,\n): ChartConfig {\n return {\n id,\n type: raw.type,\n title: raw.title,\n description: raw.description,\n xAxis: raw.xColumn,\n yAxis: raw.yColumn,\n groupBy: raw.groupColumn,\n aggregation: raw.aggregation,\n dataConfig: {\n xColumn: raw.xColumn,\n yColumn: raw.yColumn,\n groupColumn: raw.groupColumn,\n },\n };\n}\n\n// ============ Options ============\n\nexport interface SuggestChartsOptions {\n /** The AI model — either a simple config or a LanguageModel instance */\n model: ModelInput;\n /** The tabular data to analyze */\n data: TabularData;\n /** A text summary of the data. If omitted, auto-generated from `data`. */\n dataSummary?: string;\n /** Language for AI responses (e.g. \"English\", \"French\") */\n language?: string;\n /** Temperature for AI generation (default: 0.5) */\n temperature?: number;\n}\n\nexport interface SuggestCustomChartOptions {\n /** The AI model — either a simple config or a LanguageModel instance */\n model: ModelInput;\n /** The tabular data */\n data: TabularData;\n /** A text summary of the data. If omitted, auto-generated from `data`. */\n dataSummary?: string;\n /** The user's chart request (e.g. \"show sales by month\") */\n prompt: string;\n /** Language for AI responses */\n language?: string;\n /** Temperature (default: 0.5) */\n temperature?: number;\n}\n\nexport interface RepairChartOptions {\n /** The AI model — either a simple config or a LanguageModel instance */\n model: ModelInput;\n /** The chart configuration that failed */\n failedChart: ChartConfig;\n /** Available column names */\n columns: string[];\n /** Description of why the chart failed */\n errorContext: string;\n /** Language for AI responses */\n language?: string;\n /** Temperature (default: 0.3) */\n temperature?: number;\n}\n\n// ============ Public API ============\n\n/**\n * Generate chart suggestions from tabular data using AI.\n *\n * @example\n * ```ts\n * import { suggestCharts } from \"csv-charts-ai\";\n *\n * // Minimal — auto-generates dataSummary from the data\n * const charts = await suggestCharts({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * });\n *\n * // Custom endpoint — Ollama\n * const charts = await suggestCharts({\n * model: { apiKey: \"\", model: \"llama3\", baseURL: \"http://localhost:11434/v1\" },\n * data: myData,\n * });\n *\n * // Advanced — any LanguageModel from the ai SDK\n * import { anthropic } from \"@ai-sdk/anthropic\";\n * const charts = await suggestCharts({\n * model: anthropic(\"claude-sonnet-4-20250514\"),\n * data: myData,\n * language: \"French\",\n * });\n * ```\n */\nexport async function suggestCharts(\n options: SuggestChartsOptions,\n): Promise<ChartConfig[]> {\n const { data, language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n TabularDataSchema.parse(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: ChartSuggestionsResponseSchema,\n system: getChartSystemPrompt(data.headers, language),\n prompt: `Analyze this CSV data and suggest the best charts:\\n\\n${dataSummary}`,\n temperature,\n });\n\n return object.charts.map((s, i) =>\n mapChartResult(s, `chart-${i}-${Date.now()}`),\n );\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\n/**\n * Generate a single chart from a user's text prompt.\n *\n * @example\n * ```ts\n * const chart = await suggestCustomChart({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * prompt: \"Show me a bar chart of sales by category\",\n * });\n * ```\n */\nexport async function suggestCustomChart(\n options: SuggestCustomChartOptions,\n): Promise<ChartConfig | null> {\n const { data, prompt, language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n TabularDataSchema.parse(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: SingleChartResponseSchema,\n system: getCustomChartPrompt(data.headers, language),\n prompt: `Data summary:\\n${dataSummary}\\n\\nUser request: ${prompt}`,\n temperature,\n });\n\n return mapChartResult(object.chart, `chart-custom-${Date.now()}`);\n } catch (error) {\n console.error(\"Custom chart generation failed:\", getAIErrorMessage(error));\n return null;\n }\n}\n\n/**\n * Repair a chart configuration that failed to render.\n *\n * @example\n * ```ts\n * const fixed = await repairChart({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * failedChart: brokenChart,\n * columns: [\"name\", \"sales\", \"date\"],\n * errorContext: \"Column 'revenue' does not exist\",\n * });\n * ```\n */\nexport async function repairChart(\n options: RepairChartOptions,\n): Promise<ChartConfig | null> {\n const {\n failedChart,\n columns,\n errorContext,\n language,\n temperature = 0.3,\n } = options;\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: SingleChartResponseSchema,\n system: getCustomChartPrompt(columns, language),\n prompt: `The following chart configuration failed to render:\\n${JSON.stringify(failedChart, null, 2)}\\n\\nError context: ${errorContext}\\n\\nPlease fix the configuration to use valid columns and aggregation. Available columns: ${columns.join(\", \")}`,\n temperature,\n });\n\n return mapChartResult(object.chart, failedChart.id);\n } catch {\n return null;\n }\n}\n","export type ChartType = \"bar\" | \"line\" | \"pie\" | \"scatter\" | \"area\";\nexport type AggregationType =\n | \"sum\"\n | \"avg\"\n | \"count\"\n | \"min\"\n | \"max\"\n | \"none\";\n\nexport interface TabularData {\n headers: string[];\n rows: string[][];\n columns: {\n name: string;\n type: \"string\" | \"number\" | \"date\" | \"boolean\";\n index: number;\n }[];\n rowCount: number;\n}\n\nexport interface ChartConfig {\n id: string;\n type: ChartType;\n title: string;\n description: string;\n xAxis: string;\n yAxis: string;\n groupBy?: string;\n aggregation: AggregationType;\n dataConfig?: {\n xColumn: string;\n yColumn: string;\n groupColumn?: string;\n };\n}\n\nexport type SortOrder = \"none\" | \"asc\" | \"desc\";\nexport type ChartDataPoint = Record<string, string | number>;\n\n// Theme types\nexport interface ChartTheme {\n colors: string[];\n background: string;\n cardBackground: string;\n border: string;\n text: string;\n textMuted: string;\n textDimmed: string;\n gridStroke: string;\n tooltipBackground: string;\n tooltipBorder: string;\n accentPrimary: string;\n accentSecondary: string;\n accentSuccess: string;\n accentDanger: string;\n}\n\nexport const defaultDarkTheme: ChartTheme = {\n colors: [\n \"#8b5cf6\",\n \"#06b6d4\",\n \"#f43f5e\",\n \"#eab308\",\n \"#10b981\",\n \"#3b82f6\",\n \"#d946ef\",\n \"#f97316\",\n ],\n background: \"rgba(15, 23, 42, 0.5)\",\n cardBackground: \"rgba(255, 255, 255, 0.05)\",\n border: \"rgba(255, 255, 255, 0.1)\",\n text: \"#ffffff\",\n textMuted: \"#9ca3af\",\n textDimmed: \"#6b7280\",\n gridStroke: \"#374151\",\n tooltipBackground: \"#1f2937\",\n tooltipBorder: \"1px solid #374151\",\n accentPrimary: \"#8b5cf6\",\n accentSecondary: \"#06b6d4\",\n accentSuccess: \"#10b981\",\n accentDanger: \"#ef4444\",\n};\n\nexport const defaultLightTheme: ChartTheme = {\n colors: [\n \"#7c3aed\",\n \"#0891b2\",\n \"#e11d48\",\n \"#ca8a04\",\n \"#059669\",\n \"#2563eb\",\n \"#c026d3\",\n \"#ea580c\",\n ],\n background: \"#ffffff\",\n cardBackground: \"#f8fafc\",\n border: \"#e2e8f0\",\n text: \"#0f172a\",\n textMuted: \"#64748b\",\n textDimmed: \"#94a3b8\",\n gridStroke: \"#e2e8f0\",\n tooltipBackground: \"#ffffff\",\n tooltipBorder: \"1px solid #e2e8f0\",\n accentPrimary: \"#7c3aed\",\n accentSecondary: \"#0891b2\",\n accentSuccess: \"#059669\",\n accentDanger: \"#dc2626\",\n};\n","import { createContext, useContext } from \"react\";\nimport { type ChartTheme, defaultDarkTheme } from \"./types\";\n\nconst ChartThemeContext = createContext<ChartTheme>(defaultDarkTheme);\n\nexport function ChartThemeProvider({\n theme,\n children,\n}: {\n theme: ChartTheme;\n children: React.ReactNode;\n}) {\n return (\n <ChartThemeContext.Provider value={theme}>\n {children}\n </ChartThemeContext.Provider>\n );\n}\n\nexport function useChartTheme(): ChartTheme {\n return useContext(ChartThemeContext);\n}\n","import { useState, useMemo, useCallback, useRef } from \"react\";\nimport {\n BarChart,\n Bar,\n LineChart,\n Line,\n PieChart,\n Pie,\n ScatterChart,\n Scatter,\n AreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ResponsiveContainer,\n Cell,\n Brush,\n ReferenceLine,\n} from \"recharts\";\nimport { RefreshCw } from \"lucide-react\";\nimport type {\n TabularData,\n ChartConfig,\n ChartType,\n SortOrder,\n ChartDataPoint,\n} from \"./types\";\nimport { useChartTheme } from \"./ThemeContext\";\nimport { processChartDataMultiSeries } from \"./processChartData\";\nimport { ChartToolbar } from \"./ChartToolbar\";\n\nexport interface SingleChartProps {\n data: TabularData;\n chart: ChartConfig;\n onRegenerate?: (chart: ChartConfig) => Promise<void>;\n}\n\nexport function SingleChart({ data, chart, onRegenerate }: SingleChartProps) {\n const theme = useChartTheme();\n const chartContainerRef = useRef<HTMLDivElement>(null);\n const [isRegenerating, setIsRegenerating] = useState(false);\n const [sortOrder, setSortOrder] = useState<SortOrder>(\"none\");\n const [showBrush, setShowBrush] = useState(false);\n const [showTrendline, setShowTrendline] = useState(false);\n const [limitResults, setLimitResults] = useState<number>(20);\n\n const processed = useMemo(\n () => processChartDataMultiSeries(data, chart, sortOrder, limitResults),\n [data, chart, sortOrder, limitResults],\n );\n\n const { data: processedData, seriesKeys } = processed;\n const isMultiSeries = seriesKeys.length > 0;\n\n // Find actual column names from data\n const xColName =\n data.columns.find(\n (col) =>\n col.name === chart.xAxis ||\n col.name.toLowerCase() === chart.xAxis.toLowerCase(),\n )?.name ?? chart.xAxis;\n\n const yColName =\n data.columns.find(\n (col) =>\n col.name === chart.yAxis ||\n col.name.toLowerCase() === chart.yAxis.toLowerCase(),\n )?.name ?? chart.yAxis;\n\n // Calculate average for trend line\n const average = useMemo(() => {\n if (processedData.length === 0 || isMultiSeries) return 0;\n const sum = processedData.reduce((acc, item) => {\n const val = item[yColName];\n return acc + (typeof val === \"number\" ? val : 0);\n }, 0);\n return sum / processedData.length;\n }, [processedData, yColName, isMultiSeries]);\n\n const handleRegenerate = async () => {\n if (!onRegenerate) return;\n setIsRegenerating(true);\n try {\n await onRegenerate(chart);\n } finally {\n setIsRegenerating(false);\n }\n };\n\n const handleExportCSV = useCallback(() => {\n if (processedData.length === 0) return;\n\n const headers = Object.keys(processedData[0] ?? {}).join(\",\");\n const rows = processedData\n .map((row) =>\n Object.values(row)\n .map((v) => `\"${String(v)}\"`)\n .join(\",\"),\n )\n .join(\"\\n\");\n\n const csv = `${headers}\\n${rows}`;\n const blob = new Blob([csv], { type: \"text/csv\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${chart.title.replace(/\\s+/g, \"_\")}.csv`;\n a.click();\n URL.revokeObjectURL(url);\n }, [processedData, chart.title]);\n\n const handleExportPNG = useCallback(() => {\n const container = chartContainerRef.current;\n if (!container) return;\n\n const svgElement = container.querySelector(\"svg\");\n if (!svgElement) return;\n\n const svgClone = svgElement.cloneNode(true) as SVGSVGElement;\n svgClone.setAttribute(\n \"xmlns\",\n \"http://www.w3.org/2000/svg\",\n );\n // Ensure dimensions\n const rect = svgElement.getBoundingClientRect();\n svgClone.setAttribute(\"width\", String(rect.width));\n svgClone.setAttribute(\"height\", String(rect.height));\n\n const svgString = new XMLSerializer().serializeToString(svgClone);\n const svgBlob = new Blob([svgString], {\n type: \"image/svg+xml;charset=utf-8\",\n });\n const url = URL.createObjectURL(svgBlob);\n\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n const scale = 2; // retina\n canvas.width = rect.width * scale;\n canvas.height = rect.height * scale;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.scale(scale, scale);\n ctx.fillStyle = theme.tooltipBackground;\n ctx.fillRect(0, 0, rect.width, rect.height);\n ctx.drawImage(img, 0, 0, rect.width, rect.height);\n\n canvas.toBlob((blob) => {\n if (!blob) return;\n const pngUrl = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = pngUrl;\n a.download = `${chart.title.replace(/\\s+/g, \"_\")}.png`;\n a.click();\n URL.revokeObjectURL(pngUrl);\n }, \"image/png\");\n\n URL.revokeObjectURL(url);\n };\n img.src = url;\n }, [chart.title, theme.tooltipBackground]);\n\n const toggleSort = () => {\n setSortOrder((prev) => {\n if (prev === \"none\") return \"desc\";\n if (prev === \"desc\") return \"asc\";\n return \"none\";\n });\n };\n\n // Render chart content helper\n const renderChartContent = (\n type: ChartType,\n chartData: ChartDataPoint[],\n xKey: string,\n yKey: string,\n enableBrush?: boolean,\n enableTrendline?: boolean,\n avgValue?: number,\n ) => {\n const commonProps = {\n data: chartData,\n margin: { top: 20, right: 30, left: 20, bottom: 50 },\n };\n\n const tooltipStyle = {\n backgroundColor: theme.tooltipBackground,\n border: theme.tooltipBorder,\n borderRadius: \"8px\",\n };\n\n const brushComponent = enableBrush ? (\n <Brush\n dataKey={xKey}\n height={30}\n stroke={theme.accentPrimary}\n fill=\"#1e1b4b\"\n />\n ) : null;\n\n const trendlineComponent =\n enableTrendline && avgValue && !isMultiSeries ? (\n <ReferenceLine\n y={avgValue}\n stroke={theme.accentSuccess}\n strokeDasharray=\"5 5\"\n label={{\n value: `Avg: ${avgValue.toFixed(2)}`,\n fill: theme.accentSuccess,\n fontSize: 12,\n }}\n />\n ) : null;\n\n const xAxisProps = {\n dataKey: xKey,\n stroke: theme.textMuted,\n fontSize: 11,\n angle: -45,\n textAnchor: \"end\" as const,\n height: 80,\n interval: 0 as const,\n tick: { fill: theme.textMuted },\n };\n\n const yAxisProps = {\n stroke: theme.textMuted,\n fontSize: 12,\n tick: { fill: theme.textMuted },\n };\n\n // Multi-series rendering\n if (isMultiSeries && type !== \"pie\" && type !== \"scatter\") {\n switch (type) {\n case \"bar\":\n return (\n <BarChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {seriesKeys.map((key, i) => (\n <Bar\n key={key}\n dataKey={key}\n fill={theme.colors[i % theme.colors.length]}\n stackId=\"stack\"\n radius={\n i === seriesKeys.length - 1 ? [4, 4, 0, 0] : undefined\n }\n />\n ))}\n {brushComponent}\n </BarChart>\n );\n case \"line\":\n return (\n <LineChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {seriesKeys.map((key, i) => (\n <Line\n key={key}\n type=\"monotone\"\n dataKey={key}\n stroke={theme.colors[i % theme.colors.length]}\n strokeWidth={2}\n dot={{ fill: theme.colors[i % theme.colors.length] }}\n />\n ))}\n {brushComponent}\n </LineChart>\n );\n case \"area\":\n return (\n <AreaChart {...commonProps}>\n <defs>\n {seriesKeys.map((key, i) => (\n <linearGradient\n key={key}\n id={`grad-${chart.id}-${i}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop\n offset=\"5%\"\n stopColor={theme.colors[i % theme.colors.length]}\n stopOpacity={0.6}\n />\n <stop\n offset=\"95%\"\n stopColor={theme.colors[i % theme.colors.length]}\n stopOpacity={0}\n />\n </linearGradient>\n ))}\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {seriesKeys.map((key, i) => (\n <Area\n key={key}\n type=\"monotone\"\n dataKey={key}\n stroke={theme.colors[i % theme.colors.length]}\n fillOpacity={1}\n fill={`url(#grad-${chart.id}-${i})`}\n stackId=\"stack\"\n />\n ))}\n {brushComponent}\n </AreaChart>\n );\n default:\n return null;\n }\n }\n\n // Single-series rendering\n switch (type) {\n case \"bar\":\n return (\n <BarChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {trendlineComponent}\n <Bar dataKey={yKey} fill={theme.accentPrimary} radius={[4, 4, 0, 0]}>\n {chartData.map((_, index) => (\n <Cell\n key={`cell-${index}`}\n fill={theme.colors[index % theme.colors.length]}\n />\n ))}\n </Bar>\n {brushComponent}\n </BarChart>\n );\n\n case \"line\":\n return (\n <LineChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {trendlineComponent}\n <Line\n type=\"monotone\"\n dataKey={yKey}\n stroke={theme.accentPrimary}\n strokeWidth={3}\n dot={{ fill: theme.accentPrimary }}\n activeDot={{ r: 8 }}\n />\n {brushComponent}\n </LineChart>\n );\n\n case \"area\": {\n const gradientId = `colorY-${chart.id}`;\n return (\n <AreaChart {...commonProps}>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop\n offset=\"5%\"\n stopColor={theme.accentPrimary}\n stopOpacity={0.8}\n />\n <stop\n offset=\"95%\"\n stopColor={theme.accentPrimary}\n stopOpacity={0}\n />\n </linearGradient>\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {trendlineComponent}\n <Area\n type=\"monotone\"\n dataKey={yKey}\n stroke={theme.accentPrimary}\n fillOpacity={1}\n fill={`url(#${gradientId})`}\n />\n {brushComponent}\n </AreaChart>\n );\n }\n\n case \"scatter\":\n return (\n <ScatterChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis\n type=\"category\"\n {...xAxisProps}\n />\n <YAxis\n type=\"number\"\n dataKey={yKey}\n {...yAxisProps}\n />\n <Tooltip\n cursor={{ strokeDasharray: \"3 3\" }}\n contentStyle={tooltipStyle}\n />\n <Legend />\n <Scatter name={yKey} data={chartData} fill={theme.accentPrimary} />\n </ScatterChart>\n );\n\n case \"pie\":\n return (\n <PieChart>\n <Pie\n data={chartData}\n innerRadius={60}\n outerRadius={100}\n paddingAngle={5}\n dataKey={yKey}\n nameKey={xKey}\n label={({ name, percent }) =>\n `${name}: ${((percent ?? 0) * 100).toFixed(0)}%`\n }\n labelLine={{ stroke: theme.textMuted }}\n >\n {chartData.map((_, index) => (\n <Cell\n key={`cell-${index}`}\n fill={theme.colors[index % theme.colors.length]}\n />\n ))}\n </Pie>\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n </PieChart>\n );\n\n default:\n return null;\n }\n };\n\n if (processedData.length === 0) {\n return (\n <div className=\"flex h-[300px] flex-col items-center justify-center gap-4 text-gray-400\">\n <div className=\"text-center\">\n <p className=\"mb-1 font-medium text-red-400\">\n Unable to generate this chart\n </p>\n <p className=\"mb-4 text-sm text-gray-500\">\n Columns: {chart.xAxis}, {chart.yAxis}\n </p>\n {onRegenerate && (\n <button\n onClick={handleRegenerate}\n disabled={isRegenerating}\n className=\"flex items-center gap-2 rounded-lg bg-violet-600 px-4 py-2 text-sm text-white transition-colors hover:bg-violet-500 disabled:opacity-50\"\n >\n <RefreshCw\n className={`h-4 w-4 ${isRegenerating ? \"animate-spin\" : \"\"}`}\n />\n {isRegenerating ? \"Regenerating...\" : \"Regenerate with AI\"}\n </button>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <ChartToolbar\n chartType={chart.type}\n sortOrder={sortOrder}\n limitResults={limitResults}\n showBrush={showBrush}\n showTrendline={showTrendline}\n isRegenerating={isRegenerating}\n hasRegenerate={!!onRegenerate}\n onToggleSort={toggleSort}\n onLimitChange={setLimitResults}\n onToggleBrush={() => setShowBrush(!showBrush)}\n onToggleTrendline={() => setShowTrendline(!showTrendline)}\n onExportCSV={handleExportCSV}\n onExportPNG={handleExportPNG}\n onRegenerate={handleRegenerate}\n />\n\n {/* Chart */}\n <div className=\"h-[450px] w-full\" ref={chartContainerRef}>\n <ResponsiveContainer\n key={`chart-${chart.id}-${showBrush ? \"brush\" : \"no-brush\"}`}\n width=\"100%\"\n height=\"100%\"\n >\n {renderChartContent(\n chart.type,\n processedData,\n xColName,\n isMultiSeries ? \"\" : yColName,\n showBrush,\n showTrendline,\n average,\n )}\n </ResponsiveContainer>\n </div>\n\n {/* Metadata Tags */}\n <div className=\"mt-4 flex flex-wrap gap-2\">\n <span className=\"rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400\">\n X: {chart.xAxis}\n </span>\n <span className=\"rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400\">\n Y: {chart.yAxis}\n </span>\n {chart.groupBy && (\n <span className=\"rounded bg-cyan-500/20 px-2 py-0.5 text-xs text-cyan-300\">\n Group: {chart.groupBy}\n </span>\n )}\n {chart.aggregation && chart.aggregation !== \"none\" && (\n <span className=\"rounded bg-violet-500/20 px-2 py-0.5 text-xs text-violet-300\">\n {chart.aggregation}\n </span>\n )}\n <span className=\"rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400\">\n {processedData.length} items\n </span>\n {isMultiSeries && (\n <span className=\"rounded bg-emerald-500/20 px-2 py-0.5 text-xs text-emerald-300\">\n {seriesKeys.length} series\n </span>\n )}\n </div>\n </div>\n );\n}\n","import type {\n TabularData,\n ChartConfig,\n SortOrder,\n ChartDataPoint,\n} from \"./types\";\n\nexport interface ProcessedChartResult {\n data: ChartDataPoint[];\n seriesKeys: string[];\n yKey: string;\n}\n\nexport const processChartData = (\n data: TabularData,\n chart: ChartConfig,\n sortOrder: SortOrder = \"none\",\n limit = 20,\n): ChartDataPoint[] => {\n const result = processChartDataMultiSeries(data, chart, sortOrder, limit);\n return result.data;\n};\n\nexport const processChartDataMultiSeries = (\n data: TabularData,\n chart: ChartConfig,\n sortOrder: SortOrder = \"none\",\n limit = 20,\n): ProcessedChartResult => {\n let result: ChartDataPoint[] = [];\n\n // Find actual columns (case-insensitive match)\n const xColDef = data.columns.find(\n (c) => c.name.toLowerCase() === chart.xAxis.toLowerCase(),\n );\n const yColDef = data.columns.find(\n (c) => c.name.toLowerCase() === chart.yAxis.toLowerCase(),\n );\n const groupColDef = chart.groupBy\n ? data.columns.find(\n (c) => c.name.toLowerCase() === chart.groupBy!.toLowerCase(),\n )\n : undefined;\n\n if (!xColDef) return { data: [], seriesKeys: [], yKey: chart.yAxis };\n\n const xCol = xColDef.name;\n const xIdx = xColDef.index;\n\n // For count aggregation, we don't need a valid Y column - we just count occurrences\n const isCountMode = chart.aggregation === \"count\";\n const yCol = yColDef?.name ?? \"count\";\n const yIdx = yColDef?.index ?? -1;\n\n // GroupBy mode: create multi-series data (not supported for pie/scatter)\n const supportsGroupBy =\n chart.type !== \"pie\" && chart.type !== \"scatter\";\n if (\n supportsGroupBy &&\n groupColDef &&\n chart.aggregation &&\n chart.aggregation !== \"none\"\n ) {\n const groupIdx = groupColDef.index;\n const allGroups = new Set<string>();\n\n // Nested grouping: xVal -> groupVal -> stats\n const grouped = new Map<\n string,\n Map<string, { sum: number; count: number; min: number; max: number }>\n >();\n\n data.rows.forEach((row) => {\n const xVal = String(row[xIdx] ?? \"\").trim();\n const groupVal = String(row[groupIdx] ?? \"\").trim();\n if (!xVal || !groupVal) return;\n\n allGroups.add(groupVal);\n\n if (!grouped.has(xVal)) grouped.set(xVal, new Map());\n const xGroup = grouped.get(xVal)!;\n\n if (isCountMode) {\n const current = xGroup.get(groupVal) ?? {\n sum: 0,\n count: 0,\n min: 0,\n max: 0,\n };\n xGroup.set(groupVal, { ...current, count: current.count + 1 });\n } else if (yIdx >= 0) {\n const yVal = parseFloat(String(row[yIdx] ?? \"0\"));\n if (!isNaN(yVal)) {\n const current = xGroup.get(groupVal) ?? {\n sum: 0,\n count: 0,\n min: Infinity,\n max: -Infinity,\n };\n xGroup.set(groupVal, {\n sum: current.sum + yVal,\n count: current.count + 1,\n min: Math.min(current.min, yVal),\n max: Math.max(current.max, yVal),\n });\n }\n }\n });\n\n const seriesKeys = Array.from(allGroups).slice(0, 8); // max 8 series\n\n grouped.forEach((groupMap, xKey) => {\n const point: ChartDataPoint = { [xCol]: xKey };\n seriesKeys.forEach((groupKey) => {\n const stats = groupMap.get(groupKey);\n if (stats) {\n let value: number;\n switch (chart.aggregation) {\n case \"sum\":\n value = stats.sum;\n break;\n case \"avg\":\n value = stats.count > 0 ? stats.sum / stats.count : 0;\n break;\n case \"count\":\n value = stats.count;\n break;\n case \"min\":\n value = stats.min === Infinity ? 0 : stats.min;\n break;\n case \"max\":\n value = stats.max === -Infinity ? 0 : stats.max;\n break;\n default:\n value = stats.sum;\n }\n point[groupKey] = Math.round(value * 100) / 100;\n } else {\n point[groupKey] = 0;\n }\n });\n result.push(point);\n });\n\n // Sort by first series value or alphabetically\n if (sortOrder !== \"none\" && seriesKeys[0]) {\n const firstKey = seriesKeys[0];\n result.sort((a, b) => {\n const aVal = (a[firstKey] as number) ?? 0;\n const bVal = (b[firstKey] as number) ?? 0;\n return sortOrder === \"desc\" ? bVal - aVal : aVal - bVal;\n });\n }\n\n return {\n data: result.slice(0, limit),\n seriesKeys,\n yKey: yCol,\n };\n }\n\n // Standard single-series mode (existing logic)\n if (chart.aggregation && chart.aggregation !== \"none\") {\n const groups = new Map<\n string,\n { sum: number; count: number; min: number; max: number }\n >();\n\n data.rows.forEach((row) => {\n const xVal = String(row[xIdx] ?? \"\").trim();\n if (!xVal) return;\n\n if (isCountMode) {\n const current = groups.get(xVal) ?? {\n sum: 0,\n count: 0,\n min: 0,\n max: 0,\n };\n groups.set(xVal, {\n ...current,\n count: current.count + 1,\n });\n } else if (yIdx >= 0) {\n const yVal = parseFloat(String(row[yIdx] ?? \"0\"));\n if (!isNaN(yVal)) {\n const current = groups.get(xVal) ?? {\n sum: 0,\n count: 0,\n min: Infinity,\n max: -Infinity,\n };\n groups.set(xVal, {\n sum: current.sum + yVal,\n count: current.count + 1,\n min: Math.min(current.min, yVal),\n max: Math.max(current.max, yVal),\n });\n }\n }\n });\n\n groups.forEach((stats, key) => {\n let value: number;\n switch (chart.aggregation) {\n case \"sum\":\n value = stats.sum;\n break;\n case \"avg\":\n value = stats.count > 0 ? stats.sum / stats.count : 0;\n break;\n case \"count\":\n value = stats.count;\n break;\n case \"min\":\n value = stats.min === Infinity ? 0 : stats.min;\n break;\n case \"max\":\n value = stats.max === -Infinity ? 0 : stats.max;\n break;\n default:\n value = stats.sum;\n }\n result.push({ [xCol]: key, [yCol]: Math.round(value * 100) / 100 });\n });\n } else if (yIdx >= 0) {\n result = data.rows\n .slice(0, Math.min(limit * 2, data.rows.length))\n .map((row) => ({\n [xCol]: row[xIdx] ?? \"\",\n [yCol]: parseFloat(String(row[yIdx] ?? \"0\")),\n }))\n .filter((item) => !isNaN(item[yCol] as number));\n }\n\n // Apply sorting\n if (sortOrder !== \"none\") {\n result.sort((a, b) => {\n const aVal = a[yCol] as number;\n const bVal = b[yCol] as number;\n return sortOrder === \"desc\" ? bVal - aVal : aVal - bVal;\n });\n }\n\n return {\n data: result.slice(0, limit),\n seriesKeys: [],\n yKey: yCol,\n };\n};\n","import {\n RefreshCw,\n Download,\n SortAsc,\n SortDesc,\n RotateCcw,\n TrendingUp,\n Filter,\n Image,\n} from \"lucide-react\";\nimport type { ChartType, SortOrder } from \"./types\";\n\ninterface ChartToolbarProps {\n chartType: ChartType;\n sortOrder: SortOrder;\n limitResults: number;\n showBrush: boolean;\n showTrendline: boolean;\n isRegenerating: boolean;\n hasRegenerate: boolean;\n onToggleSort: () => void;\n onLimitChange: (limit: number) => void;\n onToggleBrush: () => void;\n onToggleTrendline: () => void;\n onExportCSV: () => void;\n onExportPNG: () => void;\n onRegenerate: () => void;\n}\n\nexport function ChartToolbar({\n chartType,\n sortOrder,\n limitResults,\n showBrush,\n showTrendline,\n isRegenerating,\n hasRegenerate,\n onToggleSort,\n onLimitChange,\n onToggleBrush,\n onToggleTrendline,\n onExportCSV,\n onExportPNG,\n onRegenerate,\n}: ChartToolbarProps) {\n const supportsBrush =\n chartType === \"line\" || chartType === \"area\" || chartType === \"bar\";\n const supportsTrendline =\n chartType === \"bar\" || chartType === \"line\" || chartType === \"area\";\n\n return (\n <div className=\"mb-4 flex flex-wrap items-center gap-2 rounded-xl border border-white/10 bg-white/5 p-3\">\n {/* Sort Control */}\n <button\n onClick={onToggleSort}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${\n sortOrder !== \"none\"\n ? \"border border-violet-500/30 bg-violet-500/20 text-violet-400\"\n : \"bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white\"\n }`}\n title=\"Sort by value\"\n >\n {sortOrder === \"asc\" ? (\n <SortAsc className=\"h-4 w-4\" />\n ) : sortOrder === \"desc\" ? (\n <SortDesc className=\"h-4 w-4\" />\n ) : (\n <SortDesc className=\"h-4 w-4 opacity-50\" />\n )}\n Sort\n </button>\n\n {/* Limit Results */}\n <div className=\"flex items-center gap-2\">\n <Filter className=\"h-4 w-4 text-gray-400\" />\n <select\n value={limitResults}\n onChange={(e) => onLimitChange(Number(e.target.value))}\n className=\"rounded-lg border border-white/10 bg-white/5 px-2 py-1.5 text-sm text-gray-300 focus:border-violet-500/50 focus:outline-none\"\n >\n <option value={10}>Top 10</option>\n <option value={20}>Top 20</option>\n <option value={50}>Top 50</option>\n <option value={100}>Top 100</option>\n <option value={999999}>All</option>\n </select>\n </div>\n\n {/* Brush/Zoom Toggle */}\n {supportsBrush && (\n <button\n onClick={onToggleBrush}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${\n showBrush\n ? \"border border-cyan-500/30 bg-cyan-500/20 text-cyan-400\"\n : \"bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white\"\n }`}\n title=\"Enable zoom/brush\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Zoom\n </button>\n )}\n\n {/* Trend Line Toggle */}\n {supportsTrendline && (\n <button\n onClick={onToggleTrendline}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${\n showTrendline\n ? \"border border-emerald-500/30 bg-emerald-500/20 text-emerald-400\"\n : \"bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white\"\n }`}\n title=\"Show average line\"\n >\n <TrendingUp className=\"h-4 w-4\" />\n Average\n </button>\n )}\n\n <div className=\"flex-1\" />\n\n {/* Export PNG Button */}\n <button\n onClick={onExportPNG}\n className=\"flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white\"\n title=\"Export chart as PNG image\"\n >\n <Image className=\"h-4 w-4\" />\n PNG\n </button>\n\n {/* Export CSV Button */}\n <button\n onClick={onExportCSV}\n className=\"flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white\"\n title=\"Export chart data as CSV\"\n >\n <Download className=\"h-4 w-4\" />\n CSV\n </button>\n\n {/* Regenerate Button */}\n {hasRegenerate && (\n <button\n onClick={onRegenerate}\n disabled={isRegenerating}\n className=\"flex items-center gap-1.5 rounded-lg bg-violet-500/20 px-3 py-1.5 text-sm text-violet-400 transition-colors hover:bg-violet-500/30 disabled:opacity-50\"\n >\n <RefreshCw\n className={`h-4 w-4 ${isRegenerating ? \"animate-spin\" : \"\"}`}\n />\n {isRegenerating ? \"...\" : \"Regenerate\"}\n </button>\n )}\n </div>\n );\n}\n","import type { TabularData, ChartConfig, ChartTheme } from \"./types\";\nimport { defaultDarkTheme } from \"./types\";\nimport { ChartThemeProvider } from \"./ThemeContext\";\nimport { SingleChart } from \"./SingleChart\";\n\nexport interface ChartDisplayProps {\n data: TabularData;\n charts: ChartConfig[];\n onRegenerate?: (chart: ChartConfig) => Promise<void>;\n /** Optional wrapper component for each chart card */\n cardWrapper?: React.ComponentType<{\n children: React.ReactNode;\n title?: string;\n className?: string;\n }>;\n /** Optional theme override */\n theme?: ChartTheme;\n}\n\nfunction DefaultCard({\n children,\n className = \"\",\n}: {\n children: React.ReactNode;\n title?: string;\n className?: string;\n}) {\n return <div className={className}>{children}</div>;\n}\n\nexport function ChartDisplay({\n data,\n charts,\n onRegenerate,\n cardWrapper: CardWrapper = DefaultCard,\n theme = defaultDarkTheme,\n}: ChartDisplayProps) {\n if (charts.length === 0) return null;\n\n return (\n <ChartThemeProvider theme={theme}>\n <div className=\"animate-fade-in space-y-6\">\n {charts.map((chart) => (\n <CardWrapper\n key={chart.id}\n title={chart.title}\n className=\"overflow-hidden rounded-2xl border border-white/10 bg-slate-900/50\"\n >\n <div className=\"p-6\">\n <h3 className=\"mb-2 bg-linear-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-xl font-bold text-transparent\">\n {chart.title}\n </h3>\n <p className=\"mb-4 text-gray-400\">{chart.description}</p>\n <SingleChart\n data={data}\n chart={chart}\n onRegenerate={onRegenerate}\n />\n </div>\n </CardWrapper>\n ))}\n </div>\n </ChartThemeProvider>\n );\n}\n","// Re-export from defaultDarkTheme for backwards compatibility\nexport { defaultDarkTheme as COLORS_THEME } from \"./types\";\n\nexport const COLORS = [\n \"#8b5cf6\", // Violet 500\n \"#06b6d4\", // Cyan 500\n \"#f43f5e\", // Rose 500\n \"#eab308\", // Yellow 500\n \"#10b981\", // Emerald 500\n \"#3b82f6\", // Blue 500\n \"#d946ef\", // Fuchsia 500\n \"#f97316\", // Orange 500\n];\n","// React components\nexport { ChartDisplay } from \"./ChartDisplay\";\nexport type { ChartDisplayProps } from \"./ChartDisplay\";\nexport { SingleChart } from \"./SingleChart\";\nexport type { SingleChartProps } from \"./SingleChart\";\nexport { ChartToolbar } from \"./ChartToolbar\";\nexport { ChartThemeProvider, useChartTheme } from \"./ThemeContext\";\n\n// Data processing\nexport { processChartData, processChartDataMultiSeries } from \"./processChartData\";\nexport type { ProcessedChartResult } from \"./processChartData\";\nexport { COLORS } from \"./constants\";\n\n// Types & themes\nexport type {\n ChartConfig,\n TabularData,\n ChartType,\n AggregationType,\n SortOrder,\n ChartDataPoint,\n ChartTheme,\n} from \"./types\";\nexport { defaultDarkTheme, defaultLightTheme } from \"./types\";\n\n// AI — chart generation\nexport { suggestCharts, suggestCustomChart, repairChart } from \"./ai\";\nexport { createModel, summarizeTabularData, getAIErrorMessage } from \"./ai\";\nexport { AIConfigSchema, TabularDataSchema } from \"./ai\";\nexport type {\n AIConfig,\n ModelInput,\n SuggestChartsOptions,\n SuggestCustomChartOptions,\n RepairChartOptions,\n} from \"./ai\";\n\n// AI — data analysis\nexport {\n summarizeData,\n detectAnomalies,\n askAboutData,\n streamAskAboutData,\n analyzeData,\n} from \"./analyze\";\nexport type {\n DataSummaryResult,\n AnomalyResult,\n AnalysisResult,\n SummarizeDataOptions,\n DetectAnomaliesOptions,\n AskAboutDataOptions,\n StreamAskAboutDataOptions,\n AnalyzeOptions,\n} from \"./analyze\";\n","import { generateObject, generateText, streamText } from \"ai\";\nimport { z } from \"zod\";\nimport type { TabularData, ChartConfig } from \"./types\";\nimport type { ModelInput } from \"./ai\";\nimport { summarizeTabularData, getAIErrorMessage } from \"./ai\";\nimport { suggestCharts } from \"./ai\";\n\n// ============ Schemas ============\n\nconst DataSummarySchema = z.object({\n summary: z.string(),\n keyInsights: z.array(z.string()),\n dataQuality: z.string(),\n});\n\nconst AnomalySchema = z.object({\n row: z.number(),\n column: z.string(),\n value: z.string(),\n issue: z.string(),\n severity: z.enum([\"low\", \"medium\", \"high\"]),\n});\n\nconst AnomaliesResponseSchema = z.object({\n anomalies: z.array(AnomalySchema),\n});\n\n// ============ Result Types ============\n\nexport interface DataSummaryResult {\n summary: string;\n keyInsights: string[];\n dataQuality: string;\n}\n\nexport interface AnomalyResult {\n row: number;\n column: string;\n value: string;\n issue: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface AnalysisResult {\n summary: DataSummaryResult;\n anomalies: AnomalyResult[];\n charts: ChartConfig[];\n}\n\n// ============ Prompts ============\n\nconst summarySystemPrompt = (\n language?: string,\n) => `You are a data analyst.${language ? ` Respond in ${language}.` : \"\"}\n\nAnalyze the provided CSV data summary and provide:\n1. A comprehensive summary of what this dataset represents (2-3 sentences)\n2. 3-5 key insights or patterns you notice\n3. An assessment of data quality (completeness, consistency)`;\n\nconst anomalySystemPrompt = (\n language?: string,\n) => `You are a data quality expert.${language ? ` Respond in ${language}.` : \"\"}\n\nAnalyze the provided CSV data and identify anomalies, outliers, or suspicious data points.\n\nFor each anomaly found, provide:\n1. Row number (1-indexed, excluding header)\n2. Column name\n3. The problematic value\n4. Description of the issue\n5. Severity (low, medium, high)\n\nLook for:\n- Missing or empty values where data is expected\n- Values that don't match the expected type\n- Outliers (extremely high or low values)\n- Inconsistent formatting\n- Invalid dates or formats\n\nAnalyze ALL rows provided. Return empty array if no anomalies found.`;\n\nconst questionSystemPrompt = (\n language?: string,\n) =>\n `You are a data analysis expert.${language ? ` Respond in ${language}.` : \"\"}\\n\\nThe user will ask questions about a CSV dataset. Respond clearly and precisely.`;\n\n// ============ Helper ============\n\nfunction buildSampleCSV(data: TabularData, maxRows = 50): string {\n const header = data.headers.join(\",\");\n const rows = data.rows\n .slice(0, maxRows)\n .map((row) => row.join(\",\"))\n .join(\"\\n\");\n return `${header}\\n${rows}`;\n}\n\n// We need resolveModel but it's not exported from ai.ts\n// Use a lazy approach: accept ModelInput and resolve internally\nasync function resolve(input: ModelInput) {\n // Dynamic import to avoid circular dependency\n const { createModel } = await import(\"./ai\");\n if (typeof input === \"object\" && \"doGenerate\" in input && typeof (input as Record<string, unknown>).doGenerate === \"function\") {\n return input;\n }\n return createModel(input as import(\"./ai\").AIConfig);\n}\n\n// ============ Individual Functions ============\n\nexport interface SummarizeDataOptions {\n model: ModelInput;\n data: TabularData;\n dataSummary?: string;\n language?: string;\n temperature?: number;\n}\n\n/**\n * Generate an AI summary of tabular data.\n *\n * @example\n * ```ts\n * const result = await summarizeData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * });\n * console.log(result.summary);\n * console.log(result.keyInsights);\n * console.log(result.dataQuality);\n * ```\n */\nexport async function summarizeData(\n options: SummarizeDataOptions,\n): Promise<DataSummaryResult> {\n const { data, language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n try {\n const model = await resolve(options.model);\n\n const { object } = await generateObject({\n model,\n schema: DataSummarySchema,\n system: summarySystemPrompt(language),\n prompt: `Here is the data to analyze:\\n\\n${dataSummary}`,\n temperature,\n });\n\n return {\n summary: object.summary,\n keyInsights: object.keyInsights,\n dataQuality: object.dataQuality,\n };\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\nexport interface DetectAnomaliesOptions {\n model: ModelInput;\n data: TabularData;\n dataSummary?: string;\n /** Max rows to send for analysis (default: 50) */\n maxRows?: number;\n language?: string;\n temperature?: number;\n}\n\n/**\n * Detect anomalies in tabular data using AI.\n *\n * @example\n * ```ts\n * const anomalies = await detectAnomalies({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * });\n * anomalies.forEach(a => console.log(`Row ${a.row}: ${a.issue}`));\n * ```\n */\nexport async function detectAnomalies(\n options: DetectAnomaliesOptions,\n): Promise<AnomalyResult[]> {\n const { data, maxRows = 50, language, temperature = 0.3 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n const sampleCSV = buildSampleCSV(data, maxRows);\n\n try {\n const model = await resolve(options.model);\n\n const { object } = await generateObject({\n model,\n schema: AnomaliesResponseSchema,\n system: anomalySystemPrompt(language),\n prompt: `Data summary:\\n${dataSummary}\\n\\nData to analyze (CSV format):\\n${sampleCSV}`,\n temperature,\n });\n\n return object.anomalies;\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\nexport interface AskAboutDataOptions {\n model: ModelInput;\n data: TabularData;\n question: string;\n dataSummary?: string;\n /** Previous conversation messages for context */\n history?: Array<{ prompt: string; response: string }>;\n language?: string;\n temperature?: number;\n}\n\n/**\n * Ask a question about the data and get a text response.\n *\n * @example\n * ```ts\n * const answer = await askAboutData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * question: \"What is the average revenue by category?\",\n * });\n * console.log(answer);\n * ```\n */\nexport async function askAboutData(\n options: AskAboutDataOptions,\n): Promise<string> {\n const { data, question, history = [], language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n try {\n const model = await resolve(options.model);\n\n const historyText = history\n .map((item) => `User: ${item.prompt}\\nAI: ${item.response}`)\n .join(\"\\n\\n\");\n const contextPrompt = historyText\n ? `Previous conversation history:\\n${historyText}\\n\\n`\n : \"\";\n\n const { text } = await generateText({\n model,\n system: questionSystemPrompt(language),\n prompt: `Here is the data:\\n\\n${dataSummary}\\n\\n${contextPrompt}User question: ${question}`,\n temperature,\n });\n\n return text;\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\nexport interface StreamAskAboutDataOptions extends AskAboutDataOptions {\n onChunk: (chunk: string) => void;\n onComplete: (fullText: string) => void;\n}\n\n/**\n * Ask a question with streaming response.\n *\n * @example\n * ```ts\n * await streamAskAboutData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * question: \"What trends do you see?\",\n * onChunk: (chunk) => process.stdout.write(chunk),\n * onComplete: (full) => console.log(\"\\nDone:\", full.length, \"chars\"),\n * });\n * ```\n */\nexport async function streamAskAboutData(\n options: StreamAskAboutDataOptions,\n): Promise<void> {\n const {\n data,\n question,\n history = [],\n language,\n temperature = 0.5,\n onChunk,\n onComplete,\n } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n try {\n const model = await resolve(options.model);\n\n const historyText = history\n .map((item) => `User: ${item.prompt}\\nAI: ${item.response}`)\n .join(\"\\n\\n\");\n const contextPrompt = historyText\n ? `Previous conversation history:\\n${historyText}\\n\\n`\n : \"\";\n\n let streamError: Error | null = null;\n\n const result = streamText({\n model,\n system: questionSystemPrompt(language),\n prompt: `Here is the data:\\n\\n${dataSummary}\\n\\n${contextPrompt}User question: ${question}`,\n temperature,\n onError: ({ error }) => {\n streamError =\n error instanceof Error ? error : new Error(String(error));\n },\n });\n\n let fullText = \"\";\n\n for await (const textPart of result.textStream) {\n fullText += textPart;\n onChunk(textPart);\n }\n\n if (streamError) throw streamError;\n\n const finishReason = await result.finishReason;\n if (finishReason === \"error\") {\n throw new Error(\"The AI model encountered an error while generating the response.\");\n }\n\n onComplete(fullText);\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\n// ============ Full Pipeline ============\n\nexport interface AnalyzeOptions {\n model: ModelInput;\n data: TabularData;\n dataSummary?: string;\n language?: string;\n /** Set to false to skip anomaly detection (default: true) */\n detectAnomalies?: boolean;\n /** Set to false to skip chart suggestions (default: true) */\n suggestCharts?: boolean;\n}\n\n/**\n * Run a complete AI analysis on tabular data in one call.\n * Returns summary, anomalies, and chart suggestions.\n *\n * @example\n * ```ts\n * import { analyzeData, ChartDisplay } from \"csv-charts-ai\";\n *\n * const result = await analyzeData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myCSVData,\n * });\n *\n * console.log(result.summary.keyInsights);\n * console.log(`Found ${result.anomalies.length} anomalies`);\n *\n * // Render charts\n * <ChartDisplay data={myCSVData} charts={result.charts} />\n * ```\n */\nexport async function analyzeData(\n options: AnalyzeOptions,\n): Promise<AnalysisResult> {\n const {\n data,\n language,\n detectAnomalies: runAnomalies = true,\n suggestCharts: runCharts = true,\n } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n // Run all in parallel\n const [summary, anomalies, charts] = await Promise.all([\n summarizeData({ model: options.model, data, dataSummary, language }),\n runAnomalies\n ? detectAnomalies({ model: options.model, data, dataSummary, language })\n : Promise.resolve([]),\n runCharts\n ? suggestCharts({ model: options.model, data, dataSummary, language })\n : Promise.resolve([]),\n ]);\n\n return { summary, anomalies, charts };\n}\n"],"mappings":"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","names":["RefreshCw","Image","jsx","jsx","jsxs","RefreshCw","jsx","jsxs","generateObject","z","createModel"]}
1
+ {"version":3,"sources":["../package.json","../src/version.ts","../src/types.ts","../src/ThemeContext.tsx","../src/SingleChart.tsx","../src/processChartData.ts","../src/ChartToolbar.tsx","../src/ChartDisplay.tsx","../src/constants.ts","../src/ai.ts","../src/analyze.ts"],"sourcesContent":["{\n \"name\": \"csv-charts-ai\",\n \"version\": \"1.3.1\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/maxgfr/csv-ai-analyzer\",\n \"directory\": \"packages/csv-charts-ai\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\"\n },\n \"peerDependencies\": {\n \"ai\": \"^5.0.0 || ^6.0.0\",\n \"lucide-react\": \">=0.400.0\",\n \"react\": \"^18.0.0 || ^19.0.0\",\n \"recharts\": \"^3.0.0\",\n \"zod\": \"^4.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"recharts\": {\n \"optional\": true\n },\n \"lucide-react\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@types/react\": \"^19.2.7\",\n \"ai\": \"^6.0.134\",\n \"lucide-react\": \"^0.556.0\",\n \"react\": \"^19.2.4\",\n \"recharts\": \"^3.5.1\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"zod\": \"^4.1.13\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"dependencies\": {\n \"@ai-sdk/openai\": \"^3.0.47\"\n }\n}\n","// Read version from package.json at build time (inlined by tsup)\nimport pkg from \"../package.json\" with { type: \"json\" };\nexport const VERSION: string = pkg.version;\n","export type ChartType = \"bar\" | \"line\" | \"pie\" | \"scatter\" | \"area\";\nexport type AggregationType =\n | \"sum\"\n | \"avg\"\n | \"count\"\n | \"min\"\n | \"max\"\n | \"none\";\n\nexport interface TabularData {\n headers: string[];\n rows: string[][];\n columns: {\n name: string;\n type: \"string\" | \"number\" | \"date\" | \"boolean\";\n index: number;\n }[];\n rowCount: number;\n}\n\nexport interface ChartConfig {\n id: string;\n type: ChartType;\n title: string;\n description: string;\n xAxis: string;\n yAxis: string;\n groupBy?: string;\n aggregation: AggregationType;\n dataConfig?: {\n xColumn: string;\n yColumn: string;\n groupColumn?: string;\n };\n}\n\nexport type SortOrder = \"none\" | \"asc\" | \"desc\";\nexport type ChartDataPoint = Record<string, string | number>;\n\n// Theme types\nexport interface ChartTheme {\n colors: string[];\n background: string;\n cardBackground: string;\n border: string;\n text: string;\n textMuted: string;\n textDimmed: string;\n gridStroke: string;\n tooltipBackground: string;\n tooltipBorder: string;\n accentPrimary: string;\n accentSecondary: string;\n accentSuccess: string;\n accentDanger: string;\n}\n\nexport const defaultDarkTheme: ChartTheme = {\n colors: [\n \"#8b5cf6\",\n \"#06b6d4\",\n \"#f43f5e\",\n \"#eab308\",\n \"#10b981\",\n \"#3b82f6\",\n \"#d946ef\",\n \"#f97316\",\n ],\n background: \"rgba(15, 23, 42, 0.5)\",\n cardBackground: \"rgba(255, 255, 255, 0.05)\",\n border: \"rgba(255, 255, 255, 0.1)\",\n text: \"#ffffff\",\n textMuted: \"#9ca3af\",\n textDimmed: \"#6b7280\",\n gridStroke: \"#374151\",\n tooltipBackground: \"#1f2937\",\n tooltipBorder: \"1px solid #374151\",\n accentPrimary: \"#8b5cf6\",\n accentSecondary: \"#06b6d4\",\n accentSuccess: \"#10b981\",\n accentDanger: \"#ef4444\",\n};\n\nexport const defaultLightTheme: ChartTheme = {\n colors: [\n \"#7c3aed\",\n \"#0891b2\",\n \"#e11d48\",\n \"#ca8a04\",\n \"#059669\",\n \"#2563eb\",\n \"#c026d3\",\n \"#ea580c\",\n ],\n background: \"#ffffff\",\n cardBackground: \"#f8fafc\",\n border: \"#e2e8f0\",\n text: \"#0f172a\",\n textMuted: \"#64748b\",\n textDimmed: \"#94a3b8\",\n gridStroke: \"#e2e8f0\",\n tooltipBackground: \"#ffffff\",\n tooltipBorder: \"1px solid #e2e8f0\",\n accentPrimary: \"#7c3aed\",\n accentSecondary: \"#0891b2\",\n accentSuccess: \"#059669\",\n accentDanger: \"#dc2626\",\n};\n","import { createContext, useContext } from \"react\";\nimport { type ChartTheme, defaultDarkTheme } from \"./types\";\n\nconst ChartThemeContext = createContext<ChartTheme>(defaultDarkTheme);\n\nexport function ChartThemeProvider({\n theme,\n children,\n}: {\n theme: ChartTheme;\n children: React.ReactNode;\n}) {\n return (\n <ChartThemeContext.Provider value={theme}>\n {children}\n </ChartThemeContext.Provider>\n );\n}\n\nexport function useChartTheme(): ChartTheme {\n return useContext(ChartThemeContext);\n}\n","import { useState, useMemo, useCallback, useRef } from \"react\";\nimport {\n BarChart,\n Bar,\n LineChart,\n Line,\n PieChart,\n Pie,\n ScatterChart,\n Scatter,\n AreaChart,\n Area,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ResponsiveContainer,\n Cell,\n Brush,\n ReferenceLine,\n} from \"recharts\";\nimport { RefreshCw } from \"lucide-react\";\nimport type {\n TabularData,\n ChartConfig,\n ChartType,\n SortOrder,\n ChartDataPoint,\n} from \"./types\";\nimport { useChartTheme } from \"./ThemeContext\";\nimport { processChartDataMultiSeries } from \"./processChartData\";\nimport { ChartToolbar } from \"./ChartToolbar\";\n\nexport interface SingleChartProps {\n data: TabularData;\n chart: ChartConfig;\n onRegenerate?: (chart: ChartConfig) => Promise<void>;\n}\n\nexport function SingleChart({ data, chart, onRegenerate }: SingleChartProps) {\n const theme = useChartTheme();\n const chartContainerRef = useRef<HTMLDivElement>(null);\n const [isRegenerating, setIsRegenerating] = useState(false);\n const [sortOrder, setSortOrder] = useState<SortOrder>(\"none\");\n const [showBrush, setShowBrush] = useState(false);\n const [showTrendline, setShowTrendline] = useState(false);\n const [limitResults, setLimitResults] = useState<number>(20);\n\n const processed = useMemo(\n () => processChartDataMultiSeries(data, chart, sortOrder, limitResults),\n [data, chart, sortOrder, limitResults],\n );\n\n const { data: processedData, seriesKeys } = processed;\n const isMultiSeries = seriesKeys.length > 0;\n\n // Find actual column names from data\n const xColName =\n data.columns.find(\n (col) =>\n col.name === chart.xAxis ||\n col.name.toLowerCase() === chart.xAxis.toLowerCase(),\n )?.name ?? chart.xAxis;\n\n const yColName =\n data.columns.find(\n (col) =>\n col.name === chart.yAxis ||\n col.name.toLowerCase() === chart.yAxis.toLowerCase(),\n )?.name ?? chart.yAxis;\n\n // Calculate average for trend line\n const average = useMemo(() => {\n if (processedData.length === 0 || isMultiSeries) return 0;\n const sum = processedData.reduce((acc, item) => {\n const val = item[yColName];\n return acc + (typeof val === \"number\" ? val : 0);\n }, 0);\n return sum / processedData.length;\n }, [processedData, yColName, isMultiSeries]);\n\n const handleRegenerate = async () => {\n if (!onRegenerate) return;\n setIsRegenerating(true);\n try {\n await onRegenerate(chart);\n } finally {\n setIsRegenerating(false);\n }\n };\n\n const handleExportCSV = useCallback(() => {\n if (processedData.length === 0) return;\n\n const headers = Object.keys(processedData[0] ?? {}).join(\",\");\n const rows = processedData\n .map((row) =>\n Object.values(row)\n .map((v) => `\"${String(v)}\"`)\n .join(\",\"),\n )\n .join(\"\\n\");\n\n const csv = `${headers}\\n${rows}`;\n const blob = new Blob([csv], { type: \"text/csv\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = `${chart.title.replace(/\\s+/g, \"_\")}.csv`;\n a.click();\n URL.revokeObjectURL(url);\n }, [processedData, chart.title]);\n\n const handleExportPNG = useCallback(() => {\n const container = chartContainerRef.current;\n if (!container) return;\n\n const svgElement = container.querySelector(\"svg\");\n if (!svgElement) return;\n\n const svgClone = svgElement.cloneNode(true) as SVGSVGElement;\n svgClone.setAttribute(\n \"xmlns\",\n \"http://www.w3.org/2000/svg\",\n );\n // Ensure dimensions\n const rect = svgElement.getBoundingClientRect();\n svgClone.setAttribute(\"width\", String(rect.width));\n svgClone.setAttribute(\"height\", String(rect.height));\n\n const svgString = new XMLSerializer().serializeToString(svgClone);\n const svgBlob = new Blob([svgString], {\n type: \"image/svg+xml;charset=utf-8\",\n });\n const url = URL.createObjectURL(svgBlob);\n\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n const scale = 2; // retina\n canvas.width = rect.width * scale;\n canvas.height = rect.height * scale;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n ctx.scale(scale, scale);\n ctx.fillStyle = theme.tooltipBackground;\n ctx.fillRect(0, 0, rect.width, rect.height);\n ctx.drawImage(img, 0, 0, rect.width, rect.height);\n\n canvas.toBlob((blob) => {\n if (!blob) return;\n const pngUrl = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = pngUrl;\n a.download = `${chart.title.replace(/\\s+/g, \"_\")}.png`;\n a.click();\n URL.revokeObjectURL(pngUrl);\n }, \"image/png\");\n\n URL.revokeObjectURL(url);\n };\n img.src = url;\n }, [chart.title, theme.tooltipBackground]);\n\n const toggleSort = () => {\n setSortOrder((prev) => {\n if (prev === \"none\") return \"desc\";\n if (prev === \"desc\") return \"asc\";\n return \"none\";\n });\n };\n\n // Render chart content helper\n const renderChartContent = (\n type: ChartType,\n chartData: ChartDataPoint[],\n xKey: string,\n yKey: string,\n enableBrush?: boolean,\n enableTrendline?: boolean,\n avgValue?: number,\n ) => {\n const commonProps = {\n data: chartData,\n margin: { top: 20, right: 30, left: 20, bottom: 50 },\n };\n\n const tooltipStyle = {\n backgroundColor: theme.tooltipBackground,\n border: theme.tooltipBorder,\n borderRadius: \"8px\",\n };\n\n const brushComponent = enableBrush ? (\n <Brush\n dataKey={xKey}\n height={30}\n stroke={theme.accentPrimary}\n fill=\"#1e1b4b\"\n />\n ) : null;\n\n const trendlineComponent =\n enableTrendline && avgValue && !isMultiSeries ? (\n <ReferenceLine\n y={avgValue}\n stroke={theme.accentSuccess}\n strokeDasharray=\"5 5\"\n label={{\n value: `Avg: ${avgValue.toFixed(2)}`,\n fill: theme.accentSuccess,\n fontSize: 12,\n }}\n />\n ) : null;\n\n const xAxisProps = {\n dataKey: xKey,\n stroke: theme.textMuted,\n fontSize: 11,\n angle: -45,\n textAnchor: \"end\" as const,\n height: 80,\n interval: 0 as const,\n tick: { fill: theme.textMuted },\n };\n\n const yAxisProps = {\n stroke: theme.textMuted,\n fontSize: 12,\n tick: { fill: theme.textMuted },\n };\n\n // Multi-series rendering\n if (isMultiSeries && type !== \"pie\" && type !== \"scatter\") {\n switch (type) {\n case \"bar\":\n return (\n <BarChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {seriesKeys.map((key, i) => (\n <Bar\n key={key}\n dataKey={key}\n fill={theme.colors[i % theme.colors.length]}\n stackId=\"stack\"\n radius={\n i === seriesKeys.length - 1 ? [4, 4, 0, 0] : undefined\n }\n />\n ))}\n {brushComponent}\n </BarChart>\n );\n case \"line\":\n return (\n <LineChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {seriesKeys.map((key, i) => (\n <Line\n key={key}\n type=\"monotone\"\n dataKey={key}\n stroke={theme.colors[i % theme.colors.length]}\n strokeWidth={2}\n dot={{ fill: theme.colors[i % theme.colors.length] }}\n />\n ))}\n {brushComponent}\n </LineChart>\n );\n case \"area\":\n return (\n <AreaChart {...commonProps}>\n <defs>\n {seriesKeys.map((key, i) => (\n <linearGradient\n key={key}\n id={`grad-${chart.id}-${i}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop\n offset=\"5%\"\n stopColor={theme.colors[i % theme.colors.length]}\n stopOpacity={0.6}\n />\n <stop\n offset=\"95%\"\n stopColor={theme.colors[i % theme.colors.length]}\n stopOpacity={0}\n />\n </linearGradient>\n ))}\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {seriesKeys.map((key, i) => (\n <Area\n key={key}\n type=\"monotone\"\n dataKey={key}\n stroke={theme.colors[i % theme.colors.length]}\n fillOpacity={1}\n fill={`url(#grad-${chart.id}-${i})`}\n stackId=\"stack\"\n />\n ))}\n {brushComponent}\n </AreaChart>\n );\n default:\n return null;\n }\n }\n\n // Single-series rendering\n switch (type) {\n case \"bar\":\n return (\n <BarChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {trendlineComponent}\n <Bar dataKey={yKey} fill={theme.accentPrimary} radius={[4, 4, 0, 0]}>\n {chartData.map((_, index) => (\n <Cell\n key={`cell-${index}`}\n fill={theme.colors[index % theme.colors.length]}\n />\n ))}\n </Bar>\n {brushComponent}\n </BarChart>\n );\n\n case \"line\":\n return (\n <LineChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {trendlineComponent}\n <Line\n type=\"monotone\"\n dataKey={yKey}\n stroke={theme.accentPrimary}\n strokeWidth={3}\n dot={{ fill: theme.accentPrimary }}\n activeDot={{ r: 8 }}\n />\n {brushComponent}\n </LineChart>\n );\n\n case \"area\": {\n const gradientId = `colorY-${chart.id}`;\n return (\n <AreaChart {...commonProps}>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop\n offset=\"5%\"\n stopColor={theme.accentPrimary}\n stopOpacity={0.8}\n />\n <stop\n offset=\"95%\"\n stopColor={theme.accentPrimary}\n stopOpacity={0}\n />\n </linearGradient>\n </defs>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis {...xAxisProps} />\n <YAxis {...yAxisProps} />\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n {trendlineComponent}\n <Area\n type=\"monotone\"\n dataKey={yKey}\n stroke={theme.accentPrimary}\n fillOpacity={1}\n fill={`url(#${gradientId})`}\n />\n {brushComponent}\n </AreaChart>\n );\n }\n\n case \"scatter\":\n return (\n <ScatterChart {...commonProps}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke={theme.gridStroke} />\n <XAxis\n type=\"category\"\n {...xAxisProps}\n />\n <YAxis\n type=\"number\"\n dataKey={yKey}\n {...yAxisProps}\n />\n <Tooltip\n cursor={{ strokeDasharray: \"3 3\" }}\n contentStyle={tooltipStyle}\n />\n <Legend />\n <Scatter name={yKey} data={chartData} fill={theme.accentPrimary} />\n </ScatterChart>\n );\n\n case \"pie\":\n return (\n <PieChart>\n <Pie\n data={chartData}\n innerRadius={60}\n outerRadius={100}\n paddingAngle={5}\n dataKey={yKey}\n nameKey={xKey}\n label={({ name, percent }) =>\n `${name}: ${((percent ?? 0) * 100).toFixed(0)}%`\n }\n labelLine={{ stroke: theme.textMuted }}\n >\n {chartData.map((_, index) => (\n <Cell\n key={`cell-${index}`}\n fill={theme.colors[index % theme.colors.length]}\n />\n ))}\n </Pie>\n <Tooltip contentStyle={tooltipStyle} />\n <Legend />\n </PieChart>\n );\n\n default:\n return null;\n }\n };\n\n if (processedData.length === 0) {\n return (\n <div className=\"flex h-[300px] flex-col items-center justify-center gap-4 text-gray-400\">\n <div className=\"text-center\">\n <p className=\"mb-1 font-medium text-red-400\">\n Unable to generate this chart\n </p>\n <p className=\"mb-4 text-sm text-gray-500\">\n Columns: {chart.xAxis}, {chart.yAxis}\n </p>\n {onRegenerate && (\n <button\n onClick={handleRegenerate}\n disabled={isRegenerating}\n className=\"flex items-center gap-2 rounded-lg bg-violet-600 px-4 py-2 text-sm text-white transition-colors hover:bg-violet-500 disabled:opacity-50\"\n >\n <RefreshCw\n className={`h-4 w-4 ${isRegenerating ? \"animate-spin\" : \"\"}`}\n />\n {isRegenerating ? \"Regenerating...\" : \"Regenerate with AI\"}\n </button>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <ChartToolbar\n chartType={chart.type}\n sortOrder={sortOrder}\n limitResults={limitResults}\n showBrush={showBrush}\n showTrendline={showTrendline}\n isRegenerating={isRegenerating}\n hasRegenerate={!!onRegenerate}\n onToggleSort={toggleSort}\n onLimitChange={setLimitResults}\n onToggleBrush={() => setShowBrush(!showBrush)}\n onToggleTrendline={() => setShowTrendline(!showTrendline)}\n onExportCSV={handleExportCSV}\n onExportPNG={handleExportPNG}\n onRegenerate={handleRegenerate}\n />\n\n {/* Chart */}\n <div className=\"h-[450px] w-full\" ref={chartContainerRef}>\n <ResponsiveContainer\n key={`chart-${chart.id}-${showBrush ? \"brush\" : \"no-brush\"}`}\n width=\"100%\"\n height=\"100%\"\n >\n {renderChartContent(\n chart.type,\n processedData,\n xColName,\n isMultiSeries ? \"\" : yColName,\n showBrush,\n showTrendline,\n average,\n )}\n </ResponsiveContainer>\n </div>\n\n {/* Metadata Tags */}\n <div className=\"mt-4 flex flex-wrap gap-2\">\n <span className=\"rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400\">\n X: {chart.xAxis}\n </span>\n <span className=\"rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400\">\n Y: {chart.yAxis}\n </span>\n {chart.groupBy && (\n <span className=\"rounded bg-cyan-500/20 px-2 py-0.5 text-xs text-cyan-300\">\n Group: {chart.groupBy}\n </span>\n )}\n {chart.aggregation && chart.aggregation !== \"none\" && (\n <span className=\"rounded bg-violet-500/20 px-2 py-0.5 text-xs text-violet-300\">\n {chart.aggregation}\n </span>\n )}\n <span className=\"rounded bg-white/10 px-2 py-0.5 text-xs text-gray-400\">\n {processedData.length} items\n </span>\n {isMultiSeries && (\n <span className=\"rounded bg-emerald-500/20 px-2 py-0.5 text-xs text-emerald-300\">\n {seriesKeys.length} series\n </span>\n )}\n </div>\n </div>\n );\n}\n","import type {\n TabularData,\n ChartConfig,\n SortOrder,\n ChartDataPoint,\n} from \"./types\";\n\nexport interface ProcessedChartResult {\n data: ChartDataPoint[];\n seriesKeys: string[];\n yKey: string;\n}\n\nexport const processChartData = (\n data: TabularData,\n chart: ChartConfig,\n sortOrder: SortOrder = \"none\",\n limit = 20,\n): ChartDataPoint[] => {\n const result = processChartDataMultiSeries(data, chart, sortOrder, limit);\n return result.data;\n};\n\nexport const processChartDataMultiSeries = (\n data: TabularData,\n chart: ChartConfig,\n sortOrder: SortOrder = \"none\",\n limit = 20,\n): ProcessedChartResult => {\n let result: ChartDataPoint[] = [];\n\n // Find actual columns (case-insensitive match)\n const xColDef = data.columns.find(\n (c) => c.name.toLowerCase() === chart.xAxis.toLowerCase(),\n );\n const yColDef = data.columns.find(\n (c) => c.name.toLowerCase() === chart.yAxis.toLowerCase(),\n );\n const groupColDef = chart.groupBy\n ? data.columns.find(\n (c) => c.name.toLowerCase() === chart.groupBy!.toLowerCase(),\n )\n : undefined;\n\n if (!xColDef) return { data: [], seriesKeys: [], yKey: chart.yAxis };\n\n const xCol = xColDef.name;\n const xIdx = xColDef.index;\n\n // For count aggregation, we don't need a valid Y column - we just count occurrences\n const isCountMode = chart.aggregation === \"count\";\n const yCol = yColDef?.name ?? \"count\";\n const yIdx = yColDef?.index ?? -1;\n\n // GroupBy mode: create multi-series data (not supported for pie/scatter)\n const supportsGroupBy =\n chart.type !== \"pie\" && chart.type !== \"scatter\";\n if (\n supportsGroupBy &&\n groupColDef &&\n chart.aggregation &&\n chart.aggregation !== \"none\"\n ) {\n const groupIdx = groupColDef.index;\n const allGroups = new Set<string>();\n\n // Nested grouping: xVal -> groupVal -> stats\n const grouped = new Map<\n string,\n Map<string, { sum: number; count: number; min: number; max: number }>\n >();\n\n data.rows.forEach((row) => {\n const xVal = String(row[xIdx] ?? \"\").trim();\n const groupVal = String(row[groupIdx] ?? \"\").trim();\n if (!xVal || !groupVal) return;\n\n allGroups.add(groupVal);\n\n if (!grouped.has(xVal)) grouped.set(xVal, new Map());\n const xGroup = grouped.get(xVal)!;\n\n if (isCountMode) {\n const current = xGroup.get(groupVal) ?? {\n sum: 0,\n count: 0,\n min: 0,\n max: 0,\n };\n xGroup.set(groupVal, { ...current, count: current.count + 1 });\n } else if (yIdx >= 0) {\n const yVal = parseFloat(String(row[yIdx] ?? \"0\"));\n if (!isNaN(yVal)) {\n const current = xGroup.get(groupVal) ?? {\n sum: 0,\n count: 0,\n min: Infinity,\n max: -Infinity,\n };\n xGroup.set(groupVal, {\n sum: current.sum + yVal,\n count: current.count + 1,\n min: Math.min(current.min, yVal),\n max: Math.max(current.max, yVal),\n });\n }\n }\n });\n\n const seriesKeys = Array.from(allGroups).slice(0, 8); // max 8 series\n\n grouped.forEach((groupMap, xKey) => {\n const point: ChartDataPoint = { [xCol]: xKey };\n seriesKeys.forEach((groupKey) => {\n const stats = groupMap.get(groupKey);\n if (stats) {\n let value: number;\n switch (chart.aggregation) {\n case \"sum\":\n value = stats.sum;\n break;\n case \"avg\":\n value = stats.count > 0 ? stats.sum / stats.count : 0;\n break;\n case \"count\":\n value = stats.count;\n break;\n case \"min\":\n value = stats.min === Infinity ? 0 : stats.min;\n break;\n case \"max\":\n value = stats.max === -Infinity ? 0 : stats.max;\n break;\n default:\n value = stats.sum;\n }\n point[groupKey] = Math.round(value * 100) / 100;\n } else {\n point[groupKey] = 0;\n }\n });\n result.push(point);\n });\n\n // Sort by first series value or alphabetically\n if (sortOrder !== \"none\" && seriesKeys[0]) {\n const firstKey = seriesKeys[0];\n result.sort((a, b) => {\n const aVal = (a[firstKey] as number) ?? 0;\n const bVal = (b[firstKey] as number) ?? 0;\n return sortOrder === \"desc\" ? bVal - aVal : aVal - bVal;\n });\n }\n\n return {\n data: result.slice(0, limit),\n seriesKeys,\n yKey: yCol,\n };\n }\n\n // Standard single-series mode (existing logic)\n if (chart.aggregation && chart.aggregation !== \"none\") {\n const groups = new Map<\n string,\n { sum: number; count: number; min: number; max: number }\n >();\n\n data.rows.forEach((row) => {\n const xVal = String(row[xIdx] ?? \"\").trim();\n if (!xVal) return;\n\n if (isCountMode) {\n const current = groups.get(xVal) ?? {\n sum: 0,\n count: 0,\n min: 0,\n max: 0,\n };\n groups.set(xVal, {\n ...current,\n count: current.count + 1,\n });\n } else if (yIdx >= 0) {\n const yVal = parseFloat(String(row[yIdx] ?? \"0\"));\n if (!isNaN(yVal)) {\n const current = groups.get(xVal) ?? {\n sum: 0,\n count: 0,\n min: Infinity,\n max: -Infinity,\n };\n groups.set(xVal, {\n sum: current.sum + yVal,\n count: current.count + 1,\n min: Math.min(current.min, yVal),\n max: Math.max(current.max, yVal),\n });\n }\n }\n });\n\n groups.forEach((stats, key) => {\n let value: number;\n switch (chart.aggregation) {\n case \"sum\":\n value = stats.sum;\n break;\n case \"avg\":\n value = stats.count > 0 ? stats.sum / stats.count : 0;\n break;\n case \"count\":\n value = stats.count;\n break;\n case \"min\":\n value = stats.min === Infinity ? 0 : stats.min;\n break;\n case \"max\":\n value = stats.max === -Infinity ? 0 : stats.max;\n break;\n default:\n value = stats.sum;\n }\n result.push({ [xCol]: key, [yCol]: Math.round(value * 100) / 100 });\n });\n } else if (yIdx >= 0) {\n result = data.rows\n .slice(0, Math.min(limit * 2, data.rows.length))\n .map((row) => ({\n [xCol]: row[xIdx] ?? \"\",\n [yCol]: parseFloat(String(row[yIdx] ?? \"0\")),\n }))\n .filter((item) => !isNaN(item[yCol] as number));\n }\n\n // Apply sorting\n if (sortOrder !== \"none\") {\n result.sort((a, b) => {\n const aVal = a[yCol] as number;\n const bVal = b[yCol] as number;\n return sortOrder === \"desc\" ? bVal - aVal : aVal - bVal;\n });\n }\n\n return {\n data: result.slice(0, limit),\n seriesKeys: [],\n yKey: yCol,\n };\n};\n","import {\n RefreshCw,\n Download,\n SortAsc,\n SortDesc,\n RotateCcw,\n TrendingUp,\n Filter,\n Image,\n} from \"lucide-react\";\nimport type { ChartType, SortOrder } from \"./types\";\n\ninterface ChartToolbarProps {\n chartType: ChartType;\n sortOrder: SortOrder;\n limitResults: number;\n showBrush: boolean;\n showTrendline: boolean;\n isRegenerating: boolean;\n hasRegenerate: boolean;\n onToggleSort: () => void;\n onLimitChange: (limit: number) => void;\n onToggleBrush: () => void;\n onToggleTrendline: () => void;\n onExportCSV: () => void;\n onExportPNG: () => void;\n onRegenerate: () => void;\n}\n\nexport function ChartToolbar({\n chartType,\n sortOrder,\n limitResults,\n showBrush,\n showTrendline,\n isRegenerating,\n hasRegenerate,\n onToggleSort,\n onLimitChange,\n onToggleBrush,\n onToggleTrendline,\n onExportCSV,\n onExportPNG,\n onRegenerate,\n}: ChartToolbarProps) {\n const supportsBrush =\n chartType === \"line\" || chartType === \"area\" || chartType === \"bar\";\n const supportsTrendline =\n chartType === \"bar\" || chartType === \"line\" || chartType === \"area\";\n\n return (\n <div className=\"mb-4 flex flex-wrap items-center gap-2 rounded-xl border border-white/10 bg-white/5 p-3\">\n {/* Sort Control */}\n <button\n onClick={onToggleSort}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${\n sortOrder !== \"none\"\n ? \"border border-violet-500/30 bg-violet-500/20 text-violet-400\"\n : \"bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white\"\n }`}\n title=\"Sort by value\"\n >\n {sortOrder === \"asc\" ? (\n <SortAsc className=\"h-4 w-4\" />\n ) : sortOrder === \"desc\" ? (\n <SortDesc className=\"h-4 w-4\" />\n ) : (\n <SortDesc className=\"h-4 w-4 opacity-50\" />\n )}\n Sort\n </button>\n\n {/* Limit Results */}\n <div className=\"flex items-center gap-2\">\n <Filter className=\"h-4 w-4 text-gray-400\" />\n <select\n value={limitResults}\n onChange={(e) => onLimitChange(Number(e.target.value))}\n className=\"rounded-lg border border-white/10 bg-white/5 px-2 py-1.5 text-sm text-gray-300 focus:border-violet-500/50 focus:outline-none\"\n >\n <option value={10}>Top 10</option>\n <option value={20}>Top 20</option>\n <option value={50}>Top 50</option>\n <option value={100}>Top 100</option>\n <option value={999999}>All</option>\n </select>\n </div>\n\n {/* Brush/Zoom Toggle */}\n {supportsBrush && (\n <button\n onClick={onToggleBrush}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${\n showBrush\n ? \"border border-cyan-500/30 bg-cyan-500/20 text-cyan-400\"\n : \"bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white\"\n }`}\n title=\"Enable zoom/brush\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Zoom\n </button>\n )}\n\n {/* Trend Line Toggle */}\n {supportsTrendline && (\n <button\n onClick={onToggleTrendline}\n className={`flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${\n showTrendline\n ? \"border border-emerald-500/30 bg-emerald-500/20 text-emerald-400\"\n : \"bg-white/5 text-gray-400 hover:bg-white/10 hover:text-white\"\n }`}\n title=\"Show average line\"\n >\n <TrendingUp className=\"h-4 w-4\" />\n Average\n </button>\n )}\n\n <div className=\"flex-1\" />\n\n {/* Export PNG Button */}\n <button\n onClick={onExportPNG}\n className=\"flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white\"\n title=\"Export chart as PNG image\"\n >\n <Image className=\"h-4 w-4\" />\n PNG\n </button>\n\n {/* Export CSV Button */}\n <button\n onClick={onExportCSV}\n className=\"flex items-center gap-1.5 rounded-lg bg-white/5 px-3 py-1.5 text-sm text-gray-400 transition-colors hover:bg-white/10 hover:text-white\"\n title=\"Export chart data as CSV\"\n >\n <Download className=\"h-4 w-4\" />\n CSV\n </button>\n\n {/* Regenerate Button */}\n {hasRegenerate && (\n <button\n onClick={onRegenerate}\n disabled={isRegenerating}\n className=\"flex items-center gap-1.5 rounded-lg bg-violet-500/20 px-3 py-1.5 text-sm text-violet-400 transition-colors hover:bg-violet-500/30 disabled:opacity-50\"\n >\n <RefreshCw\n className={`h-4 w-4 ${isRegenerating ? \"animate-spin\" : \"\"}`}\n />\n {isRegenerating ? \"...\" : \"Regenerate\"}\n </button>\n )}\n </div>\n );\n}\n","import type { TabularData, ChartConfig, ChartTheme } from \"./types\";\nimport { defaultDarkTheme } from \"./types\";\nimport { ChartThemeProvider } from \"./ThemeContext\";\nimport { SingleChart } from \"./SingleChart\";\n\nexport interface ChartDisplayProps {\n data: TabularData;\n charts: ChartConfig[];\n onRegenerate?: (chart: ChartConfig) => Promise<void>;\n /** Optional wrapper component for each chart card */\n cardWrapper?: React.ComponentType<{\n children: React.ReactNode;\n title?: string;\n className?: string;\n }>;\n /** Optional theme override */\n theme?: ChartTheme;\n}\n\nfunction DefaultCard({\n children,\n className = \"\",\n}: {\n children: React.ReactNode;\n title?: string;\n className?: string;\n}) {\n return <div className={className}>{children}</div>;\n}\n\nexport function ChartDisplay({\n data,\n charts,\n onRegenerate,\n cardWrapper: CardWrapper = DefaultCard,\n theme = defaultDarkTheme,\n}: ChartDisplayProps) {\n if (charts.length === 0) return null;\n\n return (\n <ChartThemeProvider theme={theme}>\n <div className=\"animate-fade-in space-y-6\">\n {charts.map((chart) => (\n <CardWrapper\n key={chart.id}\n title={chart.title}\n className=\"overflow-hidden rounded-2xl border border-white/10 bg-slate-900/50\"\n >\n <div className=\"p-6\">\n <h3 className=\"mb-2 bg-linear-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-xl font-bold text-transparent\">\n {chart.title}\n </h3>\n <p className=\"mb-4 text-gray-400\">{chart.description}</p>\n <SingleChart\n data={data}\n chart={chart}\n onRegenerate={onRegenerate}\n />\n </div>\n </CardWrapper>\n ))}\n </div>\n </ChartThemeProvider>\n );\n}\n","// Re-export from defaultDarkTheme for backwards compatibility\nexport { defaultDarkTheme as COLORS_THEME } from \"./types\";\n\nexport const COLORS = [\n \"#8b5cf6\", // Violet 500\n \"#06b6d4\", // Cyan 500\n \"#f43f5e\", // Rose 500\n \"#eab308\", // Yellow 500\n \"#10b981\", // Emerald 500\n \"#3b82f6\", // Blue 500\n \"#d946ef\", // Fuchsia 500\n \"#f97316\", // Orange 500\n];\n","import { generateObject, type LanguageModel } from \"ai\";\nimport { z } from \"zod\";\nimport type { ChartConfig, TabularData } from \"./types\";\n\n// ============ Input Validation Schemas ============\n\n/** Zod schema for simple API config (OpenAI-compatible endpoints) */\nexport const AIConfigSchema = z.object({\n /** API key for authentication */\n apiKey: z.string(),\n /** Model identifier (e.g. \"gpt-4o\", \"llama3\", \"mistral-large\") */\n model: z.string(),\n /** Custom base URL for non-OpenAI providers (Ollama, vLLM, Mistral, etc.) */\n baseURL: z.string().optional(),\n /** Provider hint — used to dynamically load the right SDK. Defaults to \"openai\". */\n provider: z\n .enum([\"openai\", \"anthropic\", \"google\", \"mistral\"])\n .optional()\n .default(\"openai\"),\n});\n\nexport type AIConfig = z.infer<typeof AIConfigSchema>;\n\n/** Zod schema for TabularData validation */\nexport const TabularDataSchema = z.object({\n headers: z.array(z.string()).min(1, \"Data must have at least one column\"),\n rows: z.array(z.array(z.string())),\n columns: z.array(\n z.object({\n name: z.string(),\n type: z.enum([\"string\", \"number\", \"date\", \"boolean\"]),\n index: z.number(),\n }),\n ),\n rowCount: z.number(),\n});\n\n/** Model input: either a simple config object or a pre-built LanguageModel */\nexport type ModelInput = AIConfig | LanguageModel;\n\n// ============ Chart Output Schemas ============\n\nconst ChartSuggestionSchema = z.object({\n type: z.enum([\"bar\", \"line\", \"pie\", \"scatter\", \"area\"]),\n title: z.string(),\n description: z.string(),\n xColumn: z\n .string()\n .describe(\"The EXACT column name to use for X axis (categories/labels)\"),\n yColumn: z\n .string()\n .describe(\"The EXACT column name to use for Y axis (values)\"),\n groupColumn: z\n .string()\n .optional()\n .describe(\"Optional column to group/segment the data\"),\n aggregation: z\n .enum([\"sum\", \"avg\", \"count\", \"min\", \"max\", \"none\"])\n .describe(\"How to aggregate Y values when there are duplicates in X\"),\n reasoning: z\n .string()\n .describe(\"Brief explanation of why this chart is useful for this data\"),\n});\n\nconst ChartSuggestionsResponseSchema = z.object({\n charts: z.array(ChartSuggestionSchema),\n});\n\nconst SingleChartResponseSchema = z.object({\n chart: ChartSuggestionSchema,\n});\n\n// ============ Error Handling ============\n\n/**\n * Extracts a user-friendly error message from AI provider errors.\n * Exported so consumers can use it in their own error handling.\n */\nexport function getAIErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n if (message.includes(\"rate limit\") || message.includes(\"429\")) {\n return \"Rate limit exceeded. Please wait a moment and try again.\";\n }\n if (\n message.includes(\"unauthorized\") ||\n message.includes(\"401\") ||\n message.includes(\"invalid api key\") ||\n message.includes(\"invalid_api_key\")\n ) {\n return \"Invalid API key. Please check your API key configuration.\";\n }\n if (\n message.includes(\"quota\") ||\n message.includes(\"insufficient_quota\") ||\n message.includes(\"billing\")\n ) {\n return \"API quota exceeded or billing issue. Please check your account status.\";\n }\n if (\n message.includes(\"network\") ||\n message.includes(\"timeout\") ||\n message.includes(\"econnrefused\") ||\n message.includes(\"fetch failed\")\n ) {\n return \"Network error. Please check your internet connection and try again.\";\n }\n if (\n message.includes(\"model\") &&\n (message.includes(\"not found\") || message.includes(\"does not exist\"))\n ) {\n return \"Model not available. Please select a different model.\";\n }\n\n return error.message;\n }\n\n return \"An unexpected error occurred. Please try again.\";\n}\n\n// ============ Data Summary Generation ============\n\n/**\n * Generate a text summary of tabular data for AI consumption.\n * If the consumer doesn't provide a `dataSummary`, this is used automatically.\n */\nexport function summarizeTabularData(data: TabularData): string {\n const lines: string[] = [];\n lines.push(`Dataset: ${data.rowCount} rows, ${data.headers.length} columns`);\n lines.push(`Columns: ${data.headers.join(\", \")}`);\n lines.push(\"\");\n\n for (const col of data.columns) {\n const idx = col.index;\n const values = data.rows.map((r) => r[idx] ?? \"\").filter((v) => v !== \"\");\n\n if (col.type === \"number\") {\n const nums = values.map(Number).filter((n) => !isNaN(n));\n if (nums.length > 0) {\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const avg = nums.reduce((a, b) => a + b, 0) / nums.length;\n lines.push(\n `- ${col.name} (${col.type}): min=${min}, max=${max}, avg=${avg.toFixed(2)}, ${nums.length} values`,\n );\n } else {\n lines.push(`- ${col.name} (${col.type}): no valid numeric values`);\n }\n } else {\n const distinct = new Set(values).size;\n const sample = values.slice(0, 5).join(\", \");\n lines.push(\n `- ${col.name} (${col.type}): ${distinct} distinct values, sample: [${sample}]`,\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n// ============ Model Resolution ============\n\nfunction isLanguageModel(input: unknown): input is LanguageModel {\n return (\n typeof input === \"object\" &&\n input !== null &&\n \"doGenerate\" in input &&\n typeof (input as Record<string, unknown>).doGenerate === \"function\"\n );\n}\n\n/**\n * Create a LanguageModel from an AIConfig.\n * Exported so consumers can create a model once and reuse it.\n *\n * @example\n * ```ts\n * const model = await createModel({ apiKey: \"sk-...\", model: \"gpt-4o\" });\n * const charts1 = await suggestCharts({ model, data, dataSummary });\n * const charts2 = await suggestCustomChart({ model, data, dataSummary, prompt: \"...\" });\n * ```\n */\nexport async function createModel(config: AIConfig): Promise<LanguageModel> {\n const parsed = AIConfigSchema.parse(config);\n\n if (parsed.baseURL || parsed.provider === \"openai\") {\n const { createOpenAI } = await import(\"@ai-sdk/openai\");\n const openai = createOpenAI({\n apiKey: parsed.apiKey,\n ...(parsed.baseURL && { baseURL: parsed.baseURL }),\n }) as unknown as (model: string) => LanguageModel;\n return openai(parsed.model);\n }\n\n switch (parsed.provider) {\n case \"anthropic\": {\n try {\n const { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n return createAnthropic({ apiKey: parsed.apiKey })(parsed.model);\n } catch {\n throw new Error(\n 'Provider \"anthropic\" requires @ai-sdk/anthropic. Install it: pnpm add @ai-sdk/anthropic',\n );\n }\n }\n case \"google\": {\n try {\n const { createGoogleGenerativeAI } = await import(\"@ai-sdk/google\");\n return createGoogleGenerativeAI({ apiKey: parsed.apiKey })(\n parsed.model,\n );\n } catch {\n throw new Error(\n 'Provider \"google\" requires @ai-sdk/google. Install it: pnpm add @ai-sdk/google',\n );\n }\n }\n case \"mistral\": {\n try {\n const { createMistral } = await import(\"@ai-sdk/mistral\");\n return createMistral({ apiKey: parsed.apiKey })(parsed.model);\n } catch {\n throw new Error(\n 'Provider \"mistral\" requires @ai-sdk/mistral. Install it: pnpm add @ai-sdk/mistral',\n );\n }\n }\n default: {\n const { createOpenAI } = await import(\"@ai-sdk/openai\");\n const openai = createOpenAI({\n apiKey: parsed.apiKey,\n }) as unknown as (model: string) => LanguageModel;\n return openai(parsed.model);\n }\n }\n}\n\nexport async function resolveModel(input: ModelInput): Promise<LanguageModel> {\n if (isLanguageModel(input)) return input;\n return createModel(input as AIConfig);\n}\n\n// ============ Prompts ============\n\nconst getChartSystemPrompt = (\n columns: string[],\n language?: string,\n) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : \"\"}\n\nYou will analyze CSV data and suggest the best charts to visualize it.\n\nAVAILABLE COLUMNS (use these EXACT names):\n${columns.map((c) => `- \"${c}\"`).join(\"\\n\")}\n\nCRITICAL RULES:\n1. xColumn and yColumn MUST be exact column names from the list above\n2. For numeric analysis, yColumn should be a numeric column\n3. For categorical comparisons, xColumn should be a categorical column\n4. Only suggest charts that make sense for the data types\n5. Use aggregation when there are multiple rows per category:\n - \"sum\" for totals (sales, revenue)\n - \"avg\" for averages (ratings, scores)\n - \"count\" for frequencies\n - \"none\" for unique values or time series\n6. Suggest 2-4 charts maximum, focusing on the most insightful ones\n\nCHART TYPE GUIDELINES:\n- bar: Compare categories (xColumn=category, yColumn=numeric)\n- line: Show trends over time (xColumn=date/time, yColumn=numeric)\n- pie: Show proportions (xColumn=category, yColumn=numeric with sum/count)\n- scatter: Show correlations (xColumn=numeric, yColumn=numeric, aggregation=none)\n- area: Show cumulative trends (xColumn=date/time, yColumn=numeric)`;\n\nconst getCustomChartPrompt = (\n columns: string[],\n language?: string,\n) => `You are a data visualization expert.${language ? ` Respond in ${language}.` : \"\"}\n\nCreate a chart configuration based on the user's request.\n\nAVAILABLE COLUMNS (use these EXACT names):\n${columns.map((c) => `- \"${c}\"`).join(\"\\n\")}\n\nIMPORTANT: Column names MUST exactly match the list above.`;\n\n// ============ Helpers ============\n\nfunction mapChartResult(\n raw: z.infer<typeof ChartSuggestionSchema>,\n id: string,\n): ChartConfig {\n return {\n id,\n type: raw.type,\n title: raw.title,\n description: raw.description,\n xAxis: raw.xColumn,\n yAxis: raw.yColumn,\n groupBy: raw.groupColumn,\n aggregation: raw.aggregation,\n dataConfig: {\n xColumn: raw.xColumn,\n yColumn: raw.yColumn,\n groupColumn: raw.groupColumn,\n },\n };\n}\n\n// ============ Options ============\n\nexport interface SuggestChartsOptions {\n /** The AI model — either a simple config or a LanguageModel instance */\n model: ModelInput;\n /** The tabular data to analyze */\n data: TabularData;\n /** A text summary of the data. If omitted, auto-generated from `data`. */\n dataSummary?: string;\n /** Language for AI responses (e.g. \"English\", \"French\") */\n language?: string;\n /** Temperature for AI generation (default: 0.5) */\n temperature?: number;\n}\n\nexport interface SuggestCustomChartOptions {\n /** The AI model — either a simple config or a LanguageModel instance */\n model: ModelInput;\n /** The tabular data */\n data: TabularData;\n /** A text summary of the data. If omitted, auto-generated from `data`. */\n dataSummary?: string;\n /** The user's chart request (e.g. \"show sales by month\") */\n prompt: string;\n /** Language for AI responses */\n language?: string;\n /** Temperature (default: 0.5) */\n temperature?: number;\n}\n\nexport interface RepairChartOptions {\n /** The AI model — either a simple config or a LanguageModel instance */\n model: ModelInput;\n /** The chart configuration that failed */\n failedChart: ChartConfig;\n /** Available column names */\n columns: string[];\n /** Description of why the chart failed */\n errorContext: string;\n /** Language for AI responses */\n language?: string;\n /** Temperature (default: 0.3) */\n temperature?: number;\n}\n\n// ============ Public API ============\n\n/**\n * Generate chart suggestions from tabular data using AI.\n *\n * @example\n * ```ts\n * import { suggestCharts } from \"csv-charts-ai\";\n *\n * // Minimal — auto-generates dataSummary from the data\n * const charts = await suggestCharts({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * });\n *\n * // Custom endpoint — Ollama\n * const charts = await suggestCharts({\n * model: { apiKey: \"\", model: \"llama3\", baseURL: \"http://localhost:11434/v1\" },\n * data: myData,\n * });\n *\n * // Advanced — any LanguageModel from the ai SDK\n * import { anthropic } from \"@ai-sdk/anthropic\";\n * const charts = await suggestCharts({\n * model: anthropic(\"claude-sonnet-4-20250514\"),\n * data: myData,\n * language: \"French\",\n * });\n * ```\n */\nexport async function suggestCharts(\n options: SuggestChartsOptions,\n): Promise<ChartConfig[]> {\n const { data, language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n TabularDataSchema.parse(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: ChartSuggestionsResponseSchema,\n system: getChartSystemPrompt(data.headers, language),\n prompt: `Analyze this CSV data and suggest the best charts:\\n\\n${dataSummary}`,\n temperature,\n });\n\n return object.charts.map((s, i) =>\n mapChartResult(s, `chart-${i}-${Date.now()}`),\n );\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\n/**\n * Generate a single chart from a user's text prompt.\n *\n * @example\n * ```ts\n * const chart = await suggestCustomChart({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * prompt: \"Show me a bar chart of sales by category\",\n * });\n * ```\n */\nexport async function suggestCustomChart(\n options: SuggestCustomChartOptions,\n): Promise<ChartConfig | null> {\n const { data, prompt, language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n TabularDataSchema.parse(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: SingleChartResponseSchema,\n system: getCustomChartPrompt(data.headers, language),\n prompt: `Data summary:\\n${dataSummary}\\n\\nUser request: ${prompt}`,\n temperature,\n });\n\n return mapChartResult(object.chart, `chart-custom-${Date.now()}`);\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\n/**\n * Repair a chart configuration that failed to render.\n *\n * @example\n * ```ts\n * const fixed = await repairChart({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * failedChart: brokenChart,\n * columns: [\"name\", \"sales\", \"date\"],\n * errorContext: \"Column 'revenue' does not exist\",\n * });\n * ```\n */\nexport async function repairChart(\n options: RepairChartOptions,\n): Promise<ChartConfig | null> {\n const {\n failedChart,\n columns,\n errorContext,\n language,\n temperature = 0.3,\n } = options;\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: SingleChartResponseSchema,\n system: getCustomChartPrompt(columns, language),\n prompt: `The following chart configuration failed to render:\\n${JSON.stringify(failedChart, null, 2)}\\n\\nError context: ${errorContext}\\n\\nPlease fix the configuration to use valid columns and aggregation. Available columns: ${columns.join(\", \")}`,\n temperature,\n });\n\n return mapChartResult(object.chart, failedChart.id);\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n","import { generateObject, generateText, streamText } from \"ai\";\nimport { z } from \"zod\";\nimport type { TabularData, ChartConfig } from \"./types\";\nimport type { ModelInput } from \"./ai\";\nimport { summarizeTabularData, getAIErrorMessage, resolveModel } from \"./ai\";\nimport { suggestCharts } from \"./ai\";\n\n// ============ Schemas ============\n\nconst DataSummarySchema = z.object({\n summary: z.string(),\n keyInsights: z.array(z.string()),\n dataQuality: z.string(),\n});\n\nconst AnomalySchema = z.object({\n row: z.number(),\n column: z.string(),\n value: z.string(),\n issue: z.string(),\n severity: z.enum([\"low\", \"medium\", \"high\"]),\n});\n\nconst AnomaliesResponseSchema = z.object({\n anomalies: z.array(AnomalySchema),\n});\n\n// ============ Result Types ============\n\nexport interface DataSummaryResult {\n summary: string;\n keyInsights: string[];\n dataQuality: string;\n}\n\nexport interface AnomalyResult {\n row: number;\n column: string;\n value: string;\n issue: string;\n severity: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface AnalysisResult {\n summary: DataSummaryResult;\n anomalies: AnomalyResult[];\n charts: ChartConfig[];\n}\n\n// ============ Prompts ============\n\nconst summarySystemPrompt = (\n language?: string,\n) => `You are a data analyst.${language ? ` Respond in ${language}.` : \"\"}\n\nAnalyze the provided CSV data summary and provide:\n1. A comprehensive summary of what this dataset represents (2-3 sentences)\n2. 3-5 key insights or patterns you notice\n3. An assessment of data quality (completeness, consistency)`;\n\nconst anomalySystemPrompt = (\n language?: string,\n) => `You are a data quality expert.${language ? ` Respond in ${language}.` : \"\"}\n\nAnalyze the provided CSV data and identify anomalies, outliers, or suspicious data points.\n\nFor each anomaly found, provide:\n1. Row number (1-indexed, excluding header)\n2. Column name\n3. The problematic value\n4. Description of the issue\n5. Severity (low, medium, high)\n\nLook for:\n- Missing or empty values where data is expected\n- Values that don't match the expected type\n- Outliers (extremely high or low values)\n- Inconsistent formatting\n- Invalid dates or formats\n\nAnalyze ALL rows provided. Return empty array if no anomalies found.`;\n\nconst questionSystemPrompt = (\n language?: string,\n) =>\n `You are a data analysis expert.${language ? ` Respond in ${language}.` : \"\"}\\n\\nThe user will ask questions about a CSV dataset. Respond clearly and precisely.`;\n\n// ============ Helper ============\n\nfunction buildSampleCSV(data: TabularData, maxRows = 50): string {\n const header = data.headers.join(\",\");\n const rows = data.rows\n .slice(0, maxRows)\n .map((row) => row.join(\",\"))\n .join(\"\\n\");\n return `${header}\\n${rows}`;\n}\n\n// ============ Individual Functions ============\n\nexport interface SummarizeDataOptions {\n model: ModelInput;\n data: TabularData;\n dataSummary?: string;\n language?: string;\n temperature?: number;\n}\n\n/**\n * Generate an AI summary of tabular data.\n *\n * @example\n * ```ts\n * const result = await summarizeData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * });\n * console.log(result.summary);\n * console.log(result.keyInsights);\n * console.log(result.dataQuality);\n * ```\n */\nexport async function summarizeData(\n options: SummarizeDataOptions,\n): Promise<DataSummaryResult> {\n const { data, language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: DataSummarySchema,\n system: summarySystemPrompt(language),\n prompt: `Here is the data to analyze:\\n\\n${dataSummary}`,\n temperature,\n });\n\n return {\n summary: object.summary,\n keyInsights: object.keyInsights,\n dataQuality: object.dataQuality,\n };\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\nexport interface DetectAnomaliesOptions {\n model: ModelInput;\n data: TabularData;\n dataSummary?: string;\n /** Max rows to send for analysis (default: 50) */\n maxRows?: number;\n language?: string;\n temperature?: number;\n}\n\n/**\n * Detect anomalies in tabular data using AI.\n *\n * @example\n * ```ts\n * const anomalies = await detectAnomalies({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * });\n * anomalies.forEach(a => console.log(`Row ${a.row}: ${a.issue}`));\n * ```\n */\nexport async function detectAnomalies(\n options: DetectAnomaliesOptions,\n): Promise<AnomalyResult[]> {\n const { data, maxRows = 50, language, temperature = 0.3 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n const sampleCSV = buildSampleCSV(data, maxRows);\n\n try {\n const model = await resolveModel(options.model);\n\n const { object } = await generateObject({\n model,\n schema: AnomaliesResponseSchema,\n system: anomalySystemPrompt(language),\n prompt: `Data summary:\\n${dataSummary}\\n\\nData to analyze (CSV format):\\n${sampleCSV}`,\n temperature,\n });\n\n return object.anomalies;\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\nexport interface AskAboutDataOptions {\n model: ModelInput;\n data: TabularData;\n question: string;\n dataSummary?: string;\n /** Previous conversation messages for context */\n history?: Array<{ prompt: string; response: string }>;\n language?: string;\n temperature?: number;\n}\n\n/**\n * Ask a question about the data and get a text response.\n *\n * @example\n * ```ts\n * const answer = await askAboutData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * question: \"What is the average revenue by category?\",\n * });\n * console.log(answer);\n * ```\n */\nexport async function askAboutData(\n options: AskAboutDataOptions,\n): Promise<string> {\n const { data, question, history = [], language, temperature = 0.5 } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const historyText = history\n .map((item) => `User: ${item.prompt}\\nAI: ${item.response}`)\n .join(\"\\n\\n\");\n const contextPrompt = historyText\n ? `Previous conversation history:\\n${historyText}\\n\\n`\n : \"\";\n\n const { text } = await generateText({\n model,\n system: questionSystemPrompt(language),\n prompt: `Here is the data:\\n\\n${dataSummary}\\n\\n${contextPrompt}User question: ${question}`,\n temperature,\n });\n\n return text;\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\nexport interface StreamAskAboutDataOptions extends AskAboutDataOptions {\n onChunk: (chunk: string) => void;\n onComplete: (fullText: string) => void;\n}\n\n/**\n * Ask a question with streaming response.\n *\n * @example\n * ```ts\n * await streamAskAboutData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myData,\n * question: \"What trends do you see?\",\n * onChunk: (chunk) => process.stdout.write(chunk),\n * onComplete: (full) => console.log(\"\\nDone:\", full.length, \"chars\"),\n * });\n * ```\n */\nexport async function streamAskAboutData(\n options: StreamAskAboutDataOptions,\n): Promise<void> {\n const {\n data,\n question,\n history = [],\n language,\n temperature = 0.5,\n onChunk,\n onComplete,\n } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n try {\n const model = await resolveModel(options.model);\n\n const historyText = history\n .map((item) => `User: ${item.prompt}\\nAI: ${item.response}`)\n .join(\"\\n\\n\");\n const contextPrompt = historyText\n ? `Previous conversation history:\\n${historyText}\\n\\n`\n : \"\";\n\n let streamError: Error | null = null;\n\n const result = streamText({\n model,\n system: questionSystemPrompt(language),\n prompt: `Here is the data:\\n\\n${dataSummary}\\n\\n${contextPrompt}User question: ${question}`,\n temperature,\n onError: ({ error }) => {\n streamError =\n error instanceof Error ? error : new Error(String(error));\n },\n });\n\n let fullText = \"\";\n\n for await (const textPart of result.textStream) {\n fullText += textPart;\n onChunk(textPart);\n }\n\n if (streamError) throw streamError;\n\n const finishReason = await result.finishReason;\n if (finishReason === \"error\") {\n throw new Error(\"The AI model encountered an error while generating the response.\");\n }\n\n onComplete(fullText);\n } catch (error) {\n throw new Error(getAIErrorMessage(error));\n }\n}\n\n// ============ Full Pipeline ============\n\nexport interface AnalyzeOptions {\n model: ModelInput;\n data: TabularData;\n dataSummary?: string;\n language?: string;\n /** Set to false to skip anomaly detection (default: true) */\n detectAnomalies?: boolean;\n /** Set to false to skip chart suggestions (default: true) */\n suggestCharts?: boolean;\n}\n\n/**\n * Run a complete AI analysis on tabular data in one call.\n * Returns summary, anomalies, and chart suggestions.\n *\n * @example\n * ```ts\n * import { analyzeData, ChartDisplay } from \"csv-charts-ai\";\n *\n * const result = await analyzeData({\n * model: { apiKey: \"sk-...\", model: \"gpt-4o\" },\n * data: myCSVData,\n * });\n *\n * console.log(result.summary.keyInsights);\n * console.log(`Found ${result.anomalies.length} anomalies`);\n *\n * // Render charts\n * <ChartDisplay data={myCSVData} charts={result.charts} />\n * ```\n */\nexport async function analyzeData(\n options: AnalyzeOptions,\n): Promise<AnalysisResult> {\n const {\n data,\n language,\n detectAnomalies: runAnomalies = true,\n suggestCharts: runCharts = true,\n } = options;\n const dataSummary = options.dataSummary ?? summarizeTabularData(data);\n\n // Run all in parallel\n const [summary, anomalies, charts] = await Promise.all([\n summarizeData({ model: options.model, data, dataSummary, language }),\n runAnomalies\n ? detectAnomalies({ model: options.model, data, dataSummary, language })\n : Promise.resolve([]),\n runCharts\n ? suggestCharts({ model: options.model, data, dataSummary, language })\n : Promise.resolve([]),\n ]);\n\n return { summary, anomalies, charts };\n}\n"],"mappings":"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","names":["RefreshCw","Image","jsx","jsx","jsxs","RefreshCw","jsx","jsxs","generateObject","z","z","generateObject"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "csv-charts-ai",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,8 +20,7 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "build": "tsup",
23
- "dev": "tsup --watch",
24
- "release": "semantic-release"
23
+ "dev": "tsup --watch"
25
24
  },
26
25
  "peerDependencies": {
27
26
  "ai": "^5.0.0 || ^6.0.0",
@@ -42,18 +41,11 @@
42
41
  }
43
42
  },
44
43
  "devDependencies": {
45
- "@semantic-release/changelog": "^6.0.3",
46
- "@semantic-release/commit-analyzer": "^13.0.1",
47
- "@semantic-release/git": "^10.0.1",
48
- "@semantic-release/github": "^12.0.6",
49
- "@semantic-release/npm": "^13.1.5",
50
- "@semantic-release/release-notes-generator": "^14.1.0",
51
44
  "@types/react": "^19.2.7",
52
45
  "ai": "^6.0.134",
53
46
  "lucide-react": "^0.556.0",
54
47
  "react": "^19.2.4",
55
48
  "recharts": "^3.5.1",
56
- "semantic-release": "^25.0.3",
57
49
  "tsup": "^8.5.0",
58
50
  "typescript": "^5.9.3",
59
51
  "zod": "^4.1.13"