SwapAI

API reference

The modern @swapai/core classifier, inspection and provider surface.

createClassifier(config)

function createClassifier<Config extends ResultConfig, FacetName extends string>(
  config: CreateClassifierConfig<Config, FacetName>,
): ConfiguredClassifier<ResultFor<Config>, FacetName>;

Creates a persistent classifier. Construction and classification never start training.

ConfiguredClassifier

interface ConfiguredClassifier<Result, FacetName extends string> {
  isTrained(): boolean;
  classify(input: string, facets?: ClassificationFacets<FacetName>): Promise<Result>;
  logClassification(
    input: string,
    result: Result,
    facets?: ClassificationFacets<FacetName>,
  ): void;
  inspect(): ClassifierInspection;
  requestTraining(): Promise<TrainingRequestResult>;
  retryTraining(trainingRunId: string): Promise<TrainingCompletionResult>;
  promoteCandidate(trainingRunId: string): Promise<TrainingPromotionResult>;
  reconcileTraining(): Promise<readonly TrainingRunInspection[]>;
  erase(): Promise<void>;
  flush(): Promise<void>;
  close(): Promise<void>;
}

Classification and collection

classify() returns the promoted model's answer when one is active. Otherwise it calls the configured reference and records its answer. While an unpromoted candidate exists, SwapAI also queues candidate inference and persists shadow evidence without returning the candidate answer.

logClassification() records an authoritative result without calling the reference. It also feeds an existing candidate's shadow evaluation.

isTrained() reports whether this process can use the promoted model. flush() waits for queued collection and shadow writes. close() flushes and releases local model and storage resources.

Inspection and operator actions

inspect() is read-only. It returns data counts, result bins, facet coverage, deficits and complete durable training-run history with evaluation, shadow, provider-resource and cleanup evidence. The separate classifiers UI projection displays only the newest 100 runs.

requestTraining() freezes one dataset revision and starts at most one provider run for it. retryTraining(id) explicitly spends on a new attempt for an eligible failed or rejected run. promoteCandidate(id) activates only a valid current candidate with passing protected and fresh shadow evidence. reconcileTraining() asks the configured provider to reconcile durable running runs. erase() cancels active provider work, verifies cleanup, and removes the classifier's database data, bundles and complete artifacts.

CreateClassifierConfig

interface CreateClassifierConfig<Config, FacetName extends string> {
  readonly name: string;
  readonly result: Config;
  readonly reference: ReferenceClassifier<ResultFor<Config>>;
  readonly training?: TrainingProvider;
  readonly decisionBoundaries?: readonly number[];
  readonly facets?: readonly FacetName[];
  readonly acceptableError?: number | `${number}%`;
  readonly maxTrainingSet?: number;
  readonly dataDirectory?: string;
  readonly datasetRequirements?: DatasetRequirementOverrides;
  readonly onBackgroundError?: (error: SwapAIError) => void;
}

Training results

type TrainingRequestResult =
  | { status: "not_ready"; deficits: readonly DatasetDeficit[] }
  | TrainingCompletionResult
  | {
      status: "already_running" | "already_promoted" | "already_failed";
      trainingRunId: string;
      datasetRevisionId: string;
    };

interface TrainingCompletionResult {
  readonly status: "candidate" | "rejected";
  readonly trainingRunId: string;
  readonly datasetRevisionId: string;
}

interface TrainingPromotionResult {
  readonly status: "promoted";
  readonly trainingRunId: string;
  readonly datasetRevisionId: string;
}

A repeat request may return the existing candidate for the same revision.

Inspection

interface ClassifierInspection {
  readonly name: string;
  readonly totalExamplesLogged: number;
  readonly retainedExamples: number;
  readonly readyForTraining: boolean;
  readonly resultBins: readonly ResultBinInspection[];
  readonly facetCoverage: readonly FacetValueInspection[];
  readonly deficits: readonly DatasetDeficit[];
  readonly examplesByPurpose: Record<
    "training" | "validation" | "representative_test" | "coverage_test",
    number
  >;
  readonly latestTrainingRun: TrainingRunInspection | null;
  readonly trainingRuns: readonly TrainingRunInspection[];
}

interface TrainingRunInspection {
  readonly id: string;
  readonly datasetRevisionId: string;
  readonly provider: string;
  readonly status: "running" | "failed" | "rejected" | "candidate" | "promoted";
  readonly providerRunId: string | null;
  readonly costUsd: number | null;
  readonly artifactSha256: string | null;
  readonly failureMessage: string | null;
  readonly resources: readonly TrainingResource[];
  readonly cleanup: {
    readonly status: "not_required" | "pending" | "succeeded" | "failed";
    readonly message: string | null;
  };
  readonly evaluations: readonly TrainingEvaluationInspection[];
  readonly shadow: ShadowEvaluationInspection | null;
  readonly startedAt: number;
  readonly finishedAt: number | null;
}

FacetValueInspection contains a declared facet name, a value or null for unlabelled data, total examples and per-purpose counts. TrainingEvaluationInspection contains purpose, optional result bin, example count, error and pass state. ShadowEvaluationInspection contains example count, mean error, pass state, failure count, last failure and last evaluation time.

TrainingProvider

interface TrainingProvider {
  readonly name: string;
  train(
    job: TrainingJob,
    lifecycle?: TrainingLifecycleReporter,
  ): Promise<TrainingCandidate>;
  reconcile?(
    run: TrainingRunInspection,
    lifecycle?: TrainingLifecycleReporter,
  ): Promise<TrainingReconciliationResult>;
  cancel?(
    run: TrainingRunInspection,
    lifecycle?: TrainingLifecycleReporter,
  ): Promise<void>;
}

The lifecycle reporter persists provider run identity, exact resources and cleanup state as soon as they are known.

Built-in constructors:

localTrainer()
runpodTrainer(options) // from @swapai/core/runpod

Both use the same format-2 runner bundle and SHA-256 verification.

Explicit legacy held-out migration

function inspectLegacyHeldOutMigration(
  options: LegacyHeldOutMigrationOptions,
): LegacyHeldOutMigrationInspection;

function migrateLegacyHeldOutExamples(
  options: MigrateLegacyHeldOutExamplesOptions,
): LegacyHeldOutMigrationResult;

Inspection returns ready, blocked or already_migrated, an immutable plan SHA-256, counts, groups and typed blockers. Eligible targets cover only pre-adoption held-out validation rows; post-adoption protected rows remain unchanged. Apply requires that reviewed hash plus the literal model-selection attestation, named operator and reason. See Legacy compatibility for the offline two-phase procedure and complete blocker list.

Effect exports

The @swapai/core/effect entry point exports createClassifierEffect, isTrained, classifyConfigured, logClassification, inspect, requestTraining, retryTraining, promoteCandidate, reconcileTraining, erase, flush and close. It also retains the legacy classify and classifyWithReference adapters. See Effect.

Legacy init

init(config) remains exported for v0.3 compatibility. Its classifier also supports erase(), while clearTrainingData() remains the older queued-clear operation. See Legacy compatibility.