@fastino-ai/pioneer-cli 0.2.9 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +21 -12
  2. package/package.json +1 -1
  3. package/src/api.ts +108 -7
  4. package/src/index.tsx +1625 -711
package/README.md CHANGED
@@ -59,26 +59,37 @@ pioneer agent --mode research # Research mode (Pro subscri
59
59
  pioneer job list
60
60
  pioneer job get <id>
61
61
  pioneer job logs <id>
62
- pioneer job create --model-name "My Model" --dataset-ids ds_123,ds_456
62
+ pioneer job delete <id>
63
+ # To create a training job, use the agent — it will help you pick a base model
64
+ # and datasets conversationally:
65
+ pioneer agent
63
66
 
64
67
  # Models
65
- pioneer model endpoints list # List model catalog entries (/projects)
68
+ pioneer model base-models # List available base models (tabular)
69
+ pioneer model endpoints list # List model catalog entries
66
70
  pioneer model endpoints create # Create a model entry (interactive by default)
67
71
  pioneer model endpoints create --model "qwen/Qwen3-8B-Instruct" --repo https://github.com/fastino-ai/Pioneer
68
- pioneer model endpoints get <model-id>
72
+ pioneer model endpoints get <model-id> # Endpoint details (incl. attached dataset count)
69
73
  pioneer model endpoints update <model-id> --description "Updated model metadata"
70
74
  pioneer model endpoints delete <model-id>
71
- pioneer model endpoints dataset-count <model-id>
72
75
  pioneer model endpoints quality-metrics <model-id>
73
- pioneer model endpoints deploy <model-id> --job <training-job-id> [--reason "..." ]
76
+ pioneer model endpoints deploy <model-id> [--job <training-job-id>] [--reason "..." ] [--all]
77
+ # If --job is omitted, pick from a list of deployable jobs interactively.
78
+ # The list is filtered to jobs whose base model matches the endpoint; pass --all to bypass that filter.
74
79
  pioneer model endpoints rollback <model-id> <deployment-id>
75
80
 
76
81
  pioneer model artifacts list # List trained and deployed artifacts
77
82
  pioneer model artifacts trained # List trained artifacts
78
83
  pioneer model artifacts deployed # List deployed artifacts
79
- pioneer model artifacts download <job-id>
84
+ pioneer model artifacts download <job-id> # Get a signed download URL for the artifact
80
85
  pioneer model artifacts upload <job-id> --to hf --repo username/model # Push trained artifact to HF
81
86
 
87
+ # Datasets
88
+ pioneer dataset list # List remote + local datasets (tabular)
89
+ pioneer dataset get <name[:version]> # Dataset details (key/value layout)
90
+
91
+ # Most read commands also accept --json for the raw JSON payload.
92
+
82
93
  # Aliases
83
94
  pioneer model_endpoints list
84
95
  pioneer model_artifacts list
@@ -129,14 +140,12 @@ pioneer agent
129
140
 
130
141
  ### Step 3: Create a Training Job
131
142
 
132
- Start training with one or more datasets:
143
+ Use `pioneer agent` to create a training job. The agent will guide you through
144
+ picking a base model, selecting datasets, and configuring hyperparameters
145
+ without needing to remember flags or dataset IDs:
133
146
 
134
147
  ```bash
135
- pioneer job create \
136
- --model-name "Medical NER Model v1" \
137
- --dataset-ids "<dataset-id>" \
138
- --base-model "fastino/gliner2-base-v1" \
139
- --epochs 10
148
+ pioneer agent
140
149
  ```
141
150
 
142
151
  ### Step 4: Monitor Training Progress
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastino-ai/pioneer-cli",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "Pioneer CLI - AI training platform with chat agent",
5
5
  "type": "module",
