diff --git a/packages/commands/src/commands/dataset/delete.ts b/packages/commands/src/commands/dataset/delete.ts index e8e5427..5e18766 100644 --- a/packages/commands/src/commands/dataset/delete.ts +++ b/packages/commands/src/commands/dataset/delete.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, deleteDataset, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const DELETE_FLAGS = { fileId: { @@ -30,6 +30,7 @@ export default defineCommand({ if (settings.quiet || format === "text") { emitBare(`Deleted ${fileId}.`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/dataset/get.ts b/packages/commands/src/commands/dataset/get.ts index f64080d..2c1cf71 100644 --- a/packages/commands/src/commands/dataset/get.ts +++ b/packages/commands/src/commands/dataset/get.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, getDataset, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const GET_FLAGS = { fileId: { @@ -46,7 +46,7 @@ export default defineCommand({ }; if (format === "json") { - emitResult(item, format); + emitResult({ ...item, request_id: response.request_id }, format); return; } @@ -58,5 +58,6 @@ export default defineCommand({ if (item.purpose) emitBare(`purpose: ${item.purpose}`); if (item.created_at) emitBare(`created_at: ${item.created_at}`); if (item.description) emitBare(`description: ${item.description}`); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/dataset/list.ts b/packages/commands/src/commands/dataset/list.ts index a34e64e..7bc858b 100644 --- a/packages/commands/src/commands/dataset/list.ts +++ b/packages/commands/src/commands/dataset/list.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, listDatasets, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare, formatTable } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId, formatTable } from "bailian-cli-runtime"; const LIST_FLAGS = { page: { type: "number", valueHint: "", description: "Page number (default: 1)" }, @@ -55,7 +55,7 @@ export default defineCommand({ })); if (format === "json") { - emitResult({ items, total }, format); + emitResult({ items, total, request_id: response.request_id }, format); return; } @@ -68,5 +68,6 @@ export default defineCommand({ const rows = items.map((i) => [i.file_id, i.name, i.size, i.purpose]); for (const line of formatTable(headers, rows)) emitBare(line); if (total !== undefined) emitBare(`\nTotal: ${total}`); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/dataset/upload.ts b/packages/commands/src/commands/dataset/upload.ts index f7d805b..a3c6104 100644 --- a/packages/commands/src/commands/dataset/upload.ts +++ b/packages/commands/src/commands/dataset/upload.ts @@ -9,10 +9,9 @@ import { MAX_MEDIA_ZIP_BYTES, BailianError, ExitCode, - type DatasetFile, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const UPLOAD_FLAGS = { file: { @@ -135,17 +134,19 @@ export default defineCommand({ return; } - const uploaded: DatasetFile = await uploadDataset(ctx.client, { + const uploaded = await uploadDataset(ctx.client, { filePath, purpose, }); + const { request_id, ...file } = uploaded; if (settings.quiet) { - emitBare(uploaded.file_id); + emitBare(file.file_id); } else if (format === "text") { - emitBare(`Uploaded ${uploaded.name} → file_id=${uploaded.file_id}`); + emitBare(`Uploaded ${file.name} → file_id=${file.file_id}`); + emitRequestId(request_id, settings.quiet); } else { - emitResult(uploaded, format); + emitResult({ ...file, request_id }, format); } }, }); diff --git a/packages/commands/src/commands/deploy/create.ts b/packages/commands/src/commands/deploy/create.ts index 60e1857..96c75d9 100644 --- a/packages/commands/src/commands/deploy/create.ts +++ b/packages/commands/src/commands/deploy/create.ts @@ -11,7 +11,7 @@ import { type CommandContext, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const CREATE_FLAGS = { model: { @@ -163,6 +163,7 @@ async function runCreate( emitBare( `\nNext: track readiness with: ${identity.binName} deploy get --deployed-model ${deployment?.deployed_model ?? ""}`, ); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/deploy/delete.ts b/packages/commands/src/commands/deploy/delete.ts index 8340d09..bd6dd85 100644 --- a/packages/commands/src/commands/deploy/delete.ts +++ b/packages/commands/src/commands/deploy/delete.ts @@ -7,7 +7,7 @@ import { ExitCode, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const DELETE_FLAGS = { deployedModel: { @@ -71,6 +71,7 @@ export default defineCommand({ emitBare(deployedModel); } else if (format === "text") { emitBare(`Deleted ${deployedModel}.`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/deploy/get.ts b/packages/commands/src/commands/deploy/get.ts index e8f6040..9c53e96 100644 --- a/packages/commands/src/commands/deploy/get.ts +++ b/packages/commands/src/commands/deploy/get.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, getDeployment, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const GET_FLAGS = { deployedModel: { @@ -58,7 +58,7 @@ export default defineCommand({ if (deployment.gmt_modified) item.updated_at = deployment.gmt_modified; if (format === "json") { - emitResult(item, format); + emitResult({ ...item, request_id: response.request_id }, format); return; } @@ -69,5 +69,6 @@ export default defineCommand({ const display = typeof value === "string" ? value : JSON.stringify(value); emitBare(`${label(key)}${display}`); } + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/deploy/list.ts b/packages/commands/src/commands/deploy/list.ts index d26b4e3..e7c2917 100644 --- a/packages/commands/src/commands/deploy/list.ts +++ b/packages/commands/src/commands/deploy/list.ts @@ -4,7 +4,7 @@ import { listDeployments, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare, formatTable } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId, formatTable } from "bailian-cli-runtime"; const LIST_FLAGS = { page: { type: "number", valueHint: "", description: "Page number (default: 1)" }, @@ -58,7 +58,7 @@ export default defineCommand({ })); if (format === "json") { - emitResult({ items, total }, format); + emitResult({ items, total, request_id: response.request_id }, format); return; } @@ -78,5 +78,6 @@ export default defineCommand({ ]); for (const line of formatTable(headers, rows)) emitBare(line); if (total !== undefined) emitBare(`\nTotal: ${total}`); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/deploy/models.ts b/packages/commands/src/commands/deploy/models.ts index 6bc8daa..d1ea972 100644 --- a/packages/commands/src/commands/deploy/models.ts +++ b/packages/commands/src/commands/deploy/models.ts @@ -4,7 +4,7 @@ import { listDeployableModels, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare, formatTable } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId, formatTable } from "bailian-cli-runtime"; const MODELS_FLAGS = { page: { type: "number", valueHint: "", description: "Page number (default: 1)" }, @@ -122,7 +122,7 @@ export default defineCommand({ } return out; }); - emitResult({ items, total }, format); + emitResult({ items, total, request_id: response.request_id }, format); return; } @@ -168,5 +168,6 @@ export default defineCommand({ ]); for (const line of formatTable(headers, rows)) emitBare(line); if (total !== undefined) emitBare(`\nTotal: ${total}`); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/deploy/scale.ts b/packages/commands/src/commands/deploy/scale.ts index d6d731b..805f9c5 100644 --- a/packages/commands/src/commands/deploy/scale.ts +++ b/packages/commands/src/commands/deploy/scale.ts @@ -4,7 +4,7 @@ import { scaleDeployment, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const SCALE_FLAGS = { deployedModel: { @@ -72,6 +72,7 @@ export default defineCommand({ } else if (format === "text") { const cap = deployment?.capacity !== undefined ? ` (capacity=${deployment.capacity})` : ""; emitBare(`Scaled ${deployedModel}${cap}.`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/deploy/update.ts b/packages/commands/src/commands/deploy/update.ts index fd582c9..0bbb29d 100644 --- a/packages/commands/src/commands/deploy/update.ts +++ b/packages/commands/src/commands/deploy/update.ts @@ -4,7 +4,7 @@ import { updateDeployment, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const UPDATE_FLAGS = { deployedModel: { @@ -70,6 +70,7 @@ export default defineCommand({ if (deployment?.tpm_limit !== undefined) parts.push(`tpm_limit=${deployment.tpm_limit}`); const summary = parts.length ? ` (${parts.join(", ")})` : ""; emitBare(`Updated ${deployedModel}${summary}.`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/finetune/cancel.ts b/packages/commands/src/commands/finetune/cancel.ts index bc511ad..789a3b0 100644 --- a/packages/commands/src/commands/finetune/cancel.ts +++ b/packages/commands/src/commands/finetune/cancel.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, cancelFineTune, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const CANCEL_FLAGS = { jobId: { @@ -38,6 +38,7 @@ export default defineCommand({ } else if (format === "text") { const status = job?.status ? ` (status=${job.status})` : ""; emitBare(`Cancelled ${jobId}${status}.`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/finetune/checkpoints.ts b/packages/commands/src/commands/finetune/checkpoints.ts index ca11000..7c05a36 100644 --- a/packages/commands/src/commands/finetune/checkpoints.ts +++ b/packages/commands/src/commands/finetune/checkpoints.ts @@ -4,7 +4,7 @@ import { listCheckpoints, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare, formatTable } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId, formatTable } from "bailian-cli-runtime"; const CHECKPOINTS_FLAGS = { jobId: { @@ -47,7 +47,7 @@ export default defineCommand({ })); if (format === "json") { - emitResult({ items, total }, format); + emitResult({ items, total, request_id: response.request_id }, format); return; } @@ -60,5 +60,6 @@ export default defineCommand({ const rows = items.map((i) => [i.checkpoint, i.step, i.status]); for (const line of formatTable(headers, rows)) emitBare(line); emitBare(`\nTotal: ${total}`); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/finetune/create.ts b/packages/commands/src/commands/finetune/create.ts index 8e72375..6fbb54f 100644 --- a/packages/commands/src/commands/finetune/create.ts +++ b/packages/commands/src/commands/finetune/create.ts @@ -27,7 +27,7 @@ import { } from "bailian-cli-core"; import { existsSync, statSync } from "fs"; import { basename } from "path"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; /** * A `--datasets` / `--validations` token is treated as a local file to upload @@ -631,6 +631,7 @@ async function runCreate( if (job?.job_id) { emitBare(`Created fine-tune job: ${job.job_id}`); if (job.status) emitBare(`Status: ${job.status}`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/finetune/delete.ts b/packages/commands/src/commands/finetune/delete.ts index f5ab6fc..102fda6 100644 --- a/packages/commands/src/commands/finetune/delete.ts +++ b/packages/commands/src/commands/finetune/delete.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, deleteFineTune, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const DELETE_FLAGS = { jobId: { @@ -36,6 +36,7 @@ export default defineCommand({ emitBare(jobId); } else if (format === "text") { emitBare(`Deleted ${jobId}.`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/finetune/export.ts b/packages/commands/src/commands/finetune/export.ts index 7f3857e..7e52de0 100644 --- a/packages/commands/src/commands/finetune/export.ts +++ b/packages/commands/src/commands/finetune/export.ts @@ -4,7 +4,7 @@ import { exportCheckpoint, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const EXPORT_FLAGS = { jobId: { @@ -69,6 +69,7 @@ export default defineCommand({ emitBare( `Next: ${identity.binName} deploy text create --model ${exported} --name `, ); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/finetune/get.ts b/packages/commands/src/commands/finetune/get.ts index d661c79..0ba0114 100644 --- a/packages/commands/src/commands/finetune/get.ts +++ b/packages/commands/src/commands/finetune/get.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, getFineTune, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const GET_FLAGS = { jobId: { @@ -56,7 +56,7 @@ export default defineCommand({ }; if (format === "json") { - emitResult(item, format); + emitResult({ ...item, request_id: response.request_id }, format); return; } @@ -76,5 +76,6 @@ export default defineCommand({ if (item.model_name) emitBare(`model_name: ${item.model_name}`); if (item.created_at) emitBare(`created_at: ${item.created_at}`); if (item.updated_at) emitBare(`updated_at: ${item.updated_at}`); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/finetune/list.ts b/packages/commands/src/commands/finetune/list.ts index d8d822d..ca4eddd 100644 --- a/packages/commands/src/commands/finetune/list.ts +++ b/packages/commands/src/commands/finetune/list.ts @@ -1,5 +1,5 @@ import { defineCommand, detectOutputFormat, listFineTunes, type FlagsDef } from "bailian-cli-core"; -import { emitResult, emitBare, formatTable } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId, formatTable } from "bailian-cli-runtime"; const LIST_FLAGS = { page: { type: "number", valueHint: "", description: "Page number (default: 1)" }, @@ -48,7 +48,7 @@ export default defineCommand({ })); if (format === "json") { - emitResult({ items, total }, format); + emitResult({ items, total, request_id: response.request_id }, format); return; } @@ -78,5 +78,6 @@ export default defineCommand({ emitBare( `Tip: OUTPUT_MODEL is the input for \`${identity.binName} deploy text create --model\``, ); + emitRequestId(response.request_id, settings.quiet); }, }); diff --git a/packages/commands/src/commands/finetune/logs.ts b/packages/commands/src/commands/finetune/logs.ts index 322327b..bd0802e 100644 --- a/packages/commands/src/commands/finetune/logs.ts +++ b/packages/commands/src/commands/finetune/logs.ts @@ -6,7 +6,7 @@ import { type FineTuneLogEntry, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; /** * Render a single log entry as a single line (mirrors the flatten logic used @@ -187,6 +187,7 @@ export default defineCommand({ emitBare(renderEntry(entry)); } if (payload?.total !== undefined) emitBare(`\nTotal: ${payload.total}`); + emitRequestId(response.request_id, settings.quiet); } else { emitResult(response, format); } diff --git a/packages/commands/src/commands/finetune/watch.ts b/packages/commands/src/commands/finetune/watch.ts index 1eb589a..c02b207 100644 --- a/packages/commands/src/commands/finetune/watch.ts +++ b/packages/commands/src/commands/finetune/watch.ts @@ -6,7 +6,7 @@ import { ExitCode, type FlagsDef, } from "bailian-cli-core"; -import { emitResult, emitBare } from "bailian-cli-runtime"; +import { emitResult, emitBare, emitRequestId } from "bailian-cli-runtime"; const DEFAULT_INTERVAL_SEC = 10; const MIN_INTERVAL_SEC = 1; @@ -135,9 +135,13 @@ export default defineCommand({ } else if (format === "text") { emitBare(`${nowStamp()} ${jobId} ${status || "UNKNOWN"}`); if (status === "SUCCEEDED") emitBare(`✓ ${jobId} ${status}`); + emitRequestId(response.request_id, settings.quiet); } else { // json: a compact, purpose-built status probe. - emitResult({ job_id: jobId, status: status || "UNKNOWN", terminal }, format); + emitResult( + { job_id: jobId, status: status || "UNKNOWN", terminal, request_id: response.request_id }, + format, + ); } if (terminal && status !== "SUCCEEDED") { @@ -175,6 +179,7 @@ export default defineCommand({ emitResult(response, format); } else if (status === "SUCCEEDED") { emitBare(`\n✓ ${jobId} ${status} (elapsed ${formatElapsed(elapsed)})`); + emitRequestId(response.request_id, settings.quiet); } if (status !== "SUCCEEDED") { throw new BailianError( diff --git a/packages/core/src/dataset/api.ts b/packages/core/src/dataset/api.ts index 8bb9d51..c7cb1d6 100644 --- a/packages/core/src/dataset/api.ts +++ b/packages/core/src/dataset/api.ts @@ -47,7 +47,7 @@ export interface DatasetUploadParams { export async function uploadDataset( client: Client, params: DatasetUploadParams, -): Promise { +): Promise { const { filePath, purpose = "fine-tune", signal } = params; const stat = statSync(filePath); const fileName = basename(filePath); @@ -75,6 +75,7 @@ export async function uploadDataset( size: body.bytes ?? stat.size, purpose: body.purpose ?? purpose, gmt_create: body.created_at ? new Date(body.created_at * 1000).toISOString() : undefined, + request_id: body.request_id, }; } // No id in response → upload reported HTTP 200 but produced no usable record diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 83c1318..d8cadb9 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -40,7 +40,7 @@ export { } from "./urls.ts"; // Output facilities consumed by commands -export { emitResult, emitBare } from "./output/output.ts"; +export { emitResult, emitBare, emitRequestId } from "./output/output.ts"; export { formatTable } from "./output/table.ts"; export { renderBoxTable, type BoxTableOptions, type BarColumn } from "./output/box-table.ts"; export { createSpinner, createProgressBar } from "./output/progress.ts"; diff --git a/packages/runtime/src/output/output.ts b/packages/runtime/src/output/output.ts index 04c3037..9b6707f 100644 --- a/packages/runtime/src/output/output.ts +++ b/packages/runtime/src/output/output.ts @@ -16,3 +16,15 @@ export function emitResult(data: unknown, format: OutputFormat): void { export function emitBare(value: string): void { process.stdout.write(value + "\n"); } + +/** + * Surface a server request id for text-mode output. Written to stderr (the + * diagnostic channel) so it never corrupts the primary stdout result, mirroring + * the request_id line the verbose HTTP logger prints. No-op when the id is + * absent (e.g. dry-run) or in --quiet mode (which owes callers a bare scalar). + * JSON output surfaces request_id inside the payload instead of calling this. + */ +export function emitRequestId(requestId: string | undefined, quiet: boolean): void { + if (!requestId || quiet) return; + process.stderr.write(`request_id: ${requestId}\n`); +}