Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/manusapis/Agix/llms.txt

Use this file to discover all available pages before exploring further.

Agix ships three analytics services that operate directly on your spreadsheet columns: forecastService projects future values from historical date-indexed data, anomalyService flags rows that fall outside expected statistical bounds, and sentimentService scores text entries and tracks satisfaction trends over time. All three can be combined with the scheduler to run automatically on a recurring basis.

Forecasting

forecastService lives at src/services/analytics/forecast.service.ts and exposes three methods for time-series work.

predict(request)

Generates a forward projection for a numeric column indexed by dates.
async predict(request: ForecastRequest): Promise<ForecastResult>
// ForecastRequest
interface ForecastRequest {
  dateColumn: string;                                             // Column letter or header name
  valueColumn: string;
  horizon: number;                                               // Number of future periods to predict
  seasonality?: "daily" | "weekly" | "monthly" | "yearly" | "auto";
}

// ForecastResult
interface ForecastResult {
  forecast: ForecastPoint[];                                     // One entry per future period
  confidenceIntervals: ConfidenceBand[];                         // e.g. 95% band
  modelUsed: string;                                             // e.g. "seasonal-decomposition"
  influentialPoints: InfluentialPoint[];
}

// ForecastPoint
interface ForecastPoint {
  date: string;          // ISO date string
  predicted: number;
  lowerBound: number;
  upperBound: number;
}
Example:
const result = await forecastService.predict({
  dateColumn: "A",
  valueColumn: "B",
  horizon: 30,           // predict the next 30 days
  seasonality: "weekly",
});

result.forecast.forEach((point) => {
  console.log(`${point.date}: ${point.predicted} [${point.lowerBound}${point.upperBound}]`);
});

decompose(dates, values)

Breaks a time series into its structural components for inspection or charting.
decompose(dates: string[], values: number[]): {
  trend: number[];
  seasonal: number[];
  residual: number[];
}

findInfluentialPoints(dates, values)

Returns the historical data points that most heavily shaped the forecast model.
findInfluentialPoints(dates: string[], values: number[]): InfluentialPoint[]

// InfluentialPoint
interface InfluentialPoint {
  date: string;
  value: number;
  influence: number;     // relative weight in the model, 0–1
}

Anomaly Detection

anomalyService lives at src/services/analytics/anomaly.service.ts. It accepts a numeric column and a detection method, then returns every row that falls outside expected bounds.

detect(columnValues, columnName, method)

async detect(
  columnValues: number[],
  columnName: string,
  method: "zscore" | "iqr" | "isolation-forest"
): Promise<AnomalyResult>
method
string
default:"zscore"
Detection algorithm to use. Defaults to "zscore" if omitted.
Computes the mean and standard deviation of the column, then flags any row where the absolute z-score exceeds 2.5.
z = |( value − mean ) / stddev|
flagged when z > 2.5
Best for normally distributed data where you want to catch values more than 2.5 standard deviations from the centre.

Result type

interface AnomalyResult {
  column: string;
  anomalies: AnomalyPoint[];
  threshold: number;           // 2.5 for zscore, 1.5 for iqr
  method: "zscore" | "iqr" | "isolation-forest";
}

interface AnomalyPoint {
  rowIndex: number;
  value: number;
  expectedValue: number;       // mean (zscore) or midpoint of Q1+Q3 (iqr)
  deviation: number;           // z-score or absolute distance from expectedValue
}
Example:
const revenue = [12000, 13400, 11800, 98000, 12700, 11200]; // 98000 is suspect

const result = await anomalyService.detect(revenue, "Revenue", "zscore");

result.anomalies.forEach((pt) => {
  console.log(`Row ${pt.rowIndex}: ${pt.value} (deviation: ${pt.deviation.toFixed(2)})`);
});
// → Row 3: 98000 (deviation: 3.47)

Sentiment Analysis

sentimentService lives at src/services/analytics/sentiment.service.ts. It scores every text entry in a column and optionally tracks how sentiment shifts across multiple analysis runs.

analyze(columnValues, columnName)

Scores each row as "positive", "negative", or "neutral", and returns an overall column score.
async analyze(
  columnValues: string[],
  columnName: string
): Promise<SentimentResult>
interface SentimentResult {
  column: string;
  entries: SentimentEntry[];
  overallScore: number;        // average score across all rows, −1 to 1
  trend: "improving" | "declining" | "stable";
}

interface SentimentEntry {
  rowIndex: number;
  text: string;
  score: number;               // −1 (most negative) to 1 (most positive)
  label: "positive" | "negative" | "neutral";
}
Use cases:
  • Customer feedback or NPS comment columns
  • Product reviews imported from a web source
  • Support ticket subject lines or descriptions
  • Employee survey free-text responses

trackTrend(columnName, history)

Compares the last three SentimentResult snapshots in history and classifies the direction of change.
async trackTrend(
  columnName: string,
  history: SentimentResult[]
): Promise<"improving" | "declining" | "stable">
The method looks at the final three entries of the history array. If the most recent overallScore is more than 0.1 higher than the oldest of the three, the trend is "improving". If it drops more than 0.1, it is "declining". Otherwise it is "stable". Example:
const feedback = [
  "Great product, really happy with it.",
  "Support was slow to respond.",
  "Exactly what I needed.",
];

const result = await sentimentService.analyze(feedback, "CustomerFeedback");

console.log(`Overall: ${result.overallScore.toFixed(2)}${result.trend}`);
result.entries.forEach((e) =>
  console.log(`  Row ${e.rowIndex}: [${e.label}] ${e.text}`)
);

All three analytics services integrate with the scheduler. You can register a daily refresh-analysis task to re-run forecasts, anomaly checks, or sentiment scans automatically as new data lands in your sheet. See the Scheduler page for a step-by-step example.

Build docs developers (and LLMs) love