Fine-Tuning
Fine-Tuning
@toothfairyai/sdk@latest…Fine-Tuning Management Module Dataset generation, training lifecycle, the adapter registry (versioning/rollback) and serving modes for fine-tuned models.
Accessed via client.finetuning.
Methods
| Method | HTTP | Endpoint |
|---|---|---|
listModels | GET | GET /models |
listJobs | GET | GET /jobs |
generateDataset | POST | POST /dataset |
getStatus | GET | GET /status/{id} |
startTraining | POST | POST /start/{id} |
cancelTraining | POST | POST /cancel/{id} |
downloadDataset | GET | GET /dataset/{id} |
listAdapters | GET | GET /adapters |
createAdapterVersion | POST | POST /adapters/{id}/version |
rollbackAdapter | POST | POST /adapters/{id}/rollback |
getServing | GET | GET /serving/{id} |
setServing | POST | POST /serving/{id} |
servingPower | POST | POST /serving/{id}/power |
listModels
List trainable models with their configurations
async listModels()
Endpoint: GET /models · AI service
Example
const result = await client.finetuning.listModels();
listJobs
List fine-tuning jobs for the workspace
async listJobs(status?: FinetuningJobStatus | string)
Endpoint: GET /jobs · Fine-Tuning service
Example
const result = await client.finetuning.listJobs();
generateDataset
Generate a training dataset from workspace documents Set rlvr: true with training_type 'grpoTraining' to build a task manifest from the workspace's rlTask documents (RL with verifiable rewards).
async generateDataset(
data: {
name: string;
base_model: string;
training_type?: string;
topics?: string[];
test_size?: number;
test_size_threshold?: number;
rlvr?: boolean;
description?: string;
}
)
Endpoint: POST /dataset · Fine-Tuning service
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human-readable name for the training job |
training_type | string | no | Training method to use. Each method maps to a document type: |
conversationalTraining(SFT) — uses Conversation documentsgenerativeTraining(DPO) — uses Preference documentsgrpoTraining(GRPO) — uses Conversation documents (model self-generates)ktoTraining(KTO) — uses Preference documents (unpaired)continuedPretraining(CPT) — uses Conversation documents (plain text)
Defaults to conversationalTraining. Note: the REST endpoint does not enforce the enum at request time (validation occurs in the async worker); send one of the listed values.
Allowed: conversationalTraining, generativeTraining, grpoTraining, ktoTraining, continuedPretraining |
| base_model | string | yes | Base model to fine-tune (canonical id from the /models endpoint) |
| topics | array<string> | no | Optional list of topic IDs to filter documents by |
| test_size | number | no | Fraction of the dataset to reserve as the test split (0.0–1.0) |
| test_size_threshold | integer | no | Minimum number of examples required in the test split |
| rlvr | boolean | no | RL with verifiable rewards. Only valid with training_type: grpoTraining — builds a task manifest from the workspace's rlTask documents instead of a conversation dataset. Configure the RL run itself via config.rl on /start. |
| description | string | no | Optional human-readable description of the training job |
Example
const result = await client.finetuning.generateDataset('…');
getStatus
Get detailed status of a fine-tuning job
async getStatus(trainingLogId: string)
Endpoint: GET /status/{id} · Fine-Tuning service
Response fields
| Field | Type | Description |
|---|---|---|
training_log_id | string | Training log ID |
status | string | Current job status. Lifecycle: dispatched → inProgress → datasetReady → fineTuningRequested → training → completed (or inError). |
Allowed: dispatched, inProgress, datasetReady, fineTuningRequested, training, completed, inError, cancellationRequested |
| name | string | Job name |
| training_type | string | Training method |
| created_at | string | Job creation timestamp (ISO 8601) |
| duration | integer | Training duration in seconds (present once training has progressed) |
| dataset | object | Dataset paths (present after dataset generation reaches the relevant stage) |
| compute_uoi | number | UoI consumed by the training job (present when status is completed) |
| model_id | string | S3 path to the fine-tuned LoRA adapter (present when status is completed) |
| base_model | string | Base model used for training (present when status is completed) |
| metrics_summary | object | Final training metrics (present when status is completed) |
| downloads | object | Presigned download URLs (present when status is completed) |
| error | object | Error detail (present when status is inError) |
Example
const result = await client.finetuning.getStatus('agent-id');
startTraining
Start a fine-tuning training job The job must be in 'datasetReady' status.
async startTraining(trainingLogId: string, config?: Record<string, any>)
Endpoint: POST /start/{id} · Fine-Tuning service
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
config | object | no | Training configuration overrides merged over the existing training configuration. Keys not present retain their prior values. Only the keys listed in x-recognized-config-keys are consumed by the managed Unsloth/QLoRA+SageMaker training engine; any other key is silently persisted but ignored. Evaluation and checkpoint frequency are controllable via evalStrategy*/evalSteps*, saveStrategy*/saveSteps*, and checkpointsNumber* (save_total_limit). |
Example
const result = await client.finetuning.startTraining('agent-id');
cancelTraining
Cancel a running fine-tuning job
async cancelTraining(trainingLogId: string): Promise<
Endpoint: POST /cancel/{id} · Fine-Tuning service
Example
const result = await client.finetuning.cancelTraining('agent-id');
downloadDataset
Get a presigned download URL for a job's generated dataset
async downloadDataset(
trainingLogId: string,
which: 'dataset' | 'test' = 'dataset'
)
Endpoint: GET /dataset/{id} · Fine-Tuning service
Example
const result = await client.finetuning.downloadDataset('agent-id');
listAdapters
List completed LoRA adapters for the workspace (adapter registry)
async listAdapters(
options: {
baseModel?: string;
limit?: number;
nextToken?: string;
} = {}
)
Endpoint: GET /adapters · Fine-Tuning service
Example
const result = await client.finetuning.listAdapters();
createAdapterVersion
Snapshot a completed adapter as an immutable version (vN)
async createAdapterVersion(trainingLogId: string, label?: string)
Endpoint: POST /adapters/{id}/version · Fine-Tuning service
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
label | string | no | Optional human-readable label for this version (e.g. "best-held-out", "promoted-2026-07"). |
Response fields
| Field | Type | Description |
|---|---|---|
adapter_id | string | Training log ID of the snapshotted adapter |
version | integer | The version number assigned (1, 2, 3, …) |
snapshot | object | The immutable version record written to the manifest |
manifest_key | string | S3 key of the manifest storing this adapter's versions |
Example
const result = await client.finetuning.createAdapterVersion('agent-id');
rollbackAdapter
Get presigned artefacts to roll back to a pinned adapter version The Chat inference layer performs the actual served-adapter swap; this endpoint returns the pinned version's weights + config URLs.
async rollbackAdapter(trainingLogId: string, version?: number)
Endpoint: POST /adapters/{id}/rollback · Fine-Tuning service
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
version | integer | no | Version number to roll back to (from a prior /version call). Omit to use the latest snapshot. |
Response fields
| Field | Type | Description |
|---|---|---|
adapter_id | string | Training log ID the rollback was requested on |
rolled_back_to | integer | The version that was resolved (explicit version or latest); null when the latest snapshot was used implicitly |
target_adapter_id | string | The training log ID whose S3 prefix holds the target weights. May differ from adapter_id when rolling back along a parent-adapter lineage (a snapshot taken from a different completed job). |
weights_url | string | Presigned URL (valid 1h) to the pinned adapter_model.safetensors |
config_url | string | Presigned URL (valid 1h) to the pinned adapter_config.json, or null if the config file is absent in S3 |
base_model | string | Base model of the resolved snapshot (from the manifest, falling back to the training meta) |
inference_template | string | Inference chat-template key to use for serving this base model |
note | string | Explains that the inference switch is performed by the Chat routing layer; this endpoint only returns the pinned adapter artefacts. |
available_versions | array<integer> | Present only in the 404 response body (not on 200) when the requested version was not found — lists all known version numbers to aid retry. Returned here for reference. |
Example
const result = await client.finetuning.rollbackAdapter('agent-id');
getServing
Get the serving config and live lane state for a fine-tuned model
async getServing(trainingLogId: string)
Endpoint: GET /serving/{id} · Fine-Tuning service
Response fields
| Field | Type | Description |
|---|---|---|
modelId | string | The fine-tuned model's API name (usable as model on chat-completions) |
trainingLogId | string | Training log ID that produced this fine-tuned model |
base_model | string | Trainable base the model was fine-tuned from |
inference_base | string | Canonical checkpoint the lane serves |
mode | string | Current serving mode |
Allowed: on-demand, scheduled, always |
| schedule | object | A recurring warm window in the given IANA timezone, or, for maximum flexibility, a cron rule. end must be later than start (overnight windows are not supported). If cron is set it takes precedence over the days/start/end window. |
| lane | object | Live lane state for the fine-tuned model's inference lane. |
| warm_seconds_accrued | integer | Warm seconds accrued in the current billing day |
| warm_seconds_note | string | Billing note: warm hours bill daily in 1-hour units (minimum 1) at the size-tier hourly rate |
Example
const result = await client.finetuning.getServing('agent-id');
setServing
Set the serving mode for a fine-tuned model ~15 min idle), 'scheduled' (warm inside recurring windows) or 'always' (kept warm continuously) 'mon'..'sun' or ['everyday']), start/end as 'HH:MM', and an IANA timezone
async setServing(
trainingLogId: string,
mode: 'on-demand' | 'scheduled' | 'always' = 'on-demand',
schedule?: Record<string, any>
)
Endpoint: POST /serving/{id} · Fine-Tuning service
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | no | on-demand (default when omitted — wakes on first request, sleeps after ~15 min idle, $0 while idle), scheduled (warm inside recurring time windows), or always (kept warm continuously). |
Allowed: on-demand, scheduled, always |
| schedule | object | no | A recurring warm window in the given IANA timezone, or, for maximum flexibility, a cron rule. end must be later than start (overnight windows are not supported). If cron is set it takes precedence over the days/start/end window. |
Response fields
| Field | Type | Description |
|---|---|---|
modelId | string | The fine-tuned model's API name (usable as model on chat-completions) |
trainingLogId | string | Training log ID that produced this fine-tuned model |
mode | string | The stored serving mode |
Allowed: on-demand, scheduled, always |
| schedule | object | A recurring warm window in the given IANA timezone, or, for maximum flexibility, a cron rule. end must be later than start (overnight windows are not supported). If cron is set it takes precedence over the days/start/end window. |
| mirrored_to_training_log | boolean | Whether the config was also mirrored onto the TrainingLog entity (inside trainingMeta) |
| note | string | scheduled/always modes take effect within ~2 minutes (the serving monitor picks up the change) |
Example
const result = await client.finetuning.setServing('agent-id');
servingPower
Turn a fine-tuned model on or off right now state='on' wakes and holds the lane warm for hours (minimum 1); state='off' releases the hold.
async servingPower(trainingLogId: string, state: 'on' | 'off', hours?: number)
Endpoint: POST /serving/{id}/power · Fine-Tuning service
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
state | string | yes | on = wake and hold warm for hours; off = release the hold now |
Allowed: on, off |
| hours | integer | no | Hours to hold the lane warm (minimum 1, 1-hour billing units) |
Response fields
| Field | Type | Description |
|---|---|---|
modelId | string | The fine-tuned model's API name |
trainingLogId | string | Training log ID that produced this fine-tuned model |
state | string | The power state applied |
Allowed: on, off |
| hours | integer | Hours booked (0 for off) |
| lane | object | Lane result returned by the serving power endpoint. With state: on, the orchestrator returns the lane's status plus pinned_until (epoch seconds the lane is held warm until). With state: off, it returns status: unpinned and the lane idles out per normal rules (up to 15 min grace). |
| billing_note | string | Warm hours accrue while held and bill daily in 1-hour units (minimum 1) |
Example
const result = await client.finetuning.servingPower('agent-id', …);