6
6
  "files": [
package/src/api.ts CHANGED
@@ -1271,10 +1271,12 @@ export interface TrainingJobListResponse {
1271
1271
  }
1272
1272
 
1273
1273
  export async function listJobs(
1274
- options: { status?: string } = {}
1274
+ options: { status?: string; project_id?: string; limit?: number } = {}
1275
1275
  ): Promise<ApiResult<TrainingJobListResponse>> {
1276
1276
  const params = new URLSearchParams();
1277
1277
  if (options.status) params.set("status", options.status);
1278
+ if (options.project_id) params.set("project_id", options.project_id);
1279
+ if (options.limit !== undefined) params.set("limit", String(options.limit));
1278
1280
  const query = params.toString();
1279
1281
  const url = query ? `/felix/training-jobs?${query}` : "/felix/training-jobs";
1280
1282
  return request<TrainingJobListResponse>("GET", url);
@@ -1284,6 +1286,25 @@ export async function getJob(jobId: string): Promise<ApiResult<TrainingJob>> {
1284
1286
  return request<TrainingJob>("GET", `/felix/training-jobs/${jobId}`);
1285
1287
  }
1286
1288
 
1289
+ /**
1290
+ * Assign (or unassign) a training job to a project. The deploy endpoint
1291
+ * (`POST /projects/{id}/deployments`) requires the job's `project_id` to
1292
+ * match the target project, so callers typically PATCH this before deploy.
1293
+ *
1294
+ * @param jobId Training job UUID.
1295
+ * @param projectId Project UUID to attach to, or `null` to unassign.
1296
+ */
1297
+ export async function updateTrainingJob(
1298
+ jobId: string,
1299
+ body: { project_id: string | null }
1300
+ ): Promise<ApiResult<{ success?: boolean; message?: string }>> {
1301
+ return request<{ success?: boolean; message?: string }>(
1302
+ "PATCH",
1303
+ `/felix/training-jobs/${jobId}`,
1304
+ body
1305
+ );
1306
+ }
1307
+
1287
1308
  export interface TrainingJobCreateRequest {
1288
1309
  model_name: string;
1289
1310
  datasets: DatasetRef[];
@@ -1457,6 +1478,24 @@ export interface DeployedModelsListResponse {
1457
1478
  count: number;
1458
1479
  }
1459
1480
 
1481
+ interface AnthropicCompatibleModelEntry {
1482
+ id?: string;
1483
+ display_name?: string;
1484
+ type?: string;
1485
+ created_at?: string | null;
1486
+ created?: number;
1487
+ owned_by?: string;
1488
+ }
1489
+
1490
+ interface AnthropicCompatibleModelsResponse {
1491
+ data?: AnthropicCompatibleModelEntry[];
1492
+ }
1493
+
1494
+ function isLikelyJobId(value: unknown): value is string {
1495
+ if (typeof value !== "string") return false;
1496
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
1497
+ }
1498
+
1460
1499
  export async function listModels(
1461
1500
  options: { includeBase?: boolean } = {}
1462
1501
  ): Promise<ApiResult<DeployedModelsListResponse>> {
@@ -1465,8 +1504,49 @@ export async function listModels(
1465
1504
  params.set("include_base", String(options.includeBase));
1466
1505
  }
1467
1506
  const query = params.toString();
1468
- const url = query ? `/felix/models?${query}` : "/felix/models";
1469
- return request<DeployedModelsListResponse>("GET", url);
1507
+ const legacyUrl = query ? `/felix/models?${query}` : "/felix/models";
1508
+ const legacy = await request<DeployedModelsListResponse>("GET", legacyUrl);
1509
+ if (legacy.ok || legacy.status !== 404) {
1510
+ return legacy;
1511
+ }
1512
+
1513
+ // Backend removed /felix/models. Fall back to the canonical
1514
+ // Anthropic/OpenAI-compatible catalog and adapt to DeployedModel.
1515
+ const fallback = await request<AnthropicCompatibleModelsResponse>("GET", "/v1/models");
1516
+ if (!fallback.ok) {
1517
+ return {
1518
+ ok: false,
1519
+ status: fallback.status,
1520
+ error: fallback.error ?? "Failed to list deployed models.",
1521
+ };
1522
+ }
1523
+ const entries = fallback.data?.data ?? [];
1524
+ const models: DeployedModel[] = entries
1525
+ .filter((entry) => entry && (options.includeBase || entry.owned_by !== "anthropic"))
1526
+ .map((entry) => {
1527
+ const id = typeof entry.id === "string" ? entry.id : "";
1528
+ return {
1529
+ id,
1530
+ job_id: isLikelyJobId(id) ? id : null,
1531
+ model_name: entry.display_name || id || undefined,
1532
+ is_base_model: entry.owned_by === "anthropic" || entry.owned_by === "openai",
1533
+ deployed_at: entry.created_at ?? null,
1534
+ last_used_at: null,
1535
+ invocation_count: 0,
1536
+ created_at: entry.created_at ?? null,
1537
+ updated_at: entry.created_at ?? null,
1538
+ };
1539
+ });
1540
+
1541
+ return {
1542
+ ok: true,
1543
+ status: fallback.status,
1544
+ data: {
1545
+ success: true,
1546
+ models,
1547
+ count: models.length,
1548
+ },
1549
+ };
1470
1550
  }
1471
1551
 
1472
1552
  export async function deleteModel(jobId: string): Promise<ApiResult> {
@@ -1678,12 +1758,20 @@ export interface BaseModelInfo {
1678
1758
  id: string;
1679
1759
  name?: string;
1680
1760
  label?: string;
1681
- type?: "encoder" | "decoder" | string;
1761
+ /**
1762
+ * One of "encoder" | "decoder" — the architectural family of the model.
1763
+ * Note: backend used to expose this as `type`; the field is now `task_type`.
1764
+ */
1682
1765
  task_type?: string;
1683
1766
  supports_inference?: boolean;
1684
1767
  supports_on_demand_inference?: boolean;
1685
1768
  supports_training?: boolean;
1686
1769
  description?: string;
1770
+ tier?: "enterprise" | "open" | string;
1771
+ context_window?: number;
1772
+ license?: string;
1773
+ input_price_per_million?: number;
1774
+ output_price_per_million?: number;
1687
1775
  }
1688
1776
 
1689
1777
  export interface BaseModelsResponse {
@@ -2820,10 +2908,23 @@ export interface ProjectDeploymentCreate {
2820
2908
  }
2821
2909
 
2822
2910
  export interface ProjectDeploymentResponse {
2823
- success: boolean;
2824
- message?: string;
2911
+ /** Deployment record id. */
2912
+ id?: string;
2825
2913
  project_id?: string;
2826
- training_job_id?: string;
2914
+ /** Set when a fine-tuned checkpoint was deployed. */
2915
+ training_job_id?: string | null;
2916
+ /**
2917
+ * Set to the stock HuggingFace base model id when a base-model deploy was
2918
+ * performed. May also be populated for training-job deploys (post backend
2919
+ * enrichment) so the record always carries "what stock model is serving".
2920
+ */
2921
+ base_model?: string | null;
2922
+ deployed_by?: string;
2923
+ reason?: string;
2924
+ deployed_at?: string;
2925
+ // Legacy/optional fields kept for older response shapes.
2926
+ success?: boolean;
2927
+ message?: string;
2827
2928
  deployment_id?: string;
2828
2929
  }
2829
2930