faces-cli 1.7.6 → 1.7.8
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/dist/commands/chat/chat.js +8 -0
- package/dist/commands/compile/doc/pause.d.ts +3 -0
- package/dist/commands/compile/doc/pause.js +52 -5
- package/dist/commands/compile/thread/pause.d.ts +3 -0
- package/dist/commands/compile/thread/pause.js +53 -5
- package/dist/poll.d.ts +21 -0
- package/dist/poll.js +34 -0
- package/dist/utils.d.ts +0 -15
- package/dist/utils.js +0 -75
- package/oclif.manifest.json +948 -1830
- package/package.json +1 -1
- package/dist/commands/billing/quota.d.ts +0 -10
- package/dist/commands/billing/quota.js +0 -12
- package/dist/commands/billing/subscription.d.ts +0 -10
- package/dist/commands/billing/subscription.js +0 -24
- package/dist/commands/face/upload.d.ts +0 -17
- package/dist/commands/face/upload.js +0 -66
- package/dist/commands/voiceprint/build-status.d.ts +0 -14
- package/dist/commands/voiceprint/build-status.js +0 -46
- package/dist/commands/voiceprint/build.d.ts +0 -23
- package/dist/commands/voiceprint/build.js +0 -109
- package/dist/commands/voiceprint/get.d.ts +0 -14
- package/dist/commands/voiceprint/get.js +0 -47
- package/dist/commands/voiceprint/refine-status.d.ts +0 -14
- package/dist/commands/voiceprint/refine-status.js +0 -43
- package/dist/commands/voiceprint/refine.d.ts +0 -23
- package/dist/commands/voiceprint/refine.js +0 -88
- package/dist/commands/voiceprint/revert.d.ts +0 -14
- package/dist/commands/voiceprint/revert.js +0 -36
- package/dist/commands/voiceprint/score-status.d.ts +0 -14
- package/dist/commands/voiceprint/score-status.js +0 -46
- package/dist/commands/voiceprint/score.d.ts +0 -24
- package/dist/commands/voiceprint/score.js +0 -114
- package/dist/commands/voiceprint/upload.d.ts +0 -17
- package/dist/commands/voiceprint/upload.js +0 -66
- package/dist/commands/voiceprint/versions.d.ts +0 -14
- package/dist/commands/voiceprint/versions.js +0 -44
- package/dist/voiceprint.d.ts +0 -28
- package/dist/voiceprint.js +0 -55
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class BillingQuota extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static flags: {
|
|
5
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
};
|
|
9
|
-
run(): Promise<unknown>;
|
|
10
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class BillingQuota extends BaseCommand {
|
|
3
|
-
static description = 'Show compilation stats per face (deprecated — use compile:stats)';
|
|
4
|
-
static flags = {
|
|
5
|
-
...BaseCommand.baseFlags,
|
|
6
|
-
};
|
|
7
|
-
async run() {
|
|
8
|
-
process.stderr.write('Note: billing:quota is deprecated. Use compile:stats instead.\n');
|
|
9
|
-
await this.config.runCommand('compile:stats', this.argv);
|
|
10
|
-
return {};
|
|
11
|
-
}
|
|
12
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class BillingSubscription extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static flags: {
|
|
5
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
};
|
|
9
|
-
run(): Promise<unknown>;
|
|
10
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
import { FacesAPIError } from '../../client.js';
|
|
3
|
-
export default class BillingSubscription extends BaseCommand {
|
|
4
|
-
static description = 'Show current plan, face count, and renewal date';
|
|
5
|
-
static flags = {
|
|
6
|
-
...BaseCommand.baseFlags,
|
|
7
|
-
};
|
|
8
|
-
async run() {
|
|
9
|
-
const { flags } = await this.parse(BillingSubscription);
|
|
10
|
-
const client = this.makeClient(flags);
|
|
11
|
-
let data;
|
|
12
|
-
try {
|
|
13
|
-
data = await client.get('/v1/billing/subscription');
|
|
14
|
-
}
|
|
15
|
-
catch (err) {
|
|
16
|
-
if (err instanceof FacesAPIError)
|
|
17
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
18
|
-
throw err;
|
|
19
|
-
}
|
|
20
|
-
if (!this.jsonEnabled())
|
|
21
|
-
this.printHuman(data);
|
|
22
|
-
return data;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class FaceUpload extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static flags: {
|
|
5
|
-
file: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
|
-
kind: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
perspective: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'face-speaker': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
};
|
|
13
|
-
static args: {
|
|
14
|
-
face_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
15
|
-
};
|
|
16
|
-
run(): Promise<unknown>;
|
|
17
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { BaseCommand } from '../../base.js';
|
|
5
|
-
import { FacesAPIError } from '../../client.js';
|
|
6
|
-
export default class FaceUpload extends BaseCommand {
|
|
7
|
-
static description = 'Upload a file (text/PDF/audio/video) to a face';
|
|
8
|
-
static flags = {
|
|
9
|
-
...BaseCommand.baseFlags,
|
|
10
|
-
file: Flags.string({ description: 'File to upload', required: true }),
|
|
11
|
-
kind: Flags.string({
|
|
12
|
-
description: 'Upload kind: document or thread',
|
|
13
|
-
options: ['document', 'thread'],
|
|
14
|
-
default: 'document',
|
|
15
|
-
}),
|
|
16
|
-
perspective: Flags.string({
|
|
17
|
-
description: 'Perspective (document only)',
|
|
18
|
-
options: ['first-person', 'third-person'],
|
|
19
|
-
default: 'third-person',
|
|
20
|
-
}),
|
|
21
|
-
'face-speaker': Flags.string({
|
|
22
|
-
description: 'Speaker name to map to the face (thread only). If omitted, first speaker is used.',
|
|
23
|
-
}),
|
|
24
|
-
};
|
|
25
|
-
static args = {
|
|
26
|
-
face_id: Args.string({ description: 'Face alias', required: true }),
|
|
27
|
-
};
|
|
28
|
-
async run() {
|
|
29
|
-
const { args, flags } = await this.parse(FaceUpload);
|
|
30
|
-
const client = this.makeClient(flags);
|
|
31
|
-
if (!fs.existsSync(flags.file))
|
|
32
|
-
this.error(`File not found: ${flags.file}`);
|
|
33
|
-
const filename = path.basename(flags.file);
|
|
34
|
-
const fileBlob = new Blob([fs.readFileSync(flags.file)], { type: 'application/octet-stream' });
|
|
35
|
-
const form = new FormData();
|
|
36
|
-
form.append('file', fileBlob, filename);
|
|
37
|
-
// type, perspective, face_speaker are query params (not form fields)
|
|
38
|
-
const params = new URLSearchParams();
|
|
39
|
-
params.set('type', flags.kind);
|
|
40
|
-
params.set('perspective', flags.perspective);
|
|
41
|
-
if (flags['face-speaker'])
|
|
42
|
-
params.set('face_speaker', flags['face-speaker']);
|
|
43
|
-
let data;
|
|
44
|
-
try {
|
|
45
|
-
data = await client.postForm(`/v1/faces/${args.face_id}/upload?${params}`, form);
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
if (err instanceof FacesAPIError)
|
|
49
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
50
|
-
throw err;
|
|
51
|
-
}
|
|
52
|
-
if (!this.jsonEnabled()) {
|
|
53
|
-
this.printHuman(data);
|
|
54
|
-
const res = data;
|
|
55
|
-
if (flags.kind === 'thread' && res.thread_id) {
|
|
56
|
-
this.log(`\nNext step:`);
|
|
57
|
-
this.log(` faces compile:thread:make ${res.thread_id}`);
|
|
58
|
-
}
|
|
59
|
-
else if (flags.kind === 'document' && res.document_id) {
|
|
60
|
-
this.log(`\nNext step:`);
|
|
61
|
-
this.log(` faces compile:doc:make ${res.document_id}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return data;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class VoiceprintBuildStatus extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
};
|
|
10
|
-
static args: {
|
|
11
|
-
job_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<unknown>;
|
|
14
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Args } from '@oclif/core';
|
|
2
|
-
import { BaseCommand } from '../../base.js';
|
|
3
|
-
import { FacesAPIError } from '../../client.js';
|
|
4
|
-
import { jobFailureMessage } from '../../voiceprint.js';
|
|
5
|
-
import { printBuildReport } from './build.js';
|
|
6
|
-
export default class VoiceprintBuildStatus extends BaseCommand {
|
|
7
|
-
static description = 'Get the status/result of a voiceprint build job (from voiceprint:build without --wait)';
|
|
8
|
-
static examples = ['<%= config.bin %> <%= command.id %> 4e13bf03-fbc1-4ad0-92ae-16984e2f9a1d'];
|
|
9
|
-
static flags = { ...BaseCommand.baseFlags };
|
|
10
|
-
static args = {
|
|
11
|
-
job_id: Args.string({ description: 'Build job id', required: true }),
|
|
12
|
-
};
|
|
13
|
-
async run() {
|
|
14
|
-
const { args, flags } = await this.parse(VoiceprintBuildStatus);
|
|
15
|
-
const client = this.makeClient(flags);
|
|
16
|
-
let data;
|
|
17
|
-
try {
|
|
18
|
-
data = (await client.get(`/v1/voiceprint/builds/${encodeURIComponent(args.job_id)}`));
|
|
19
|
-
}
|
|
20
|
-
catch (err) {
|
|
21
|
-
if (err instanceof FacesAPIError)
|
|
22
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
23
|
-
throw err;
|
|
24
|
-
}
|
|
25
|
-
if (this.jsonEnabled())
|
|
26
|
-
return data;
|
|
27
|
-
const status = String(data.status ?? 'unknown');
|
|
28
|
-
if (status === 'failed') {
|
|
29
|
-
this.log(`job: ${args.job_id}`);
|
|
30
|
-
this.log(`status: failed`);
|
|
31
|
-
this.log(`error: ${jobFailureMessage(data.error)}`);
|
|
32
|
-
}
|
|
33
|
-
else if (status === 'done') {
|
|
34
|
-
printBuildReport(this, args.job_id, data);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
const p = data.progress;
|
|
38
|
-
this.log(`job: ${args.job_id}`);
|
|
39
|
-
this.log(`status: ${status}`);
|
|
40
|
-
if (p?.stage)
|
|
41
|
-
this.log(`stage: ${p.stage}${p.total ? ` ${p.done}/${p.total}` : ''}`);
|
|
42
|
-
this.log(`(still running — poll again with: faces voiceprint:build-status ${args.job_id})`);
|
|
43
|
-
}
|
|
44
|
-
return data;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class VoiceprintBuild extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
'holdout-count': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'min-valid': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
'oauth-only': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
wait: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
};
|
|
15
|
-
static args: {
|
|
16
|
-
self_alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
17
|
-
};
|
|
18
|
-
run(): Promise<unknown>;
|
|
19
|
-
}
|
|
20
|
-
/** Shared build-report formatter (used by voiceprint:build --wait and voiceprint:build-status). */
|
|
21
|
-
export declare function printBuildReport(cmd: {
|
|
22
|
-
log: (m: string) => void;
|
|
23
|
-
}, jobId: string, data: Record<string, unknown>): void;
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import { BaseCommand } from '../../base.js';
|
|
3
|
-
import { FacesAPIError } from '../../client.js';
|
|
4
|
-
import { pollVoiceprintJob, jobFailureMessage } from '../../voiceprint.js';
|
|
5
|
-
export default class VoiceprintBuild extends BaseCommand {
|
|
6
|
-
static description = "Build a self face's voice map from its uploaded corpus. Auto-creates the hidden <self>-voiceprint face and installs the map. Async — use --wait to block.";
|
|
7
|
-
static examples = [
|
|
8
|
-
'<%= config.bin %> <%= command.id %> alice --wait',
|
|
9
|
-
'<%= config.bin %> <%= command.id %> alice --holdout-count 120 --oauth-only --wait',
|
|
10
|
-
];
|
|
11
|
-
static flags = {
|
|
12
|
-
...BaseCommand.baseFlags,
|
|
13
|
-
model: Flags.string({ description: 'Model that forges the voice map (default: gpt-5.4)' }),
|
|
14
|
-
'holdout-count': Flags.integer({ description: 'Stratified scoring holdout size (default: 120)' }),
|
|
15
|
-
'min-valid': Flags.integer({ description: 'Corpus floor below which no holdout is split — train on all (default: 550)' }),
|
|
16
|
-
'oauth-only': Flags.boolean({ description: 'Only run on a free (OAuth) route; never fall back to billed inference', default: false }),
|
|
17
|
-
wait: Flags.boolean({ description: 'Block and poll until the build finishes (default: print the job_id and return)', default: false }),
|
|
18
|
-
};
|
|
19
|
-
static args = {
|
|
20
|
-
self_alias: Args.string({ description: 'Self face alias', required: true }),
|
|
21
|
-
};
|
|
22
|
-
async run() {
|
|
23
|
-
const { args, flags } = await this.parse(VoiceprintBuild);
|
|
24
|
-
const client = this.makeClient(flags);
|
|
25
|
-
const json = this.jsonEnabled();
|
|
26
|
-
const payload = { self_face: args.self_alias };
|
|
27
|
-
if (flags.model)
|
|
28
|
-
payload.model = flags.model;
|
|
29
|
-
if (flags['holdout-count'] !== undefined)
|
|
30
|
-
payload.holdout_count = flags['holdout-count'];
|
|
31
|
-
if (flags['min-valid'] !== undefined)
|
|
32
|
-
payload.min_valid = flags['min-valid'];
|
|
33
|
-
if (flags['oauth-only'])
|
|
34
|
-
payload.oauth_only = true;
|
|
35
|
-
let started;
|
|
36
|
-
try {
|
|
37
|
-
started = (await client.post('/v1/voiceprint/builds', { body: payload }));
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
if (err instanceof FacesAPIError)
|
|
41
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
42
|
-
throw err;
|
|
43
|
-
}
|
|
44
|
-
const jobId = String(started.job_id ?? '');
|
|
45
|
-
if (!jobId)
|
|
46
|
-
this.error('Server did not return a job_id');
|
|
47
|
-
if (!flags.wait) {
|
|
48
|
-
if (!json) {
|
|
49
|
-
this.log(`Build started: ${jobId}`);
|
|
50
|
-
this.log(`Poll with: faces voiceprint:build-status ${jobId}`);
|
|
51
|
-
}
|
|
52
|
-
return started;
|
|
53
|
-
}
|
|
54
|
-
if (!json)
|
|
55
|
-
process.stderr.write(`Building voice map for ${args.self_alias} (job ${jobId})...\n`);
|
|
56
|
-
let final;
|
|
57
|
-
let lastStage = '';
|
|
58
|
-
try {
|
|
59
|
-
final = await pollVoiceprintJob(client, '/v1/voiceprint/builds', jobId, {
|
|
60
|
-
timeoutMs: 3_600_000, // a large corpus fans lenses over many chunks — can take a while
|
|
61
|
-
onPoll: (data) => {
|
|
62
|
-
if (json)
|
|
63
|
-
return;
|
|
64
|
-
const p = data.progress;
|
|
65
|
-
const key = p ? `${p.stage}:${p.done}/${p.total}` : String(data.status);
|
|
66
|
-
if (key !== lastStage) {
|
|
67
|
-
lastStage = key;
|
|
68
|
-
process.stderr.write(` ${p?.stage ?? data.status}${p?.total ? ` ${p.done}/${p.total}` : ''}\n`);
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
if (err instanceof FacesAPIError)
|
|
75
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
76
|
-
this.error(err instanceof Error ? err.message : String(err));
|
|
77
|
-
}
|
|
78
|
-
if (final.status === 'failed')
|
|
79
|
-
this.error(`Build failed: ${jobFailureMessage(final.error)}`);
|
|
80
|
-
if (json)
|
|
81
|
-
return final;
|
|
82
|
-
printBuildReport(this, jobId, final);
|
|
83
|
-
return final;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/** Shared build-report formatter (used by voiceprint:build --wait and voiceprint:build-status). */
|
|
87
|
-
export function printBuildReport(cmd, jobId, data) {
|
|
88
|
-
const report = (data.report ?? {});
|
|
89
|
-
cmd.log(`job: ${jobId}`);
|
|
90
|
-
cmd.log(`status: ${data.status}`);
|
|
91
|
-
if (data.voiceprint_face_id)
|
|
92
|
-
cmd.log(`voiceprint_face_id: ${data.voiceprint_face_id}`);
|
|
93
|
-
if (data.version_id)
|
|
94
|
-
cmd.log(`version_id: ${data.version_id}`);
|
|
95
|
-
if (report.voice_map_chars !== undefined)
|
|
96
|
-
cmd.log(`voice_map_chars: ${report.voice_map_chars}`);
|
|
97
|
-
const baseline = report.baseline;
|
|
98
|
-
if (baseline) {
|
|
99
|
-
if (baseline.skipped) {
|
|
100
|
-
cmd.log(`baseline: skipped (${baseline.skipped})`);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
cmd.log(`baseline VCI: ${baseline.VCI ?? 'n/a'}`);
|
|
104
|
-
cmd.log(`baseline VFI: ${baseline.VFI ?? 'n/a'}`);
|
|
105
|
-
if (baseline.delta_ratio !== undefined)
|
|
106
|
-
cmd.log(`baseline delta: ${baseline.delta_ratio}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class VoiceprintGet extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
};
|
|
10
|
-
static args: {
|
|
11
|
-
job_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<unknown>;
|
|
14
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { Args } from '@oclif/core';
|
|
2
|
-
import { BaseCommand } from '../../base.js';
|
|
3
|
-
import { FacesAPIError } from '../../client.js';
|
|
4
|
-
export default class VoiceprintGet extends BaseCommand {
|
|
5
|
-
static description = 'Get the status/result of a voiceprint scoring job started with voiceprint:score --no-wait';
|
|
6
|
-
static examples = ['<%= config.bin %> <%= command.id %> 4e13bf03-fbc1-4ad0-92ae-16984e2f9a1d'];
|
|
7
|
-
static flags = { ...BaseCommand.baseFlags };
|
|
8
|
-
static args = {
|
|
9
|
-
job_id: Args.string({ description: 'Scoring job id (from voiceprint:score --no-wait)', required: true }),
|
|
10
|
-
};
|
|
11
|
-
async run() {
|
|
12
|
-
const { args, flags } = await this.parse(VoiceprintGet);
|
|
13
|
-
const client = this.makeClient(flags);
|
|
14
|
-
let data;
|
|
15
|
-
try {
|
|
16
|
-
data = (await client.get(`/v1/voiceprint/score/${encodeURIComponent(args.job_id)}`));
|
|
17
|
-
}
|
|
18
|
-
catch (err) {
|
|
19
|
-
if (err instanceof FacesAPIError)
|
|
20
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
21
|
-
throw err;
|
|
22
|
-
}
|
|
23
|
-
if (this.jsonEnabled())
|
|
24
|
-
return data;
|
|
25
|
-
const status = String(data.status ?? 'unknown');
|
|
26
|
-
this.log(`job: ${args.job_id}`);
|
|
27
|
-
this.log(`status: ${status}`);
|
|
28
|
-
const progress = data.progress;
|
|
29
|
-
if (progress && typeof progress.pairs_done === 'number') {
|
|
30
|
-
this.log(`pairs: ${progress.pairs_done}/${progress.pairs_total ?? '?'}`);
|
|
31
|
-
}
|
|
32
|
-
if (status === 'done') {
|
|
33
|
-
const report = (data.report ?? {});
|
|
34
|
-
this.log(`VCI: ${report.VCI ?? 'n/a'} (voice closeness — 100 = writes indistinguishably from the person)`);
|
|
35
|
-
this.log(`VFI: ${report.VFI ?? 'n/a'} (voice fidelity — how much of their voice is captured vs a generic baseline)`);
|
|
36
|
-
if (report.n_pairs !== undefined)
|
|
37
|
-
this.log(`n_pairs: ${report.n_pairs}`);
|
|
38
|
-
}
|
|
39
|
-
else if (status === 'failed') {
|
|
40
|
-
this.log(`error: ${data.error ?? 'unknown error'}`);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
this.log(`(still running — poll again with: faces voiceprint:get ${args.job_id})`);
|
|
44
|
-
}
|
|
45
|
-
return data;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class VoiceprintRefineStatus extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
};
|
|
10
|
-
static args: {
|
|
11
|
-
job_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<unknown>;
|
|
14
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Args } from '@oclif/core';
|
|
2
|
-
import { BaseCommand } from '../../base.js';
|
|
3
|
-
import { FacesAPIError } from '../../client.js';
|
|
4
|
-
import { jobFailureMessage } from '../../voiceprint.js';
|
|
5
|
-
import { printRefineReport } from './refine.js';
|
|
6
|
-
export default class VoiceprintRefineStatus extends BaseCommand {
|
|
7
|
-
static description = 'Get the status/result of a voiceprint refine job (from voiceprint:refine without --wait)';
|
|
8
|
-
static examples = ['<%= config.bin %> <%= command.id %> 4e13bf03-fbc1-4ad0-92ae-16984e2f9a1d'];
|
|
9
|
-
static flags = { ...BaseCommand.baseFlags };
|
|
10
|
-
static args = {
|
|
11
|
-
job_id: Args.string({ description: 'Refine job id', required: true }),
|
|
12
|
-
};
|
|
13
|
-
async run() {
|
|
14
|
-
const { args, flags } = await this.parse(VoiceprintRefineStatus);
|
|
15
|
-
const client = this.makeClient(flags);
|
|
16
|
-
let data;
|
|
17
|
-
try {
|
|
18
|
-
data = (await client.get(`/v1/voiceprint/refines/${encodeURIComponent(args.job_id)}`));
|
|
19
|
-
}
|
|
20
|
-
catch (err) {
|
|
21
|
-
if (err instanceof FacesAPIError)
|
|
22
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
23
|
-
throw err;
|
|
24
|
-
}
|
|
25
|
-
if (this.jsonEnabled())
|
|
26
|
-
return data;
|
|
27
|
-
const status = String(data.status ?? 'unknown');
|
|
28
|
-
if (status === 'failed') {
|
|
29
|
-
this.log(`job: ${args.job_id}`);
|
|
30
|
-
this.log(`status: failed`);
|
|
31
|
-
this.log(`error: ${jobFailureMessage(data.error)}`);
|
|
32
|
-
}
|
|
33
|
-
else if (status === 'done') {
|
|
34
|
-
printRefineReport(this, args.job_id, (data.report ?? {}));
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
this.log(`job: ${args.job_id}`);
|
|
38
|
-
this.log(`status: ${status}`);
|
|
39
|
-
this.log(`(still running — poll again with: faces voiceprint:refine-status ${args.job_id})`);
|
|
40
|
-
}
|
|
41
|
-
return data;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class VoiceprintRefine extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
model: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
temperature: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'n-samples': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
'oauth-only': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
wait: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
};
|
|
15
|
-
static args: {
|
|
16
|
-
self_alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
17
|
-
};
|
|
18
|
-
run(): Promise<unknown>;
|
|
19
|
-
}
|
|
20
|
-
/** Shared refine-report formatter (used by voiceprint:refine --wait and voiceprint:refine-status). */
|
|
21
|
-
export declare function printRefineReport(cmd: {
|
|
22
|
-
log: (m: string) => void;
|
|
23
|
-
}, jobId: string, report: Record<string, unknown>): void;
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import { BaseCommand } from '../../base.js';
|
|
3
|
-
import { FacesAPIError } from '../../client.js';
|
|
4
|
-
import { pollVoiceprintJob, jobFailureMessage } from '../../voiceprint.js';
|
|
5
|
-
export default class VoiceprintRefine extends BaseCommand {
|
|
6
|
-
static description = "Tune the active version's post-processing recipe and promote it only if it beats the current one. Requires an existing build with a holdout ≥ 20. Undo with voiceprint:revert.";
|
|
7
|
-
static examples = [
|
|
8
|
-
'<%= config.bin %> <%= command.id %> alice --wait',
|
|
9
|
-
'<%= config.bin %> <%= command.id %> alice --temperature 0.4 --n-samples 6 --wait',
|
|
10
|
-
];
|
|
11
|
-
static flags = {
|
|
12
|
-
...BaseCommand.baseFlags,
|
|
13
|
-
model: Flags.string({ description: "Model used to forge candidate drafts (default: the active version's build model)" }),
|
|
14
|
-
temperature: Flags.string({ description: 'Sampling temperature for candidate drafts (default: 0.4)' }),
|
|
15
|
-
'n-samples': Flags.integer({ description: 'Drafts forged per holdout pair (default: 6)' }),
|
|
16
|
-
'oauth-only': Flags.boolean({ description: 'Only run on a free (OAuth) route; never fall back to billed inference', default: false }),
|
|
17
|
-
wait: Flags.boolean({ description: 'Block and poll until refine finishes (default: print the job_id and return)', default: false }),
|
|
18
|
-
};
|
|
19
|
-
static args = {
|
|
20
|
-
self_alias: Args.string({ description: 'Self face alias', required: true }),
|
|
21
|
-
};
|
|
22
|
-
async run() {
|
|
23
|
-
const { args, flags } = await this.parse(VoiceprintRefine);
|
|
24
|
-
const client = this.makeClient(flags);
|
|
25
|
-
const json = this.jsonEnabled();
|
|
26
|
-
const payload = { self_face: args.self_alias };
|
|
27
|
-
if (flags.model)
|
|
28
|
-
payload.model = flags.model;
|
|
29
|
-
if (flags.temperature !== undefined)
|
|
30
|
-
payload.temperature = Number.parseFloat(flags.temperature);
|
|
31
|
-
if (flags['n-samples'] !== undefined)
|
|
32
|
-
payload.n_samples = flags['n-samples'];
|
|
33
|
-
if (flags['oauth-only'])
|
|
34
|
-
payload.oauth_only = true;
|
|
35
|
-
let started;
|
|
36
|
-
try {
|
|
37
|
-
started = (await client.post('/v1/voiceprint/refines', { body: payload }));
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
if (err instanceof FacesAPIError)
|
|
41
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
42
|
-
throw err;
|
|
43
|
-
}
|
|
44
|
-
const jobId = String(started.job_id ?? '');
|
|
45
|
-
if (!jobId)
|
|
46
|
-
this.error('Server did not return a job_id');
|
|
47
|
-
if (!flags.wait) {
|
|
48
|
-
if (!json) {
|
|
49
|
-
this.log(`Refine started: ${jobId}`);
|
|
50
|
-
this.log(`Poll with: faces voiceprint:refine-status ${jobId}`);
|
|
51
|
-
}
|
|
52
|
-
return started;
|
|
53
|
-
}
|
|
54
|
-
if (!json)
|
|
55
|
-
process.stderr.write(`Refining ${args.self_alias}'s recipe (job ${jobId})...\n`);
|
|
56
|
-
let final;
|
|
57
|
-
try {
|
|
58
|
-
final = await pollVoiceprintJob(client, '/v1/voiceprint/refines', jobId, { timeoutMs: 3_600_000 });
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
if (err instanceof FacesAPIError)
|
|
62
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
63
|
-
this.error(err instanceof Error ? err.message : String(err));
|
|
64
|
-
}
|
|
65
|
-
if (final.status === 'failed')
|
|
66
|
-
this.error(`Refine failed: ${jobFailureMessage(final.error)}`);
|
|
67
|
-
if (json)
|
|
68
|
-
return final;
|
|
69
|
-
printRefineReport(this, jobId, (final.report ?? {}));
|
|
70
|
-
return final;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
/** Shared refine-report formatter (used by voiceprint:refine --wait and voiceprint:refine-status). */
|
|
74
|
-
export function printRefineReport(cmd, jobId, report) {
|
|
75
|
-
const decision = String(report.decision ?? 'unknown');
|
|
76
|
-
const baseline = (report.baseline ?? {});
|
|
77
|
-
cmd.log(`job: ${jobId}`);
|
|
78
|
-
cmd.log(`decision: ${decision}${decision === 'promote' ? ' (a better recipe was promoted to a new active version)' : decision === 'keep' ? ' (nothing beat the current recipe; unchanged)' : ''}`);
|
|
79
|
-
if (baseline.VCI !== undefined || baseline.VFI !== undefined) {
|
|
80
|
-
cmd.log(`baseline: VCI ${baseline.VCI ?? 'n/a'} / VFI ${baseline.VFI ?? 'n/a'}`);
|
|
81
|
-
}
|
|
82
|
-
if (report.version_id)
|
|
83
|
-
cmd.log(`version: ${report.version_id}`);
|
|
84
|
-
if (Array.isArray(report.promoted_recipe))
|
|
85
|
-
cmd.log(`recipe: ${JSON.stringify(report.promoted_recipe)}`);
|
|
86
|
-
if (decision === 'promote')
|
|
87
|
-
cmd.log(`\nUndo with: faces voiceprint:revert <self_alias>`);
|
|
88
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../../base.js';
|
|
2
|
-
export default class VoiceprintRevert extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
-
token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
-
'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
};
|
|
10
|
-
static args: {
|
|
11
|
-
self_alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<unknown>;
|
|
14
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Args } from '@oclif/core';
|
|
2
|
-
import { BaseCommand } from '../../base.js';
|
|
3
|
-
import { FacesAPIError } from '../../client.js';
|
|
4
|
-
export default class VoiceprintRevert extends BaseCommand {
|
|
5
|
-
static description = "Revert a self face's voice map to its prior version (one-deep undo; re-running toggles back). Only changes which stored recipe/baseline is active — the map text is frozen.";
|
|
6
|
-
static examples = ['<%= config.bin %> <%= command.id %> alice'];
|
|
7
|
-
static flags = { ...BaseCommand.baseFlags };
|
|
8
|
-
static args = {
|
|
9
|
-
self_alias: Args.string({ description: 'Self face alias', required: true }),
|
|
10
|
-
};
|
|
11
|
-
async run() {
|
|
12
|
-
const { args, flags } = await this.parse(VoiceprintRevert);
|
|
13
|
-
const client = this.makeClient(flags);
|
|
14
|
-
let data;
|
|
15
|
-
try {
|
|
16
|
-
data = (await client.post('/v1/voiceprint/versions/revert', { body: { self_face: args.self_alias } }));
|
|
17
|
-
}
|
|
18
|
-
catch (err) {
|
|
19
|
-
if (err instanceof FacesAPIError) {
|
|
20
|
-
if (err.statusCode === 409)
|
|
21
|
-
this.error(`Nothing to revert to — ${args.self_alias} has only one voice-map version.`);
|
|
22
|
-
this.error(`Error (${err.statusCode}): ${err.message}`);
|
|
23
|
-
}
|
|
24
|
-
throw err;
|
|
25
|
-
}
|
|
26
|
-
if (this.jsonEnabled())
|
|
27
|
-
return data;
|
|
28
|
-
this.log(`self_face: ${data.self_face ?? args.self_alias}`);
|
|
29
|
-
this.log(`from_version: ${data.from_version ?? '?'}`);
|
|
30
|
-
this.log(`to_version: ${data.to_version ?? '?'}`);
|
|
31
|
-
this.log(`VCI/VFI: ${data.baseline_vci ?? 'n/a'} / ${data.baseline_vfi ?? 'n/a'}`);
|
|
32
|
-
if (data.recipe !== undefined)
|
|
33
|
-
this.log(`recipe: ${JSON.stringify(data.recipe)}`);
|
|
34
|
-
return data;
|
|
35
|
-
}
|
|
36
|
-
}
|