@tutorflow/cli 0.3.1 → 0.4.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 +246 -664
- package/dist/client.d.ts +16 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +76 -16
- package/dist/client.js.map +1 -1
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +38 -23
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +20 -12
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/classroom.d.ts +3 -0
- package/dist/commands/classroom.d.ts.map +1 -0
- package/dist/commands/classroom.js +27 -0
- package/dist/commands/classroom.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +4 -4
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/course.d.ts.map +1 -1
- package/dist/commands/course.js +25 -96
- package/dist/commands/course.js.map +1 -1
- package/dist/commands/credits.d.ts +3 -0
- package/dist/commands/credits.d.ts.map +1 -0
- package/dist/commands/credits.js +39 -0
- package/dist/commands/credits.js.map +1 -0
- package/dist/commands/evaluate.d.ts +3 -0
- package/dist/commands/evaluate.d.ts.map +1 -1
- package/dist/commands/evaluate.js +98 -57
- package/dist/commands/evaluate.js.map +1 -1
- package/dist/commands/interactive.d.ts +13 -0
- package/dist/commands/interactive.d.ts.map +1 -0
- package/dist/commands/interactive.js +100 -0
- package/dist/commands/interactive.js.map +1 -0
- package/dist/commands/learner.d.ts +4 -0
- package/dist/commands/learner.d.ts.map +1 -0
- package/dist/commands/learner.js +76 -0
- package/dist/commands/learner.js.map +1 -0
- package/dist/commands/module.d.ts.map +1 -1
- package/dist/commands/module.js +18 -98
- package/dist/commands/module.js.map +1 -1
- package/dist/commands/platform.d.ts.map +1 -1
- package/dist/commands/platform.js +10 -2
- package/dist/commands/platform.js.map +1 -1
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +69 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/slide.d.ts.map +1 -1
- package/dist/commands/slide.js +25 -97
- package/dist/commands/slide.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +38 -106
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/video.d.ts.map +1 -1
- package/dist/commands/video.js +138 -86
- package/dist/commands/video.js.map +1 -1
- package/dist/commands/webhook.d.ts +3 -0
- package/dist/commands/webhook.d.ts.map +1 -0
- package/dist/commands/webhook.js +75 -0
- package/dist/commands/webhook.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -16
- package/dist/config.js.map +1 -1
- package/dist/content/context.d.ts +26 -0
- package/dist/content/context.d.ts.map +1 -0
- package/dist/content/context.js +74 -0
- package/dist/content/context.js.map +1 -0
- package/dist/content/resource.d.ts +66 -0
- package/dist/content/resource.d.ts.map +1 -0
- package/dist/content/resource.js +181 -0
- package/dist/content/resource.js.map +1 -0
- package/dist/content/runs.d.ts +51 -0
- package/dist/content/runs.d.ts.map +1 -0
- package/dist/content/runs.js +171 -0
- package/dist/content/runs.js.map +1 -0
- package/dist/index.js +71 -21
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +15 -65
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/dist/utils/args.d.ts +15 -0
- package/dist/utils/args.d.ts.map +1 -0
- package/dist/utils/args.js +91 -0
- package/dist/utils/args.js.map +1 -0
- package/dist/utils/keys.d.ts +11 -0
- package/dist/utils/keys.d.ts.map +1 -0
- package/dist/utils/keys.js +29 -0
- package/dist/utils/keys.js.map +1 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +21 -6
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/runtime.d.ts +14 -4
- package/dist/utils/runtime.d.ts.map +1 -1
- package/dist/utils/runtime.js +42 -7
- package/dist/utils/runtime.js.map +1 -1
- package/package.json +4 -3
- package/dist/utils/spinner.d.ts +0 -8
- package/dist/utils/spinner.d.ts.map +0 -1
- package/dist/utils/spinner.js +0 -26
- package/dist/utils/spinner.js.map +0 -1
package/dist/commands/course.js
CHANGED
|
@@ -1,104 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.courseCommand = courseCommand;
|
|
7
4
|
const commander_1 = require("commander");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const output_1 = require("../utils/output");
|
|
12
|
-
const runtime_1 = require("../utils/runtime");
|
|
5
|
+
const args_1 = require("../utils/args");
|
|
6
|
+
const resource_1 = require("../content/resource");
|
|
7
|
+
const COURSES = { path: 'courses', noun: 'course' };
|
|
13
8
|
function courseCommand() {
|
|
14
|
-
const course = new commander_1.Command('course').description('
|
|
15
|
-
course
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
response = await client.request('POST', '/v1/platform/courses', {
|
|
37
|
-
prompt: coursePrompt,
|
|
38
|
-
lessonCount: parseInt(options.lessons, 10),
|
|
39
|
-
language: options.language,
|
|
40
|
-
mode: 'sync',
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
finally {
|
|
44
|
-
s?.stop('Done');
|
|
45
|
-
}
|
|
46
|
-
(0, output_1.printResult)(response);
|
|
47
|
-
if (options.open && response.previewUrl && (0, runtime_1.isInteractive)()) {
|
|
48
|
-
const shouldOpen = await (0, prompts_1.confirm)({ message: 'Open in browser?' });
|
|
49
|
-
if (shouldOpen === true)
|
|
50
|
-
await (0, open_1.default)(response.previewUrl);
|
|
51
|
-
}
|
|
52
|
-
}));
|
|
53
|
-
course
|
|
54
|
-
.command('list')
|
|
55
|
-
.option('-l, --limit <number>', 'Number of results', '10')
|
|
56
|
-
.option('-o, --offset <number>', 'Number of rows to skip', '0')
|
|
57
|
-
.option('-s, --status <status>', 'Filter by status')
|
|
58
|
-
.action((0, runtime_1.command)(async (options) => {
|
|
59
|
-
const client = await client_1.ApiClient.createAuthenticated();
|
|
60
|
-
const qs = new URLSearchParams({ limit: options.limit, offset: options.offset });
|
|
61
|
-
if (options.status)
|
|
62
|
-
qs.set('status', options.status);
|
|
63
|
-
const response = await client.request('GET', `/v1/platform/courses?${qs.toString()}`);
|
|
64
|
-
const courses = Array.isArray(response) ? response : response.items ?? response.data ?? [];
|
|
65
|
-
if ((0, runtime_1.isJsonMode)()) {
|
|
66
|
-
(0, output_1.printResult)(courses);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
(0, output_1.printResult)(courses.map((c) => ({
|
|
70
|
-
ID: c.id,
|
|
71
|
-
Title: c.title || 'Untitled',
|
|
72
|
-
Status: c.status,
|
|
73
|
-
Created: new Date(c.createdAt).toLocaleDateString(),
|
|
74
|
-
})));
|
|
75
|
-
}
|
|
76
|
-
}));
|
|
77
|
-
course
|
|
78
|
-
.command('get <id>')
|
|
79
|
-
.description('Fetch a single course by ID')
|
|
80
|
-
.action((0, runtime_1.command)(async (id) => {
|
|
81
|
-
const client = await client_1.ApiClient.createAuthenticated();
|
|
82
|
-
const response = await client.request('GET', `/v1/platform/courses/${id}`);
|
|
83
|
-
(0, output_1.printResult)(response);
|
|
84
|
-
}));
|
|
85
|
-
course
|
|
86
|
-
.command('open <id>')
|
|
87
|
-
.description('Open a course in the browser')
|
|
88
|
-
.action((0, runtime_1.command)(async (id) => {
|
|
89
|
-
const client = await client_1.ApiClient.createAuthenticated();
|
|
90
|
-
const response = await client.request('GET', `/v1/platform/courses/${id}`);
|
|
91
|
-
if (!response.previewUrl) {
|
|
92
|
-
throw new runtime_1.CliError('No preview URL available for this course', {
|
|
93
|
-
code: 'ENOPREVIEW',
|
|
94
|
-
exitCode: 1,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
if ((0, runtime_1.isInteractive)())
|
|
98
|
-
await (0, open_1.default)(response.previewUrl);
|
|
99
|
-
(0, output_1.printResult)({ previewUrl: response.previewUrl });
|
|
100
|
-
(0, output_1.printStatus)('Opening in browser...', 'success');
|
|
101
|
-
}));
|
|
9
|
+
const course = new commander_1.Command('course').description('Generate and manage classroom courses');
|
|
10
|
+
(0, resource_1.addGenerateCommand)(course, {
|
|
11
|
+
...COURSES,
|
|
12
|
+
description: 'Generate a course with every lesson (3 credits for the outline + 3 per lesson)',
|
|
13
|
+
promptLabel: 'Describe the course',
|
|
14
|
+
example: 'tutorflow course generate "Beginner Python" --lessons 5 --wait',
|
|
15
|
+
configure: (cmd) => cmd
|
|
16
|
+
.option('-n, --lessons <number>', 'Number of lessons')
|
|
17
|
+
.option('-l, --language <lang>', 'Language code', 'en')
|
|
18
|
+
.option('--level <level>', 'Learner level, e.g. beginner')
|
|
19
|
+
.option('--title <title>', 'Course title (generated when omitted)')
|
|
20
|
+
.option('--description <text>', 'Course description'),
|
|
21
|
+
buildBody: (prompt, options) => ({
|
|
22
|
+
prompt,
|
|
23
|
+
lessonCount: (0, args_1.parsePositiveInt)(options.lessons, '--lessons'),
|
|
24
|
+
language: options.language,
|
|
25
|
+
level: options.level,
|
|
26
|
+
title: options.title,
|
|
27
|
+
description: options.description,
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
(0, resource_1.addCrudCommands)(course, COURSES);
|
|
102
31
|
return course;
|
|
103
32
|
}
|
|
104
33
|
//# sourceMappingURL=course.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"course.js","sourceRoot":"","sources":["../../src/commands/course.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"course.js","sourceRoot":"","sources":["../../src/commands/course.ts"],"names":[],"mappings":";;AAcA,sCA0BC;AAxCD,yCAAoC;AACpC,wCAAiD;AACjD,kDAA6F;AAU7F,MAAM,OAAO,GAAiB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAElE,SAAgB,aAAa;IAC3B,MAAM,MAAM,GAAG,IAAI,mBAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC;IAE1F,IAAA,6BAAkB,EAAwB,MAAM,EAAE;QAChD,GAAG,OAAO;QACV,WAAW,EAAE,gFAAgF;QAC7F,WAAW,EAAE,qBAAqB;QAClC,OAAO,EAAE,gEAAgE;QACzE,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CACjB,GAAG;aACA,MAAM,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;aACrD,MAAM,CAAC,uBAAuB,EAAE,eAAe,EAAE,IAAI,CAAC;aACtD,MAAM,CAAC,iBAAiB,EAAE,8BAA8B,CAAC;aACzD,MAAM,CAAC,iBAAiB,EAAE,uCAAuC,CAAC;aAClE,MAAM,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;QACzD,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAC/B,MAAM;YACN,WAAW,EAAE,IAAA,uBAAgB,EAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC;YAC3D,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC;KACH,CAAC,CAAC;IACH,IAAA,0BAAe,EAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.d.ts","sourceRoot":"","sources":["../../src/commands/credits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,cAAc,IAAI,OAAO,CAqCxC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.creditsCommand = creditsCommand;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const output_1 = require("../utils/output");
|
|
6
|
+
const runtime_1 = require("../utils/runtime");
|
|
7
|
+
const args_1 = require("../utils/args");
|
|
8
|
+
const context_1 = require("../content/context");
|
|
9
|
+
function creditsCommand() {
|
|
10
|
+
const credits = new commander_1.Command('credits').description('AI Credit balance and history (one ledger per organization)');
|
|
11
|
+
credits
|
|
12
|
+
.command('balance')
|
|
13
|
+
.description('Show the AI Credit balance this key spends from')
|
|
14
|
+
.action((0, runtime_1.command)(async () => {
|
|
15
|
+
const client = await (0, context_1.createContentClient)();
|
|
16
|
+
(0, output_1.printResult)(await client.request('GET', '/v1/content/credits'));
|
|
17
|
+
}));
|
|
18
|
+
credits
|
|
19
|
+
.command('history')
|
|
20
|
+
.description('List AI Credit charges, refunds and adjustments, newest first')
|
|
21
|
+
.option('-l, --limit <number>', 'Rows per page (max 100)', '20')
|
|
22
|
+
.option('--cursor <cursor>', 'meta.nextCursor from the previous page')
|
|
23
|
+
.option('--from <iso>', 'Only rows at or after this ISO 8601 time')
|
|
24
|
+
.option('--to <iso>', 'Only rows before this ISO 8601 time')
|
|
25
|
+
.option('--type <type>', 'Credit history type')
|
|
26
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
27
|
+
const limit = (0, args_1.parsePositiveInt)(options.limit, '--limit');
|
|
28
|
+
const client = await (0, context_1.createContentClient)();
|
|
29
|
+
const qs = new URLSearchParams({ limit: String(limit) });
|
|
30
|
+
for (const key of ['cursor', 'from', 'to', 'type']) {
|
|
31
|
+
const value = options[key];
|
|
32
|
+
if (value)
|
|
33
|
+
qs.set(key, value);
|
|
34
|
+
}
|
|
35
|
+
(0, output_1.printResult)(await client.request('GET', `/v1/content/credits/history?${qs}`));
|
|
36
|
+
}));
|
|
37
|
+
return credits;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=credits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.js","sourceRoot":"","sources":["../../src/commands/credits.ts"],"names":[],"mappings":";;AAMA,wCAqCC;AA3CD,yCAAoC;AACpC,4CAA8C;AAC9C,8CAA2C;AAC3C,wCAAiD;AACjD,gDAAyD;AAEzD,SAAgB,cAAc;IAC5B,MAAM,OAAO,GAAG,IAAI,mBAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,6DAA6D,CAAC,CAAC;IAElH,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CACL,IAAA,iBAAO,EAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,IAAA,6BAAmB,GAAE,CAAC;QAC3C,IAAA,oBAAW,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,+DAA+D,CAAC;SAC5E,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,EAAE,IAAI,CAAC;SAC/D,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,CAAC;SACrE,MAAM,CAAC,cAAc,EAAE,0CAA0C,CAAC;SAClE,MAAM,CAAC,YAAY,EAAE,qCAAqC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC;SAC9C,MAAM,CACL,IAAA,iBAAO,EACL,KAAK,EAAE,OAAsF,EAAE,EAAE;QAC/F,MAAM,KAAK,GAAG,IAAA,uBAAgB,EAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,IAAA,6BAAmB,GAAE,CAAC;QAC3C,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzD,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAU,EAAE,CAAC;YAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,KAAK;gBAAE,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,IAAA,oBAAW,EAAC,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,+BAA+B,EAAE,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC,CACF,CACF,CAAC;IAEJ,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
/** `tutorflow evaluate`: grade one answer synchronously (1 credit). */
|
|
2
3
|
export declare function evaluateCommand(): Command;
|
|
4
|
+
/** `tutorflow evaluation …`: past evaluations and the learner model. */
|
|
5
|
+
export declare function evaluationCommand(): Command;
|
|
3
6
|
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/commands/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/commands/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCpC,uEAAuE;AACvE,wBAAgB,eAAe,IAAI,OAAO,CA+BzC;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,IAAI,OAAO,CAkE3C"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.evaluateCommand = evaluateCommand;
|
|
4
|
+
exports.evaluationCommand = evaluationCommand;
|
|
4
5
|
const commander_1 = require("commander");
|
|
5
6
|
const prompts_1 = require("@clack/prompts");
|
|
6
|
-
const client_1 = require("../client");
|
|
7
7
|
const output_1 = require("../utils/output");
|
|
8
8
|
const runtime_1 = require("../utils/runtime");
|
|
9
|
+
const args_1 = require("../utils/args");
|
|
10
|
+
const context_1 = require("../content/context");
|
|
9
11
|
const VALID_TYPES = ['exact', 'rubric_short_answer', 'open_ended'];
|
|
10
12
|
const TYPE_ALIASES = {
|
|
11
13
|
exact: 'exact',
|
|
@@ -14,56 +16,112 @@ const TYPE_ALIASES = {
|
|
|
14
16
|
'open-ended': 'open_ended',
|
|
15
17
|
open_ended: 'open_ended',
|
|
16
18
|
};
|
|
19
|
+
/** `tutorflow evaluate`: grade one answer synchronously (1 credit). */
|
|
17
20
|
function evaluateCommand() {
|
|
18
21
|
return new commander_1.Command('evaluate')
|
|
19
|
-
.description('
|
|
22
|
+
.description('Grade a learner answer (1 credit); concept tags feed the learner model')
|
|
20
23
|
.option('-t, --type <type>', 'Evaluation type (exact | rubric_short_answer | open_ended). Aliases: rubric, open-ended')
|
|
21
24
|
.option('-q, --question <text>', 'The question being evaluated')
|
|
22
|
-
.option('-a, --student-answer <text>', "
|
|
25
|
+
.option('-a, --student-answer <text>', "Learner's answer")
|
|
23
26
|
.option('-e, --expected-answer <text>', 'Reference answer (required for exact)')
|
|
24
27
|
.option('--rubric-json <json>', 'Rubric JSON for rubric_short_answer evaluations')
|
|
25
28
|
.option('--max-score <number>', 'Maximum score for the evaluation')
|
|
26
29
|
.option('-l, --language <lang>', 'Feedback language', 'en')
|
|
30
|
+
.option('--learner-id <id>', 'Your id for the learner; feeds `evaluation mastery <id>`')
|
|
31
|
+
.option('--concept-tags <list>', 'Comma-separated concepts this question measures')
|
|
32
|
+
.option('--subject <subject>', 'Subject of the question')
|
|
27
33
|
.option('--idempotency-key <key>', 'Idempotency key for safe retries')
|
|
28
34
|
.action((0, runtime_1.command)(async (options) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const result = await (0, prompts_1.select)({
|
|
33
|
-
message: 'Select evaluation type:',
|
|
34
|
-
options: [
|
|
35
|
-
{ value: 'exact', label: 'Exact Match' },
|
|
36
|
-
{ value: 'rubric_short_answer', label: 'Rubric-based' },
|
|
37
|
-
{ value: 'open_ended', label: 'Open-ended AI Evaluation' },
|
|
38
|
-
],
|
|
39
|
-
});
|
|
40
|
-
if (typeof result === 'symbol') {
|
|
41
|
-
throw new runtime_1.CliError('Cancelled', { code: 'ECANCELLED', exitCode: 130 });
|
|
42
|
-
}
|
|
43
|
-
evalType = result;
|
|
44
|
-
}
|
|
45
|
-
const question = options.question ?? (await promptOrThrow('Enter the question:', '--question'));
|
|
46
|
-
const studentAnswer = options.studentAnswer ??
|
|
47
|
-
(await promptOrThrow('Enter the student answer:', '--student-answer'));
|
|
48
|
-
let expectedAnswer = options.expectedAnswer;
|
|
49
|
-
if (evalType === 'exact' && !expectedAnswer) {
|
|
50
|
-
expectedAnswer = await promptOrThrow('Enter the expected answer:', '--expected-answer');
|
|
51
|
-
}
|
|
52
|
-
const rubric = parseRubric(evalType, options.rubricJson);
|
|
53
|
-
const client = await client_1.ApiClient.createAuthenticated();
|
|
54
|
-
const response = await client.request('POST', '/v1/platform/evaluations', {
|
|
55
|
-
evaluationType: evalType,
|
|
56
|
-
questionText: question,
|
|
57
|
-
learnerAnswer: studentAnswer,
|
|
58
|
-
referenceAnswer: expectedAnswer,
|
|
59
|
-
rubric,
|
|
60
|
-
maxScore: parseOptionalInteger(options.maxScore, '--max-score'),
|
|
61
|
-
language: options.language,
|
|
62
|
-
mode: 'sync',
|
|
63
|
-
}, options.idempotencyKey ? { 'Idempotency-Key': options.idempotencyKey } : undefined);
|
|
64
|
-
(0, output_1.printResult)(response);
|
|
35
|
+
const body = await buildEvaluationBody(options);
|
|
36
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
37
|
+
(0, output_1.printResult)(await ctx.client.request('POST', (0, context_1.classroomPath)(ctx, '/evaluations'), body, (0, args_1.idempotencyHeaders)(options.idempotencyKey)));
|
|
65
38
|
}));
|
|
66
39
|
}
|
|
40
|
+
/** `tutorflow evaluation …`: past evaluations and the learner model. */
|
|
41
|
+
function evaluationCommand() {
|
|
42
|
+
const evaluation = new commander_1.Command('evaluation').description('Read past evaluations and the learner model built from them');
|
|
43
|
+
evaluation
|
|
44
|
+
.command('list')
|
|
45
|
+
.description('List evaluations of the classroom, newest first')
|
|
46
|
+
.option('-l, --limit <number>', 'Items per page', '20')
|
|
47
|
+
.option('--cursor <cursor>', 'meta.nextCursor from the previous page')
|
|
48
|
+
.option('--learner-id <id>', 'Only this learner (the id evaluations were sent with)')
|
|
49
|
+
.option('--status <status>', 'Filter by status, e.g. COMPLETED')
|
|
50
|
+
.option('--type <type>', 'Filter by evaluation type')
|
|
51
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
52
|
+
const limit = (0, args_1.parsePositiveInt)(options.limit, '--limit');
|
|
53
|
+
const evaluationType = normalizeType(options.type);
|
|
54
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
55
|
+
const qs = new URLSearchParams({ limit: String(limit) });
|
|
56
|
+
if (options.cursor)
|
|
57
|
+
qs.set('cursor', options.cursor);
|
|
58
|
+
if (options.learnerId)
|
|
59
|
+
qs.set('learner', options.learnerId);
|
|
60
|
+
if (options.status)
|
|
61
|
+
qs.set('status', options.status);
|
|
62
|
+
if (evaluationType)
|
|
63
|
+
qs.set('evaluationType', evaluationType);
|
|
64
|
+
(0, output_1.printResult)(await ctx.client.request('GET', `${(0, context_1.classroomPath)(ctx, '/evaluations')}?${qs}`));
|
|
65
|
+
}));
|
|
66
|
+
evaluation
|
|
67
|
+
.command('get <evaluationId>')
|
|
68
|
+
.description('Show one evaluation')
|
|
69
|
+
.action((0, runtime_1.command)(async (id) => {
|
|
70
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
71
|
+
(0, output_1.printResult)(await ctx.client.request('GET', (0, context_1.classroomPath)(ctx, `/evaluations/${(0, context_1.segment)(id)}`)));
|
|
72
|
+
}));
|
|
73
|
+
evaluation
|
|
74
|
+
.command('concepts')
|
|
75
|
+
.description('List the concepts evaluations have tagged in this classroom')
|
|
76
|
+
.action((0, runtime_1.command)(async () => {
|
|
77
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
78
|
+
(0, output_1.printResult)(await ctx.client.request('GET', (0, context_1.classroomPath)(ctx, '/concepts')));
|
|
79
|
+
}));
|
|
80
|
+
evaluation
|
|
81
|
+
.command('mastery <learnerId>')
|
|
82
|
+
.description("Show a learner's mastery per concept")
|
|
83
|
+
.action((0, runtime_1.command)(async (learnerId) => {
|
|
84
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
85
|
+
(0, output_1.printResult)(await ctx.client.request('GET', (0, context_1.classroomPath)(ctx, `/mastery/${(0, context_1.segment)(learnerId)}`)));
|
|
86
|
+
}));
|
|
87
|
+
return evaluation;
|
|
88
|
+
}
|
|
89
|
+
async function buildEvaluationBody(options) {
|
|
90
|
+
const evaluationType = normalizeType(options.type) ?? (await promptType());
|
|
91
|
+
const questionText = await (0, args_1.valueOrPrompt)(options.question, 'Enter the question:', 'Pass --question <text>.');
|
|
92
|
+
const learnerAnswer = await (0, args_1.valueOrPrompt)(options.studentAnswer, 'Enter the student answer:', 'Pass --student-answer <text>.');
|
|
93
|
+
const referenceAnswer = evaluationType === 'exact'
|
|
94
|
+
? await (0, args_1.valueOrPrompt)(options.expectedAnswer, 'Enter the expected answer:', 'Pass --expected-answer <text>.')
|
|
95
|
+
: options.expectedAnswer;
|
|
96
|
+
return (0, args_1.compact)({
|
|
97
|
+
evaluationType,
|
|
98
|
+
questionText,
|
|
99
|
+
learnerAnswer,
|
|
100
|
+
referenceAnswer,
|
|
101
|
+
rubric: parseRubric(evaluationType, options.rubricJson),
|
|
102
|
+
maxScore: (0, args_1.parsePositiveInt)(options.maxScore, '--max-score'),
|
|
103
|
+
language: options.language,
|
|
104
|
+
learnerExternalId: options.learnerId,
|
|
105
|
+
conceptTags: (0, args_1.splitList)(options.conceptTags),
|
|
106
|
+
subject: options.subject,
|
|
107
|
+
mode: 'sync',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async function promptType() {
|
|
111
|
+
(0, runtime_1.requireInteractive)(`Pass --type ${VALID_TYPES.join('|')}`);
|
|
112
|
+
const result = await (0, prompts_1.select)({
|
|
113
|
+
message: 'Select evaluation type:',
|
|
114
|
+
options: [
|
|
115
|
+
{ value: 'exact', label: 'Exact Match' },
|
|
116
|
+
{ value: 'rubric_short_answer', label: 'Rubric-based' },
|
|
117
|
+
{ value: 'open_ended', label: 'Open-ended AI Evaluation' },
|
|
118
|
+
],
|
|
119
|
+
});
|
|
120
|
+
if (typeof result === 'symbol') {
|
|
121
|
+
throw new runtime_1.CliError('Cancelled', { code: 'ECANCELLED', exitCode: 130 });
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
67
125
|
function normalizeType(type) {
|
|
68
126
|
if (!type)
|
|
69
127
|
return undefined;
|
|
@@ -73,21 +131,12 @@ function normalizeType(type) {
|
|
|
73
131
|
}
|
|
74
132
|
return normalized;
|
|
75
133
|
}
|
|
76
|
-
function parseOptionalInteger(value, flagName) {
|
|
77
|
-
if (value === undefined)
|
|
78
|
-
return undefined;
|
|
79
|
-
const parsed = Number.parseInt(value, 10);
|
|
80
|
-
if (!Number.isInteger(parsed)) {
|
|
81
|
-
throw new runtime_1.CliError(`${flagName} must be an integer`, { code: 'EINVAL', exitCode: 2 });
|
|
82
|
-
}
|
|
83
|
-
return parsed;
|
|
84
|
-
}
|
|
85
134
|
function parseRubric(type, rubricJson) {
|
|
86
135
|
if (type !== 'rubric_short_answer')
|
|
87
136
|
return undefined;
|
|
88
137
|
if (!rubricJson) {
|
|
89
138
|
throw new runtime_1.CliError('rubric_short_answer requires --rubric-json <json>.', {
|
|
90
|
-
code: '
|
|
139
|
+
code: 'EINVAL',
|
|
91
140
|
exitCode: 2,
|
|
92
141
|
});
|
|
93
142
|
}
|
|
@@ -101,12 +150,4 @@ function parseRubric(type, rubricJson) {
|
|
|
101
150
|
});
|
|
102
151
|
}
|
|
103
152
|
}
|
|
104
|
-
async function promptOrThrow(message, flagHint) {
|
|
105
|
-
(0, runtime_1.requireInteractive)(`Pass ${flagHint} <text>.`);
|
|
106
|
-
const result = await (0, prompts_1.text)({ message });
|
|
107
|
-
if (!result || typeof result === 'symbol') {
|
|
108
|
-
throw new runtime_1.CliError('Cancelled', { code: 'ECANCELLED', exitCode: 130 });
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
}
|
|
112
153
|
//# sourceMappingURL=evaluate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/commands/evaluate.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/commands/evaluate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { type ResourceSpec } from '../content/resource';
|
|
3
|
+
interface InteractiveSpec extends ResourceSpec {
|
|
4
|
+
command: string;
|
|
5
|
+
description: string;
|
|
6
|
+
briefCredits: string;
|
|
7
|
+
buildCredits: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function interactiveCommand(spec: InteractiveSpec): Command;
|
|
10
|
+
export declare function gameCommand(): Command;
|
|
11
|
+
export declare function simulationCommand(): Command;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=interactive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/commands/interactive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,EAKL,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAY7B,UAAU,eAAgB,SAAQ,YAAY;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAWD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CA+DjE;AAwCD,wBAAgB,WAAW,IAAI,OAAO,CASrC;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAS3C"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interactiveCommand = interactiveCommand;
|
|
4
|
+
exports.gameCommand = gameCommand;
|
|
5
|
+
exports.simulationCommand = simulationCommand;
|
|
6
|
+
const commander_1 = require("commander");
|
|
7
|
+
const output_1 = require("../utils/output");
|
|
8
|
+
const runtime_1 = require("../utils/runtime");
|
|
9
|
+
const args_1 = require("../utils/args");
|
|
10
|
+
const context_1 = require("../content/context");
|
|
11
|
+
const resource_1 = require("../content/resource");
|
|
12
|
+
const runs_1 = require("../content/runs");
|
|
13
|
+
/**
|
|
14
|
+
* Games and simulations share one lifecycle: create → brief (plan) → build →
|
|
15
|
+
* revise. The CLI always asks for the 202 answer (Prefer: respond-async)
|
|
16
|
+
* instead of the SSE stream, and --wait polls the resource's run route.
|
|
17
|
+
*/
|
|
18
|
+
const VISIBILITIES = ['PUBLIC', 'PRIVATE'];
|
|
19
|
+
const ASYNC_HEADERS = { Prefer: 'respond-async' };
|
|
20
|
+
function interactiveCommand(spec) {
|
|
21
|
+
const root = new commander_1.Command(spec.command).description(spec.description);
|
|
22
|
+
root
|
|
23
|
+
.command('create')
|
|
24
|
+
.description(`Create an empty ${spec.noun}; then run brief and build`)
|
|
25
|
+
.requiredOption('--title <title>', 'Title')
|
|
26
|
+
.option('--description <text>', 'Description')
|
|
27
|
+
.option('--visibility <visibility>', 'PUBLIC or PRIVATE', 'PRIVATE')
|
|
28
|
+
.option('--idempotency-key <key>', 'Idempotency key for safe retries')
|
|
29
|
+
.action((0, runtime_1.command)(async (options) => {
|
|
30
|
+
const visibility = (0, args_1.parseChoice)(options.visibility, '--visibility', VISIBILITIES);
|
|
31
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
32
|
+
(0, output_1.printResult)(await ctx.client.request('POST', (0, resource_1.resourcePath)(ctx, spec), (0, args_1.compact)({ title: options.title, description: options.description, visibility }), (0, args_1.idempotencyHeaders)(options.idempotencyKey)));
|
|
33
|
+
}));
|
|
34
|
+
addStep(root, spec, {
|
|
35
|
+
name: 'brief',
|
|
36
|
+
description: `Plan the ${spec.noun} (${spec.briefCredits})`,
|
|
37
|
+
configure: (cmd) => cmd.option('--reference <markdown>', 'Reference material in Markdown'),
|
|
38
|
+
body: (options) => (0, args_1.compact)({ referenceMarkdown: options.reference }),
|
|
39
|
+
});
|
|
40
|
+
addStep(root, spec, {
|
|
41
|
+
name: 'build',
|
|
42
|
+
description: `Build the ${spec.noun} from its plan (${spec.buildCredits})`,
|
|
43
|
+
configure: (cmd) => cmd,
|
|
44
|
+
body: () => undefined,
|
|
45
|
+
});
|
|
46
|
+
addStep(root, spec, {
|
|
47
|
+
name: 'revise',
|
|
48
|
+
description: `Revise the ${spec.noun} from feedback (${spec.buildCredits})`,
|
|
49
|
+
configure: (cmd) => cmd.requiredOption('--feedback <text>', 'What to change'),
|
|
50
|
+
body: (options) => ({ feedback: options.feedback }),
|
|
51
|
+
});
|
|
52
|
+
root
|
|
53
|
+
.command('status <id>')
|
|
54
|
+
.description('Show the running step and how the last one ended')
|
|
55
|
+
.action((0, runtime_1.command)(async (id) => {
|
|
56
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
57
|
+
(0, output_1.printResult)(await ctx.client.request('GET', (0, resource_1.resourcePath)(ctx, spec, id, '/run')));
|
|
58
|
+
}));
|
|
59
|
+
(0, resource_1.addCrudCommands)(root, spec);
|
|
60
|
+
return root;
|
|
61
|
+
}
|
|
62
|
+
function addStep(root, spec, step) {
|
|
63
|
+
const cmd = step.configure(root.command(`${step.name} <id>`).description(step.description));
|
|
64
|
+
(0, resource_1.addWaitOptions)(cmd).option('--idempotency-key <key>', 'Idempotency key for safe retries');
|
|
65
|
+
cmd.action((0, runtime_1.command)(async (id, options) => {
|
|
66
|
+
const timeoutSeconds = (0, resource_1.parseTimeout)(options);
|
|
67
|
+
const ctx = await (0, context_1.resolveContentContext)();
|
|
68
|
+
const accepted = await startStep(ctx, spec, id, step.name, step.body(options), options);
|
|
69
|
+
(0, output_1.printResult)(options.wait
|
|
70
|
+
? await (0, runs_1.waitForResourceRun)(ctx, spec.path, id, accepted.runId ?? undefined, timeoutSeconds)
|
|
71
|
+
: accepted);
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
function startStep(ctx, spec, id, step, body, options) {
|
|
75
|
+
return ctx.client.request('POST', (0, resource_1.resourcePath)(ctx, spec, id, `/${step}`), body, {
|
|
76
|
+
...ASYNC_HEADERS,
|
|
77
|
+
...(0, args_1.idempotencyHeaders)(options.idempotencyKey),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function gameCommand() {
|
|
81
|
+
return interactiveCommand({
|
|
82
|
+
path: 'games',
|
|
83
|
+
noun: 'game',
|
|
84
|
+
command: 'game',
|
|
85
|
+
description: 'Create, plan and build classroom games',
|
|
86
|
+
briefCredits: '1 credit',
|
|
87
|
+
buildCredits: '40 credits',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function simulationCommand() {
|
|
91
|
+
return interactiveCommand({
|
|
92
|
+
path: 'simulations',
|
|
93
|
+
noun: 'simulation',
|
|
94
|
+
command: 'simulation',
|
|
95
|
+
description: 'Create, plan and build classroom simulations',
|
|
96
|
+
briefCredits: '1 credit',
|
|
97
|
+
buildCredits: '20 credits for 2D, 30 for 3D',
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=interactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/commands/interactive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learner.d.ts","sourceRoot":"","sources":["../../src/commands/learner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,sFAAsF;AACtF,wBAAgB,cAAc,IAAI,OAAO,CAsFxC"}
|