bailian-cli-core 2.2.1 → 2.3.0
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.
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/index.d.mts +270 -5
- package/dist/index.mjs +25 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Internal SDK for [`bailian-cli`](https://www.npmjs.com/package/bailian-cli).
|
|
|
7
7
|
Not intended for direct use. For installation, usage, and documentation, see the CLI package:
|
|
8
8
|
|
|
9
9
|
- npm: <https://www.npmjs.com/package/bailian-cli>
|
|
10
|
-
- Homepage: <https://bailian.console.aliyun.com/cli?
|
|
10
|
+
- Homepage: <https://bailian.console.aliyun.com/cli?spm=a2ty07.github>
|
|
11
11
|
|
|
12
12
|
## License
|
|
13
13
|
|
package/README.zh.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1875,6 +1875,7 @@ export declare function refreshAccessToken(opts: {
|
|
|
1875
1875
|
//#region src/client/endpoints.d.ts
|
|
1876
1876
|
export declare function chatPath(): string;
|
|
1877
1877
|
export declare function responsesPath(): string;
|
|
1878
|
+
export declare function decisionPath(): string;
|
|
1878
1879
|
/** Async image API used by wan2.6-t2i / wan2.6-image (T2I) and similar message-format models. */
|
|
1879
1880
|
export declare function imagePath(): string;
|
|
1880
1881
|
/** Sync multimodal API (qwen-image / wan2.7-image / z-image generate; also wan2.6-image edit). */
|
|
@@ -1900,7 +1901,7 @@ export declare function speechVocabularyPath(): string;
|
|
|
1900
1901
|
export declare function profileSchemaPath(): string;
|
|
1901
1902
|
export declare function userProfilePath(schemaId: string): string;
|
|
1902
1903
|
export declare function knowledgeRetrievePath(): string;
|
|
1903
|
-
export declare function workspaceMaaSBaseUrl(workspaceId: string): string;
|
|
1904
|
+
export declare function workspaceMaaSBaseUrl(workspaceId: string, region?: string): string;
|
|
1904
1905
|
export declare function knowledgeSearchEndpoint(workspaceId: string): string;
|
|
1905
1906
|
export declare function knowledgeChatEndpoint(workspaceId: string): string;
|
|
1906
1907
|
/** Per-workspace AgentStudio host (same shape as {@link ragEndpoint}'s host). */
|
|
@@ -2423,6 +2424,14 @@ export declare function getApiKeyLoginKind(apiKey: string): ApiKeyLoginKind;
|
|
|
2423
2424
|
*/
|
|
2424
2425
|
export declare function normalizeModelBaseUrl(input: string): string;
|
|
2425
2426
|
//#endregion
|
|
2427
|
+
//#region src/config/validation.d.ts
|
|
2428
|
+
declare const TIMEOUT_ERROR_MESSAGE: {
|
|
2429
|
+
readonly "en-US": "Timeout must be a positive finite number.";
|
|
2430
|
+
readonly "zh-CN": "请求超时必须是一个有限的正数。";
|
|
2431
|
+
};
|
|
2432
|
+
/** Shared timeout constraint for effective settings and CLI flag validation. */
|
|
2433
|
+
export declare function validateTimeout(timeout: unknown): typeof TIMEOUT_ERROR_MESSAGE | undefined;
|
|
2434
|
+
//#endregion
|
|
2426
2435
|
//#region src/output/formatter.d.ts
|
|
2427
2436
|
type OutputFormat = "text" | "json";
|
|
2428
2437
|
export declare function detectOutputFormat(flagValue?: string): OutputFormat;
|
|
@@ -2442,6 +2451,7 @@ interface UploadOptions {
|
|
|
2442
2451
|
filePath: string;
|
|
2443
2452
|
identity: TrackingIdentity;
|
|
2444
2453
|
signal?: AbortSignal;
|
|
2454
|
+
timeout?: number;
|
|
2445
2455
|
}
|
|
2446
2456
|
/** Encode a local image as a Data URI. */
|
|
2447
2457
|
export declare function imageFileToDataUri(filePath: string): string;
|
|
@@ -2463,6 +2473,7 @@ export declare function isLocalFile(input: string): boolean;
|
|
|
2463
2473
|
export declare function resolveFileUrl(input: string, apiKey: string, model: string, opts: {
|
|
2464
2474
|
identity: TrackingIdentity;
|
|
2465
2475
|
signal?: AbortSignal;
|
|
2476
|
+
timeout?: number;
|
|
2466
2477
|
}): Promise<string>;
|
|
2467
2478
|
//#endregion
|
|
2468
2479
|
//#region src/dataset/types.d.ts
|
|
@@ -2619,9 +2630,11 @@ interface ValidateOpts {
|
|
|
2619
2630
|
* Every record MUST carry `chosen` + `rejected`.
|
|
2620
2631
|
* - `"cpt"` — `{text: "..."}` (continual pre-training). Raw text only,
|
|
2621
2632
|
* no `messages[]`.
|
|
2622
|
-
* - `
|
|
2623
|
-
*
|
|
2624
|
-
*
|
|
2633
|
+
* - `"decision"` — `{state:{content}, questions:{...}}`(决策模型训练数据)。
|
|
2634
|
+
* - `undefined` — auto-detect per record: a record with `state`/`questions`
|
|
2635
|
+
* is validated as decision data, one with `chosen` or
|
|
2636
|
+
* `rejected` as DPO, one with `text` (and no `messages`) as
|
|
2637
|
+
* CPT, otherwise as ChatML.
|
|
2625
2638
|
* `finetune create` sets this from `--training-type` (dpo* → "dpo",
|
|
2626
2639
|
* cpt → "cpt") so a malformed dataset fails at validate time, not on the
|
|
2627
2640
|
* platform ten minutes in.
|
|
@@ -2635,7 +2648,7 @@ interface ValidateOpts {
|
|
|
2635
2648
|
model?: string;
|
|
2636
2649
|
}
|
|
2637
2650
|
/** The schemas a `.jsonl` record can be validated against. */
|
|
2638
|
-
type DatasetSchema = "chatml" | "dpo" | "cpt" | "tts" | "image" | "video";
|
|
2651
|
+
type DatasetSchema = "chatml" | "dpo" | "cpt" | "decision" | "tts" | "image" | "video";
|
|
2639
2652
|
type ValidationSeverity = "error" | "warning";
|
|
2640
2653
|
interface ValidationIssue {
|
|
2641
2654
|
severity: ValidationSeverity;
|
|
@@ -2775,6 +2788,8 @@ export declare const MAX_DATASET_BYTES: number;
|
|
|
2775
2788
|
* CPT requires at least 50M tokens; larger files are expected.
|
|
2776
2789
|
*/
|
|
2777
2790
|
export declare const MAX_CPT_BYTES: number;
|
|
2791
|
+
/** 决策模型训练数据单文件上限,按平台文档为 300MB。 */
|
|
2792
|
+
export declare const MAX_DECISION_DATASET_BYTES: number;
|
|
2778
2793
|
/**
|
|
2779
2794
|
* Image / video ZIP size cap — 2 GB per the platform docs. Used by
|
|
2780
2795
|
* `bl dataset upload` for media schemas and by the `sft-lora` training
|
|
@@ -2799,6 +2814,90 @@ export declare function parseDatasetSchemaFlag(value: string | undefined): Datas
|
|
|
2799
2814
|
*/
|
|
2800
2815
|
export declare function formatIssue(issue: ValidationIssue): string;
|
|
2801
2816
|
//#endregion
|
|
2817
|
+
//#region src/decision/questions.d.ts
|
|
2818
|
+
/**
|
|
2819
|
+
* 决策模型(TypeSafe System One)问题定义与 state 的结构校验。
|
|
2820
|
+
*
|
|
2821
|
+
* 推理请求(`bl decision`)与训练数据校验(`decision` record schema)共用这里的
|
|
2822
|
+
* 规则;训练侧在此之上再校验 `label` / `target`。规则以决策模型 API 文档为准:
|
|
2823
|
+
* - state:非空字符串、对象或数组;
|
|
2824
|
+
* - instructions:可选字符串;
|
|
2825
|
+
* - choice.criteria:选项名 → 描述,1–255 项;
|
|
2826
|
+
* - score.criteria:从低到高的等级描述数组,2–255 级;
|
|
2827
|
+
* - noul.criteria:可选,只能包含 `true` / `false` 描述。
|
|
2828
|
+
*/
|
|
2829
|
+
export declare const DECISION_QUESTION_TYPES: readonly ["choice", "noul", "score"];
|
|
2830
|
+
export type DecisionQuestionType = (typeof DECISION_QUESTION_TYPES)[number];
|
|
2831
|
+
export declare const MAX_DECISION_CHOICE_OPTIONS = 255;
|
|
2832
|
+
export declare const MIN_DECISION_SCORE_LEVELS = 2;
|
|
2833
|
+
export declare const MAX_DECISION_SCORE_LEVELS = 255;
|
|
2834
|
+
export interface DecisionIssue {
|
|
2835
|
+
code: string;
|
|
2836
|
+
/** 双语文案:命令层用 `ctx.localize` 渲染,训练校验拼成 `英文 / 中文`。 */
|
|
2837
|
+
message: {
|
|
2838
|
+
readonly "en-US": string;
|
|
2839
|
+
readonly "zh-CN": string;
|
|
2840
|
+
};
|
|
2841
|
+
path: string;
|
|
2842
|
+
}
|
|
2843
|
+
export declare function isDecisionObject(value: unknown): value is Record<string, unknown>;
|
|
2844
|
+
export declare function inspectDecisionState(state: unknown, path?: string): DecisionIssue[];
|
|
2845
|
+
/** 校验单个问题定义(不含训练专用的 label / target)。 */
|
|
2846
|
+
export declare function inspectDecisionQuestion(question: unknown, path: string): DecisionIssue[];
|
|
2847
|
+
/** 校验问题表本身是否为非空对象。 */
|
|
2848
|
+
export declare function inspectDecisionQuestionTable(questions: unknown, path?: string): DecisionIssue[];
|
|
2849
|
+
export declare function inspectDecisionQuestionId(questionId: string, path?: string): DecisionIssue[];
|
|
2850
|
+
/** 校验完整问题表:表结构、每个问题 ID 与问题定义。 */
|
|
2851
|
+
export declare function inspectDecisionQuestions(questions: unknown, path?: string): DecisionIssue[];
|
|
2852
|
+
//#endregion
|
|
2853
|
+
//#region src/decision/request.d.ts
|
|
2854
|
+
export declare const DEFAULT_DECISION_MODEL = "decision-model-preview";
|
|
2855
|
+
/** 决策模型开放的 workspace 域名地域。 */
|
|
2856
|
+
export declare const DECISION_REGIONS: readonly ["cn-beijing", "ap-southeast-1"];
|
|
2857
|
+
export type DecisionRegion = (typeof DECISION_REGIONS)[number];
|
|
2858
|
+
export declare const DEFAULT_DECISION_REGION: DecisionRegion;
|
|
2859
|
+
export type DecisionState = string | Record<string, unknown> | unknown[];
|
|
2860
|
+
export interface DecisionQuestion {
|
|
2861
|
+
type: DecisionQuestionType;
|
|
2862
|
+
instructions?: string;
|
|
2863
|
+
criteria?: Record<string, string> | string[];
|
|
2864
|
+
[key: string]: unknown;
|
|
2865
|
+
}
|
|
2866
|
+
export interface DecisionRequest {
|
|
2867
|
+
model: string;
|
|
2868
|
+
state: DecisionState;
|
|
2869
|
+
questions: Record<string, DecisionQuestion>;
|
|
2870
|
+
}
|
|
2871
|
+
export interface DecisionAnswer {
|
|
2872
|
+
type?: string;
|
|
2873
|
+
choice?: string;
|
|
2874
|
+
noul?: number;
|
|
2875
|
+
score?: number;
|
|
2876
|
+
confidence?: number;
|
|
2877
|
+
probabilities?: Record<string, number>;
|
|
2878
|
+
legend?: Record<string, string>;
|
|
2879
|
+
[key: string]: unknown;
|
|
2880
|
+
}
|
|
2881
|
+
export interface DecisionResponse {
|
|
2882
|
+
model?: string;
|
|
2883
|
+
request_id?: string;
|
|
2884
|
+
answers?: Record<string, DecisionAnswer>;
|
|
2885
|
+
usage?: {
|
|
2886
|
+
input_tokens?: number;
|
|
2887
|
+
[key: string]: unknown;
|
|
2888
|
+
};
|
|
2889
|
+
latency_ms?: number;
|
|
2890
|
+
[key: string]: unknown;
|
|
2891
|
+
}
|
|
2892
|
+
/**
|
|
2893
|
+
* 兼容两种问题文件:裸问题表 `{ id: {...} }`,或外层包了一层的 `{ "questions": {...} }`
|
|
2894
|
+
* (如示例包里的 workload.json / 训练样本)。当 `questions` 本身像一个问题定义
|
|
2895
|
+
* (带字符串 `type`)时,视为 ID 恰好叫 "questions" 的裸问题表,不做解包。
|
|
2896
|
+
*/
|
|
2897
|
+
export declare function unwrapDecisionQuestions(parsed: unknown): unknown;
|
|
2898
|
+
/** 去掉每个问题上的训练字段(label / target),返回新对象,不修改入参。 */
|
|
2899
|
+
export declare function stripDecisionTrainingFields(questions: unknown): unknown;
|
|
2900
|
+
//#endregion
|
|
2802
2901
|
//#region src/finetune/types.d.ts
|
|
2803
2902
|
/**
|
|
2804
2903
|
* Fine-tune job API types.
|
|
@@ -2993,6 +3092,126 @@ export interface GetFineTuneResponse {
|
|
|
2993
3092
|
output?: FineTuneJob;
|
|
2994
3093
|
data?: FineTuneJob;
|
|
2995
3094
|
}
|
|
3095
|
+
/** A tunable hyper-parameter declared by a compression template. */
|
|
3096
|
+
export interface CompressHyperParameter {
|
|
3097
|
+
name?: string;
|
|
3098
|
+
/** `number` (data_range / step) or `string` (support_values). */
|
|
3099
|
+
type?: string;
|
|
3100
|
+
display_name?: string;
|
|
3101
|
+
description?: string;
|
|
3102
|
+
defaultValue?: string;
|
|
3103
|
+
recommend_value?: string;
|
|
3104
|
+
required?: boolean;
|
|
3105
|
+
support_values?: string[];
|
|
3106
|
+
data_range?: string[];
|
|
3107
|
+
step?: number;
|
|
3108
|
+
[k: string]: unknown;
|
|
3109
|
+
}
|
|
3110
|
+
/** A compression template bound to a quantizable model. */
|
|
3111
|
+
export interface CompressTemplate {
|
|
3112
|
+
template_id?: string;
|
|
3113
|
+
template_name?: string;
|
|
3114
|
+
description?: string;
|
|
3115
|
+
/** Currently always `quantization`. */
|
|
3116
|
+
compress_type?: string;
|
|
3117
|
+
hyper_parameters?: CompressHyperParameter[];
|
|
3118
|
+
[k: string]: unknown;
|
|
3119
|
+
}
|
|
3120
|
+
/** A quantizable custom model and the templates it supports. */
|
|
3121
|
+
export interface CompressModel {
|
|
3122
|
+
model?: string;
|
|
3123
|
+
model_name?: string;
|
|
3124
|
+
base_model?: string;
|
|
3125
|
+
templates?: CompressTemplate[];
|
|
3126
|
+
[k: string]: unknown;
|
|
3127
|
+
}
|
|
3128
|
+
/** GET /api/v1/fine-tunes/compress/templates response. */
|
|
3129
|
+
export interface ListCompressTemplatesResponse {
|
|
3130
|
+
request_id?: string;
|
|
3131
|
+
output?: {
|
|
3132
|
+
base_models?: string[];
|
|
3133
|
+
custom_models?: CompressModel[];
|
|
3134
|
+
[k: string]: unknown;
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
/** POST /api/v1/fine-tunes/compress/jobs request body. */
|
|
3138
|
+
export interface CreateCompressJobRequest {
|
|
3139
|
+
/** Source custom (full-parameter fine-tuned) model ID. */
|
|
3140
|
+
model: string;
|
|
3141
|
+
template_id: string;
|
|
3142
|
+
job_name?: string;
|
|
3143
|
+
job_description?: string;
|
|
3144
|
+
/** Key-value overrides; only the keys to override. */
|
|
3145
|
+
hyper_parameters?: Record<string, unknown>;
|
|
3146
|
+
/** Calibration dataset file IDs; only effective when `calib_input=true`. */
|
|
3147
|
+
custom_calibration_file_ids?: string[];
|
|
3148
|
+
/** Output model name suffix (≤ 8 chars, lowercase letters and digits). */
|
|
3149
|
+
output_model_suffix?: string;
|
|
3150
|
+
}
|
|
3151
|
+
/** A compression job record as returned by the platform. */
|
|
3152
|
+
export interface CompressJob {
|
|
3153
|
+
job_id?: string;
|
|
3154
|
+
job_name?: string;
|
|
3155
|
+
job_description?: string;
|
|
3156
|
+
/** PENDING | QUEUING | RUNNING | CANCELING | SUCCEEDED | FAILED | CANCELED */
|
|
3157
|
+
status?: string;
|
|
3158
|
+
model?: string;
|
|
3159
|
+
base_model?: string;
|
|
3160
|
+
template_id?: string;
|
|
3161
|
+
template_name?: string;
|
|
3162
|
+
template_description?: string;
|
|
3163
|
+
training_type?: string;
|
|
3164
|
+
compress_type?: string;
|
|
3165
|
+
hyper_parameters?: Record<string, unknown>;
|
|
3166
|
+
custom_calibration_file_ids?: string[];
|
|
3167
|
+
/** Quantized output model ID (only set on SUCCEEDED). */
|
|
3168
|
+
quantized_output?: string | null;
|
|
3169
|
+
create_time?: string;
|
|
3170
|
+
start_time?: string | null;
|
|
3171
|
+
end_time?: string | null;
|
|
3172
|
+
error?: {
|
|
3173
|
+
code?: string;
|
|
3174
|
+
message?: string;
|
|
3175
|
+
[k: string]: unknown;
|
|
3176
|
+
} | null;
|
|
3177
|
+
group?: string;
|
|
3178
|
+
/** GPU seconds; present on SUCCEEDED / CANCELED. */
|
|
3179
|
+
usage?: number;
|
|
3180
|
+
[k: string]: unknown;
|
|
3181
|
+
}
|
|
3182
|
+
/** POST /api/v1/fine-tunes/compress/jobs and GET /jobs/{job_id} response. */
|
|
3183
|
+
export interface CompressJobResponse {
|
|
3184
|
+
request_id?: string;
|
|
3185
|
+
output?: CompressJob;
|
|
3186
|
+
}
|
|
3187
|
+
/** GET /api/v1/fine-tunes/compress/jobs response. */
|
|
3188
|
+
export interface ListCompressJobsResponse {
|
|
3189
|
+
request_id?: string;
|
|
3190
|
+
output?: {
|
|
3191
|
+
total?: number;
|
|
3192
|
+
page_no?: number;
|
|
3193
|
+
page_size?: number;
|
|
3194
|
+
jobs?: CompressJob[];
|
|
3195
|
+
[k: string]: unknown;
|
|
3196
|
+
};
|
|
3197
|
+
}
|
|
3198
|
+
/** GET /api/v1/fine-tunes/compress/jobs/{job_id}/logs response. */
|
|
3199
|
+
export interface GetCompressJobLogsResponse {
|
|
3200
|
+
request_id?: string;
|
|
3201
|
+
output?: {
|
|
3202
|
+
total?: number;
|
|
3203
|
+
logs?: string[];
|
|
3204
|
+
[k: string]: unknown;
|
|
3205
|
+
};
|
|
3206
|
+
}
|
|
3207
|
+
/** POST /jobs/{job_id}/cancel and DELETE /jobs/{job_id} response. */
|
|
3208
|
+
export interface CompressJobActionResponse {
|
|
3209
|
+
request_id?: string;
|
|
3210
|
+
output?: {
|
|
3211
|
+
status?: string;
|
|
3212
|
+
[k: string]: unknown;
|
|
3213
|
+
};
|
|
3214
|
+
}
|
|
2996
3215
|
//#endregion
|
|
2997
3216
|
//#region src/finetune/api.d.ts
|
|
2998
3217
|
/** POST /api/v1/fine-tunes */
|
|
@@ -3031,6 +3250,52 @@ export declare function listCheckpoints(client: Client, jobId: string, signal?:
|
|
|
3031
3250
|
*/
|
|
3032
3251
|
export declare function exportCheckpoint(client: Client, jobId: string, checkpoint: string, modelName: string, signal?: AbortSignal): Promise<ExportCheckpointResponse>;
|
|
3033
3252
|
//#endregion
|
|
3253
|
+
//#region src/finetune/compress.d.ts
|
|
3254
|
+
export interface ListCompressTemplatesParams {
|
|
3255
|
+
/** Filter by custom model ID, or a base model name to list all derived custom models. */
|
|
3256
|
+
model?: string;
|
|
3257
|
+
/** Response language: `zh-CN` | `en-US`. */
|
|
3258
|
+
lang?: string;
|
|
3259
|
+
signal?: AbortSignal;
|
|
3260
|
+
}
|
|
3261
|
+
/** GET /api/v1/fine-tunes/compress/templates */
|
|
3262
|
+
export declare function listCompressTemplates(client: Client, params?: ListCompressTemplatesParams): Promise<ListCompressTemplatesResponse>;
|
|
3263
|
+
/** POST /api/v1/fine-tunes/compress/jobs */
|
|
3264
|
+
export declare function createCompressJob(client: Client, body: CreateCompressJobRequest, signal?: AbortSignal): Promise<CompressJobResponse>;
|
|
3265
|
+
export interface ListCompressJobsParams {
|
|
3266
|
+
status?: string;
|
|
3267
|
+
model?: string;
|
|
3268
|
+
templateId?: string;
|
|
3269
|
+
quantSpec?: string;
|
|
3270
|
+
quantMethod?: string;
|
|
3271
|
+
startTime?: string;
|
|
3272
|
+
endTime?: string;
|
|
3273
|
+
searchKey?: string;
|
|
3274
|
+
/** `job_id` | `job_name`; narrows `searchKey` to one field. */
|
|
3275
|
+
selectKey?: string;
|
|
3276
|
+
sortOrder?: string;
|
|
3277
|
+
pageNo?: number;
|
|
3278
|
+
pageSize?: number;
|
|
3279
|
+
signal?: AbortSignal;
|
|
3280
|
+
}
|
|
3281
|
+
/** GET /api/v1/fine-tunes/compress/jobs */
|
|
3282
|
+
export declare function listCompressJobs(client: Client, params?: ListCompressJobsParams): Promise<ListCompressJobsResponse>;
|
|
3283
|
+
/** GET /api/v1/fine-tunes/compress/jobs/{job_id} */
|
|
3284
|
+
export declare function getCompressJob(client: Client, jobId: string, signal?: AbortSignal): Promise<CompressJobResponse>;
|
|
3285
|
+
export interface GetCompressJobLogsParams {
|
|
3286
|
+
/** Skip the first N lines. */
|
|
3287
|
+
offset?: number;
|
|
3288
|
+
/** Number of lines to read (server cap: 1000). */
|
|
3289
|
+
line?: number;
|
|
3290
|
+
signal?: AbortSignal;
|
|
3291
|
+
}
|
|
3292
|
+
/** GET /api/v1/fine-tunes/compress/jobs/{job_id}/logs */
|
|
3293
|
+
export declare function getCompressJobLogs(client: Client, jobId: string, params?: GetCompressJobLogsParams): Promise<GetCompressJobLogsResponse>;
|
|
3294
|
+
/** POST /api/v1/fine-tunes/compress/jobs/{job_id}/cancel */
|
|
3295
|
+
export declare function cancelCompressJob(client: Client, jobId: string, signal?: AbortSignal): Promise<CompressJobActionResponse>;
|
|
3296
|
+
/** DELETE /api/v1/fine-tunes/compress/jobs/{job_id} */
|
|
3297
|
+
export declare function deleteCompressJob(client: Client, jobId: string, signal?: AbortSignal): Promise<CompressJobActionResponse>;
|
|
3298
|
+
//#endregion
|
|
3034
3299
|
//#region src/finetune/capability.d.ts
|
|
3035
3300
|
/**
|
|
3036
3301
|
* Training-type vocabulary exposed to users.
|