@happyvertical/smrt-education 0.57.43 → 0.57.44
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/AGENTS.md +12 -0
- package/README.md +5 -0
- package/agents/course-authoring-service.md +179 -0
- package/agents/course-generation-review.md +79 -0
- package/agents/learner-service.md +33 -0
- package/agents/question-records.md +100 -0
- package/dist/chunks/{workbook-photo-service-C6mbUUp6.js → workbook-photo-service-BxvZDqjM.js} +1440 -309
- package/dist/chunks/workbook-photo-service-BxvZDqjM.js.map +1 -0
- package/dist/course-append-only.d.ts +15 -0
- package/dist/course-append-only.d.ts.map +1 -0
- package/dist/course-authoring-contracts.d.ts +464 -0
- package/dist/course-authoring-contracts.d.ts.map +1 -0
- package/dist/course-authoring-licence.d.ts +15 -0
- package/dist/course-authoring-licence.d.ts.map +1 -0
- package/dist/course-authoring-models.d.ts +291 -0
- package/dist/course-authoring-models.d.ts.map +1 -0
- package/dist/course-authoring-service.d.ts +244 -0
- package/dist/course-authoring-service.d.ts.map +1 -0
- package/dist/course-delegation.d.ts +26 -0
- package/dist/course-delegation.d.ts.map +1 -0
- package/dist/course-generation-contracts.d.ts +150 -0
- package/dist/course-generation-contracts.d.ts.map +1 -0
- package/dist/course-generation-models.d.ts +94 -0
- package/dist/course-generation-models.d.ts.map +1 -0
- package/dist/course-generation-output.d.ts +31 -0
- package/dist/course-generation-output.d.ts.map +1 -0
- package/dist/course-generation-proposal-generator.d.ts +94 -0
- package/dist/course-generation-proposal-generator.d.ts.map +1 -0
- package/dist/course-generation-review-service.d.ts +149 -0
- package/dist/course-generation-review-service.d.ts.map +1 -0
- package/dist/course-release-scope.d.ts +37 -0
- package/dist/course-release-scope.d.ts.map +1 -0
- package/dist/course-review-contracts.d.ts +127 -0
- package/dist/course-review-contracts.d.ts.map +1 -0
- package/dist/course-review-digest.d.ts +4 -0
- package/dist/course-review-digest.d.ts.map +1 -0
- package/dist/course-review-evaluation.d.ts +63 -0
- package/dist/course-review-evaluation.d.ts.map +1 -0
- package/dist/course-review-gate.d.ts +15 -0
- package/dist/course-review-gate.d.ts.map +1 -0
- package/dist/course-review-models.d.ts +96 -0
- package/dist/course-review-models.d.ts.map +1 -0
- package/dist/group-sharing-contracts.d.ts +5 -0
- package/dist/group-sharing-contracts.d.ts.map +1 -1
- package/dist/group-sharing-policy.d.ts.map +1 -1
- package/dist/group-sharing-reader.d.ts.map +1 -1
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5658 -116
- package/dist/index.js.map +1 -1
- package/dist/ingestion.js +1 -1
- package/dist/learner-plan-service.d.ts.map +1 -1
- package/dist/learner-service.d.ts +81 -7
- package/dist/learner-service.d.ts.map +1 -1
- package/dist/learners.d.ts +6 -0
- package/dist/learners.d.ts.map +1 -1
- package/dist/manifest.json +14304 -2177
- package/dist/question-authoring-service.d.ts +125 -0
- package/dist/question-authoring-service.d.ts.map +1 -0
- package/dist/question-content.d.ts +25 -0
- package/dist/question-content.d.ts.map +1 -0
- package/dist/question-contracts.d.ts +240 -0
- package/dist/question-contracts.d.ts.map +1 -0
- package/dist/question-models.d.ts +124 -0
- package/dist/question-models.d.ts.map +1 -0
- package/dist/question-render.d.ts +20 -0
- package/dist/question-render.d.ts.map +1 -0
- package/dist/question-response-contracts.d.ts +54 -0
- package/dist/question-response-contracts.d.ts.map +1 -0
- package/dist/question-response-service.d.ts +63 -0
- package/dist/question-response-service.d.ts.map +1 -0
- package/dist/question-rubric.d.ts +23 -0
- package/dist/question-rubric.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +5410 -910
- package/dist/submission-service.d.ts.map +1 -1
- package/dist/submissions.d.ts +5 -0
- package/dist/submissions.d.ts.map +1 -1
- package/dist/workbook-contracts.d.ts +6 -0
- package/dist/workbook-contracts.d.ts.map +1 -1
- package/dist/workbook-models.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/chunks/workbook-photo-service-C6mbUUp6.js.map +0 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { CourseAuthoringError } from './course-authoring-contracts.js';
|
|
2
|
+
export type CourseGenerationStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
|
|
3
|
+
export declare const COURSE_GENERATION_STATUSES: readonly CourseGenerationStatus[];
|
|
4
|
+
export declare const COURSE_GENERATION_TERMINAL: readonly CourseGenerationStatus[];
|
|
5
|
+
/** Provider identity, shaped like the ingestion `ProviderIdentity`. */
|
|
6
|
+
export interface CourseGeneratorIdentity {
|
|
7
|
+
provider: string;
|
|
8
|
+
model: string;
|
|
9
|
+
version: string;
|
|
10
|
+
}
|
|
11
|
+
/** What a generator is given: the exact snapshot retained on the job. */
|
|
12
|
+
export interface CourseGeneratorRequest {
|
|
13
|
+
tenantId: string;
|
|
14
|
+
courseId: string;
|
|
15
|
+
jobId: string;
|
|
16
|
+
instruction: string;
|
|
17
|
+
/** Immutable snapshot of the base revision; never contains answer keys. */
|
|
18
|
+
material: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Host-injected generation port. It matches the ingestion `ProposalGenerator`
|
|
22
|
+
* result contract (untrusted `output`, optional `usage` and `responseModel`).
|
|
23
|
+
* The service never selects a provider; the output is validated against the
|
|
24
|
+
* closed proposal schema before anything is written.
|
|
25
|
+
*/
|
|
26
|
+
export interface CourseMaterialGenerator {
|
|
27
|
+
identity: CourseGeneratorIdentity;
|
|
28
|
+
generate(request: CourseGeneratorRequest, options: {
|
|
29
|
+
signal: AbortSignal;
|
|
30
|
+
maxOutputBytes: number;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
output: unknown;
|
|
33
|
+
completion: 'complete' | 'unknown';
|
|
34
|
+
usage?: Record<string, number>;
|
|
35
|
+
responseModel?: string;
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
38
|
+
export interface CourseGenerationLimits {
|
|
39
|
+
timeoutMs: number;
|
|
40
|
+
maxOutputBytes: number;
|
|
41
|
+
}
|
|
42
|
+
/** Closed, validated generation output. Absent members are not proposed. */
|
|
43
|
+
export interface CourseGenerationProposalLesson {
|
|
44
|
+
/** Existing lesson to propose changes to; omitted for a new lesson. */
|
|
45
|
+
lessonKey?: string;
|
|
46
|
+
/** New lessons only. */
|
|
47
|
+
sectionKey?: string;
|
|
48
|
+
sectionTitle?: string;
|
|
49
|
+
title?: string;
|
|
50
|
+
body?: string;
|
|
51
|
+
estimatedMinutes?: number;
|
|
52
|
+
difficulty?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface CourseGenerationProposal {
|
|
55
|
+
course: {
|
|
56
|
+
summary?: string;
|
|
57
|
+
subject?: string;
|
|
58
|
+
objectives?: string[];
|
|
59
|
+
};
|
|
60
|
+
lessons: CourseGenerationProposalLesson[];
|
|
61
|
+
rationale: string;
|
|
62
|
+
}
|
|
63
|
+
export type CourseProposalFieldStatus = 'added' | 'filled' | 'conflict' | 'unchanged';
|
|
64
|
+
export type CourseProposalDecisionKind = 'accepted' | 'rejected';
|
|
65
|
+
/** One field of the supplied-versus-proposed comparison. */
|
|
66
|
+
export interface CourseProposalFieldView {
|
|
67
|
+
/** `course.summary`, `lesson:<key>.body` or `new-lesson:<n>`. */
|
|
68
|
+
field: string;
|
|
69
|
+
status: CourseProposalFieldStatus;
|
|
70
|
+
/** Supplied value when the proposal was made; null when there was none. */
|
|
71
|
+
supplied: unknown;
|
|
72
|
+
proposed: unknown;
|
|
73
|
+
/** Value in the current draft head; differs from `supplied` once edited. */
|
|
74
|
+
current: unknown;
|
|
75
|
+
/** A conflict stays undecided until a guardian or delegate decides it. */
|
|
76
|
+
decision: CourseProposalDecisionKind | null;
|
|
77
|
+
}
|
|
78
|
+
export interface CourseProposalView {
|
|
79
|
+
proposalId: string;
|
|
80
|
+
jobId: string;
|
|
81
|
+
courseId: string;
|
|
82
|
+
baseRevisionId: string;
|
|
83
|
+
/** The new draft revision holding only additions and fills. */
|
|
84
|
+
resultRevisionId: string;
|
|
85
|
+
rationale: string;
|
|
86
|
+
fields: CourseProposalFieldView[];
|
|
87
|
+
}
|
|
88
|
+
export interface CourseGenerationUsageView {
|
|
89
|
+
inputTokens: number | null;
|
|
90
|
+
outputTokens: number | null;
|
|
91
|
+
cost: number | null;
|
|
92
|
+
costCurrency: string | null;
|
|
93
|
+
raw: Record<string, number>;
|
|
94
|
+
}
|
|
95
|
+
export interface CourseGenerationEventView {
|
|
96
|
+
sequence: number;
|
|
97
|
+
status: CourseGenerationStatus;
|
|
98
|
+
provider: string;
|
|
99
|
+
model: string;
|
|
100
|
+
version: string;
|
|
101
|
+
responseModel: string;
|
|
102
|
+
usage: CourseGenerationUsageView;
|
|
103
|
+
errorCode: string | null;
|
|
104
|
+
detail: string;
|
|
105
|
+
proposalId: string | null;
|
|
106
|
+
resultRevisionId: string | null;
|
|
107
|
+
actorUserId: string;
|
|
108
|
+
delegatingGuardianUserId: string | null;
|
|
109
|
+
delegationId: string | null;
|
|
110
|
+
recordedAt: string;
|
|
111
|
+
}
|
|
112
|
+
export interface CourseGenerationView {
|
|
113
|
+
jobId: string;
|
|
114
|
+
courseId: string;
|
|
115
|
+
baseRevisionId: string;
|
|
116
|
+
requestKey: string;
|
|
117
|
+
instruction: string;
|
|
118
|
+
status: CourseGenerationStatus;
|
|
119
|
+
provider: string;
|
|
120
|
+
model: string;
|
|
121
|
+
usage: CourseGenerationUsageView;
|
|
122
|
+
errorCode: string | null;
|
|
123
|
+
proposalId: string | null;
|
|
124
|
+
resultRevisionId: string | null;
|
|
125
|
+
requestedByUserId: string;
|
|
126
|
+
delegatingGuardianUserId: string | null;
|
|
127
|
+
delegationId: string | null;
|
|
128
|
+
events: CourseGenerationEventView[];
|
|
129
|
+
}
|
|
130
|
+
export declare class CourseGeneratorNotConfiguredError extends CourseAuthoringError {
|
|
131
|
+
constructor();
|
|
132
|
+
}
|
|
133
|
+
export declare class CourseGenerationNotFoundError extends CourseAuthoringError {
|
|
134
|
+
constructor();
|
|
135
|
+
}
|
|
136
|
+
export declare class CourseGenerationInProgressError extends CourseAuthoringError {
|
|
137
|
+
constructor();
|
|
138
|
+
}
|
|
139
|
+
export declare class CourseGenerationOutputError extends CourseAuthoringError {
|
|
140
|
+
readonly path: string;
|
|
141
|
+
constructor(path: string);
|
|
142
|
+
}
|
|
143
|
+
export declare class CourseProposalNotFoundError extends CourseAuthoringError {
|
|
144
|
+
constructor();
|
|
145
|
+
}
|
|
146
|
+
export declare class CourseProposalFieldError extends CourseAuthoringError {
|
|
147
|
+
readonly fields: readonly string[];
|
|
148
|
+
constructor(fields: readonly string[]);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=course-generation-contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-generation-contracts.d.ts","sourceRoot":"","sources":["../src/course-generation-contracts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { SmrtCollection, SmrtObject, type SmrtSaveOptions } from '@happyvertical/smrt-core';
|
|
2
|
+
/** Immutable generation request with its retained input snapshot. */
|
|
3
|
+
export declare class CourseGenerationJob extends SmrtObject {
|
|
4
|
+
tenantId: string;
|
|
5
|
+
courseId: string;
|
|
6
|
+
baseRevisionId: string;
|
|
7
|
+
requestKey: string;
|
|
8
|
+
payloadDigest: string;
|
|
9
|
+
instruction: string;
|
|
10
|
+
/** The exact material snapshot offered to the provider. */
|
|
11
|
+
inputJson: string;
|
|
12
|
+
requestedByUserId: string;
|
|
13
|
+
delegatingGuardianUserId: string;
|
|
14
|
+
delegationId: string;
|
|
15
|
+
recordedAt: Date;
|
|
16
|
+
constructor(options?: Record<string, unknown>);
|
|
17
|
+
delete(): Promise<void>;
|
|
18
|
+
save(options?: SmrtSaveOptions): Promise<this>;
|
|
19
|
+
}
|
|
20
|
+
export declare class CourseGenerationJobCollection extends SmrtCollection<CourseGenerationJob> {
|
|
21
|
+
static readonly _itemClass: typeof CourseGenerationJob;
|
|
22
|
+
}
|
|
23
|
+
/** Append-only status log; the highest sequence is the job's status and outcome. */
|
|
24
|
+
export declare class CourseGenerationEvent extends SmrtObject {
|
|
25
|
+
tenantId: string;
|
|
26
|
+
jobId: string;
|
|
27
|
+
courseId: string;
|
|
28
|
+
sequence: number;
|
|
29
|
+
status: string;
|
|
30
|
+
provider: string;
|
|
31
|
+
model: string;
|
|
32
|
+
version: string;
|
|
33
|
+
responseModel: string;
|
|
34
|
+
inputTokens: number | null;
|
|
35
|
+
outputTokens: number | null;
|
|
36
|
+
cost: number | null;
|
|
37
|
+
costCurrency: string | null;
|
|
38
|
+
usageJson: string;
|
|
39
|
+
errorCode: string | null;
|
|
40
|
+
detail: string;
|
|
41
|
+
proposalId: string | null;
|
|
42
|
+
resultRevisionId: string | null;
|
|
43
|
+
actorUserId: string;
|
|
44
|
+
delegatingGuardianUserId: string;
|
|
45
|
+
delegationId: string;
|
|
46
|
+
requestKey: string;
|
|
47
|
+
recordedAt: Date;
|
|
48
|
+
constructor(options?: Record<string, unknown>);
|
|
49
|
+
delete(): Promise<void>;
|
|
50
|
+
save(options?: SmrtSaveOptions): Promise<this>;
|
|
51
|
+
}
|
|
52
|
+
export declare class CourseGenerationEventCollection extends SmrtCollection<CourseGenerationEvent> {
|
|
53
|
+
static readonly _itemClass: typeof CourseGenerationEvent;
|
|
54
|
+
}
|
|
55
|
+
/** The validated proposal for one job and its supplied-versus-proposed plan. */
|
|
56
|
+
export declare class CourseProposal extends SmrtObject {
|
|
57
|
+
tenantId: string;
|
|
58
|
+
jobId: string;
|
|
59
|
+
courseId: string;
|
|
60
|
+
baseRevisionId: string;
|
|
61
|
+
resultRevisionId: string;
|
|
62
|
+
rationale: string;
|
|
63
|
+
proposalJson: string;
|
|
64
|
+
planJson: string;
|
|
65
|
+
recordedAt: Date;
|
|
66
|
+
constructor(options?: Record<string, unknown>);
|
|
67
|
+
delete(): Promise<void>;
|
|
68
|
+
save(options?: SmrtSaveOptions): Promise<this>;
|
|
69
|
+
}
|
|
70
|
+
export declare class CourseProposalCollection extends SmrtCollection<CourseProposal> {
|
|
71
|
+
static readonly _itemClass: typeof CourseProposal;
|
|
72
|
+
}
|
|
73
|
+
/** Explicit, recorded accept or reject of conflicting proposal fields. */
|
|
74
|
+
export declare class CourseProposalDecision extends SmrtObject {
|
|
75
|
+
tenantId: string;
|
|
76
|
+
proposalId: string;
|
|
77
|
+
courseId: string;
|
|
78
|
+
decision: string;
|
|
79
|
+
fieldsJson: string;
|
|
80
|
+
resultRevisionId: string | null;
|
|
81
|
+
actorUserId: string;
|
|
82
|
+
delegatingGuardianUserId: string;
|
|
83
|
+
delegationId: string;
|
|
84
|
+
requestKey: string;
|
|
85
|
+
payloadDigest: string;
|
|
86
|
+
recordedAt: Date;
|
|
87
|
+
constructor(options?: Record<string, unknown>);
|
|
88
|
+
delete(): Promise<void>;
|
|
89
|
+
save(options?: SmrtSaveOptions): Promise<this>;
|
|
90
|
+
}
|
|
91
|
+
export declare class CourseProposalDecisionCollection extends SmrtCollection<CourseProposalDecision> {
|
|
92
|
+
static readonly _itemClass: typeof CourseProposalDecision;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=course-generation-models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-generation-models.d.ts","sourceRoot":"","sources":["../src/course-generation-models.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { CourseDraftInput, CourseRevisionView } from './course-authoring-contracts.js';
|
|
2
|
+
import { type CourseGenerationProposal, type CourseProposalFieldStatus } from './course-generation-contracts.js';
|
|
3
|
+
/**
|
|
4
|
+
* Validates untrusted provider output against the closed proposal schema.
|
|
5
|
+
* `existingLessonKeys` are the lessons of the snapshot the job ran against: a
|
|
6
|
+
* proposal may only address a lesson that exists there.
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateCourseGenerationOutput(output: unknown, existingLessonKeys: ReadonlySet<string>): CourseGenerationProposal;
|
|
9
|
+
/** Field paths a proposal can decide, and how to read the current value. */
|
|
10
|
+
export interface ProposalFieldPlan {
|
|
11
|
+
field: string;
|
|
12
|
+
status: CourseProposalFieldStatus;
|
|
13
|
+
supplied: unknown;
|
|
14
|
+
proposed: unknown;
|
|
15
|
+
}
|
|
16
|
+
/** Per-field comparison of a proposal against the supplied base revision. */
|
|
17
|
+
export declare function planProposal(base: CourseRevisionView, proposal: CourseGenerationProposal): ProposalFieldPlan[];
|
|
18
|
+
/** Stable key for a generated lesson, so a replayed job reproduces the same row. */
|
|
19
|
+
export declare const generatedLessonKey: (jobId: string, index: number) => string;
|
|
20
|
+
/** Rebuilds a draft input from a stored revision, preserving materials and questions. */
|
|
21
|
+
export declare function draftFromRevision(view: CourseRevisionView): CourseDraftInput;
|
|
22
|
+
/**
|
|
23
|
+
* Applies the selected plan entries to a draft built from `view`. Returns
|
|
24
|
+
* the fields that no longer apply (for example a deleted lesson).
|
|
25
|
+
*/
|
|
26
|
+
export declare function applyProposalFields(draft: CourseDraftInput, entries: ReadonlyArray<ProposalFieldPlan>, options: {
|
|
27
|
+
jobId: string;
|
|
28
|
+
}): {
|
|
29
|
+
missing: string[];
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=course-generation-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-generation-output.d.ts","sourceRoot":"","sources":["../src/course-generation-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAEhB,kBAAkB,EACnB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEL,KAAK,wBAAwB,EAE7B,KAAK,yBAAyB,EAC/B,MAAM,kCAAkC,CAAC;AAyC1C;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,OAAO,EACf,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,GACtC,wBAAwB,CAkF1B;AAED,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,yBAAyB,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAmBD,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,kBAAkB,EACxB,QAAQ,EAAE,wBAAwB,GACjC,iBAAiB,EAAE,CA+CrB;AAED,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,WACS,CAAC;AAIzE,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,gBAAgB,CAuC5E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAuEvB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { ProposalGenerator } from '@happyvertical/smrt-ingestion/proposals';
|
|
2
|
+
import type { CourseMaterialGenerator } from './course-generation-contracts.js';
|
|
3
|
+
export declare const COURSE_PROPOSAL_HANDLER = "@happyvertical/smrt-education:propose-course-material";
|
|
4
|
+
/** The closed JSON shape a model is asked to produce; validated again on receipt. */
|
|
5
|
+
export declare const COURSE_PROPOSAL_ARGS_SCHEMA: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly additionalProperties: false;
|
|
8
|
+
readonly properties: {
|
|
9
|
+
readonly course: {
|
|
10
|
+
readonly type: "object";
|
|
11
|
+
readonly additionalProperties: false;
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly summary: {
|
|
14
|
+
type: string;
|
|
15
|
+
minLength: number;
|
|
16
|
+
maxLength: number;
|
|
17
|
+
};
|
|
18
|
+
readonly subject: {
|
|
19
|
+
type: string;
|
|
20
|
+
minLength: number;
|
|
21
|
+
maxLength: number;
|
|
22
|
+
};
|
|
23
|
+
readonly objectives: {
|
|
24
|
+
readonly type: "array";
|
|
25
|
+
readonly minItems: 1;
|
|
26
|
+
readonly maxItems: 50;
|
|
27
|
+
readonly items: {
|
|
28
|
+
type: string;
|
|
29
|
+
minLength: number;
|
|
30
|
+
maxLength: number;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
readonly lessons: {
|
|
36
|
+
readonly type: "array";
|
|
37
|
+
readonly maxItems: 50;
|
|
38
|
+
readonly items: {
|
|
39
|
+
readonly type: "object";
|
|
40
|
+
readonly additionalProperties: false;
|
|
41
|
+
readonly properties: {
|
|
42
|
+
readonly lessonKey: {
|
|
43
|
+
type: string;
|
|
44
|
+
minLength: number;
|
|
45
|
+
maxLength: number;
|
|
46
|
+
};
|
|
47
|
+
readonly sectionKey: {
|
|
48
|
+
type: string;
|
|
49
|
+
minLength: number;
|
|
50
|
+
maxLength: number;
|
|
51
|
+
};
|
|
52
|
+
readonly sectionTitle: {
|
|
53
|
+
type: string;
|
|
54
|
+
minLength: number;
|
|
55
|
+
maxLength: number;
|
|
56
|
+
};
|
|
57
|
+
readonly title: {
|
|
58
|
+
type: string;
|
|
59
|
+
minLength: number;
|
|
60
|
+
maxLength: number;
|
|
61
|
+
};
|
|
62
|
+
readonly body: {
|
|
63
|
+
type: string;
|
|
64
|
+
minLength: number;
|
|
65
|
+
maxLength: number;
|
|
66
|
+
};
|
|
67
|
+
readonly estimatedMinutes: {
|
|
68
|
+
readonly type: "integer";
|
|
69
|
+
readonly minimum: 1;
|
|
70
|
+
readonly maximum: 1440;
|
|
71
|
+
};
|
|
72
|
+
readonly difficulty: {
|
|
73
|
+
readonly type: "integer";
|
|
74
|
+
readonly minimum: 1;
|
|
75
|
+
readonly maximum: 10;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
readonly rationale: {
|
|
81
|
+
type: string;
|
|
82
|
+
minLength: number;
|
|
83
|
+
maxLength: number;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Adapts an ingestion `ProposalGenerator` (the host's trusted SDK-bound
|
|
89
|
+
* adapter) to the course generation port. The material is offered as one
|
|
90
|
+
* evidence segment; the model's output stays untrusted and is validated by the
|
|
91
|
+
* service against the closed proposal schema. No provider is chosen here.
|
|
92
|
+
*/
|
|
93
|
+
export declare function createProposalCourseGenerator(generator: ProposalGenerator): CourseMaterialGenerator;
|
|
94
|
+
//# sourceMappingURL=course-generation-proposal-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-generation-proposal-generator.d.ts","sourceRoot":"","sources":["../src/course-generation-proposal-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,kCAAkC,CAAC;AAG1C,eAAO,MAAM,uBAAuB,0DACqB,CAAC;AAO1D,qFAAqF;AACrF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqC9B,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,iBAAiB,GAC3B,uBAAuB,CAoDzB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import { type CourseAuthoringActor, type CourseAuthoringAuthorizer } from './course-authoring-contracts.js';
|
|
3
|
+
import { type CourseGenerationLimits, type CourseGenerationView, type CourseMaterialGenerator, type CourseProposalView } from './course-generation-contracts.js';
|
|
4
|
+
import { type CourseFindingResolutionKind, type CourseReviewContextInput, type CourseReviewFindingInput, type CourseReviewView } from './course-review-contracts.js';
|
|
5
|
+
import { QuestionAuthoringService, type QuestionAuthoringServiceOptions } from './question-authoring-service.js';
|
|
6
|
+
type Tx = DatabaseInterface;
|
|
7
|
+
export interface CourseGenerationReviewServiceOptions extends QuestionAuthoringServiceOptions {
|
|
8
|
+
/** Host-supplied generation port; without it `runGeneration` fails closed. */
|
|
9
|
+
generator?: CourseMaterialGenerator;
|
|
10
|
+
generationLimits?: Partial<CourseGenerationLimits>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generation proposals and revision-bound educational review (SMRT #4516).
|
|
14
|
+
* It extends `QuestionAuthoringService`, so it adds only the generation and
|
|
15
|
+
* review operations and uses the same authorizer, tenancy checks and CAS save
|
|
16
|
+
* path. Its release gate and discard guard default to the review-backed ones.
|
|
17
|
+
*/
|
|
18
|
+
export declare class CourseGenerationReviewService extends QuestionAuthoringService {
|
|
19
|
+
private readonly generator;
|
|
20
|
+
private readonly limits;
|
|
21
|
+
constructor(db: DatabaseInterface, authorizer: CourseAuthoringAuthorizer, options?: CourseGenerationReviewServiceOptions);
|
|
22
|
+
private baseView;
|
|
23
|
+
/** Provider-facing snapshot: no keys, assets or personal-use lesson bodies. */
|
|
24
|
+
private material;
|
|
25
|
+
private jobRow;
|
|
26
|
+
private jobEvents;
|
|
27
|
+
private usageView;
|
|
28
|
+
private eventView;
|
|
29
|
+
private generationView;
|
|
30
|
+
private appendEvent;
|
|
31
|
+
/**
|
|
32
|
+
* Records a generation request against the draft head the caller saw. A
|
|
33
|
+
* retried key returns the existing job and its proposal; the same key with
|
|
34
|
+
* different input is a typed conflict. Nothing is generated or written to the
|
|
35
|
+
* draft here.
|
|
36
|
+
*/
|
|
37
|
+
requestGeneration(request: CourseAuthoringActor & {
|
|
38
|
+
courseId: string;
|
|
39
|
+
expectedHeadRevisionId: string;
|
|
40
|
+
requestKey: string;
|
|
41
|
+
instruction?: string;
|
|
42
|
+
}): Promise<CourseGenerationView>;
|
|
43
|
+
/**
|
|
44
|
+
* Runs a queued job through the injected generator outside any transaction,
|
|
45
|
+
* then records the outcome. Success writes a new draft revision holding only
|
|
46
|
+
* additions and fills; conflicting proposals wait for an explicit decision.
|
|
47
|
+
* Failure, timeout, cancellation, a stale head or invalid output leave the
|
|
48
|
+
* head unchanged and keep the input.
|
|
49
|
+
*/
|
|
50
|
+
runGeneration(request: CourseAuthoringActor & {
|
|
51
|
+
jobId: string;
|
|
52
|
+
}): Promise<CourseGenerationView>;
|
|
53
|
+
/** Cancels a queued or running job; a finished job is returned unchanged. */
|
|
54
|
+
cancelGeneration(request: CourseAuthoringActor & {
|
|
55
|
+
jobId: string;
|
|
56
|
+
requestKey: string;
|
|
57
|
+
}): Promise<CourseGenerationView>;
|
|
58
|
+
getGeneration(request: CourseAuthoringActor & {
|
|
59
|
+
jobId: string;
|
|
60
|
+
}): Promise<CourseGenerationView>;
|
|
61
|
+
private currentValue;
|
|
62
|
+
private proposalView;
|
|
63
|
+
private proposalRow;
|
|
64
|
+
/** Supplied-versus-proposed comparison, per field, against the current head. */
|
|
65
|
+
getProposal(request: CourseAuthoringActor & {
|
|
66
|
+
courseId: string;
|
|
67
|
+
proposalId: string;
|
|
68
|
+
}): Promise<CourseProposalView>;
|
|
69
|
+
/**
|
|
70
|
+
* Explicitly accepts or rejects conflicting proposal fields. Accepting appends
|
|
71
|
+
* a new draft revision on the expected head (compare and swap); supplied
|
|
72
|
+
* content is replaced only by this recorded decision.
|
|
73
|
+
*/
|
|
74
|
+
decideProposal(request: CourseAuthoringActor & {
|
|
75
|
+
courseId: string;
|
|
76
|
+
proposalId: string;
|
|
77
|
+
expectedHeadRevisionId: string;
|
|
78
|
+
decision: 'accept' | 'reject';
|
|
79
|
+
fields: string[];
|
|
80
|
+
requestKey: string;
|
|
81
|
+
}): Promise<CourseProposalView & {
|
|
82
|
+
headRevisionId: string;
|
|
83
|
+
}>;
|
|
84
|
+
private normalizeFindings;
|
|
85
|
+
private reviewContext;
|
|
86
|
+
private reviewView;
|
|
87
|
+
/** Revision ids a finding may point at: the course revision, its lessons and questions. */
|
|
88
|
+
private targetIds;
|
|
89
|
+
/**
|
|
90
|
+
* Records an educational review of one exact revision, authored by the
|
|
91
|
+
* caller (a guardian, or an agent for its delegating guardian). The review
|
|
92
|
+
* has no score; level target and theme come from the revision, and a learner
|
|
93
|
+
* review must name the evidence snapshot it used.
|
|
94
|
+
*/
|
|
95
|
+
recordReview(request: CourseAuthoringActor & {
|
|
96
|
+
courseId: string;
|
|
97
|
+
revisionId: string;
|
|
98
|
+
requestKey: string;
|
|
99
|
+
context?: CourseReviewContextInput;
|
|
100
|
+
generalSummary?: string;
|
|
101
|
+
learnerSummary?: string;
|
|
102
|
+
findings: CourseReviewFindingInput[];
|
|
103
|
+
reviewer?: {
|
|
104
|
+
provider?: string;
|
|
105
|
+
model?: string;
|
|
106
|
+
};
|
|
107
|
+
}): Promise<CourseReviewView>;
|
|
108
|
+
/** Reviews of a course, newest first, with findings, resolutions and outdated state. */
|
|
109
|
+
listReviews(request: CourseAuthoringActor & {
|
|
110
|
+
courseId: string;
|
|
111
|
+
revisionId?: string;
|
|
112
|
+
}): Promise<CourseReviewView[]>;
|
|
113
|
+
getReview(request: CourseAuthoringActor & {
|
|
114
|
+
courseId: string;
|
|
115
|
+
reviewId: string;
|
|
116
|
+
}): Promise<CourseReviewView>;
|
|
117
|
+
private markOutdated;
|
|
118
|
+
/** A new draft revision makes every review of an earlier revision outdated. */
|
|
119
|
+
protected onDraftRevisionAppended(tx: Tx, actor: CourseAuthoringActor, revision: {
|
|
120
|
+
courseId: string;
|
|
121
|
+
revisionId: string;
|
|
122
|
+
}): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Records that a learner's evidence snapshot changed: learner reviews of this
|
|
125
|
+
* course that used a different snapshot become outdated.
|
|
126
|
+
*/
|
|
127
|
+
noteContextChange(request: CourseAuthoringActor & {
|
|
128
|
+
courseId: string;
|
|
129
|
+
learnerId: string;
|
|
130
|
+
evidenceSnapshotRef: string;
|
|
131
|
+
requestKey: string;
|
|
132
|
+
}): Promise<{
|
|
133
|
+
outdatedReviewIds: string[];
|
|
134
|
+
}>;
|
|
135
|
+
/**
|
|
136
|
+
* Resolves one finding. Only a person may resolve a finding flagged for human
|
|
137
|
+
* verification; a delegated agent is refused. Release stays blocked while any
|
|
138
|
+
* blocking or human-verification finding is unresolved.
|
|
139
|
+
*/
|
|
140
|
+
resolveFinding(request: CourseAuthoringActor & {
|
|
141
|
+
courseId: string;
|
|
142
|
+
findingId: string;
|
|
143
|
+
resolution: CourseFindingResolutionKind;
|
|
144
|
+
note?: string;
|
|
145
|
+
requestKey: string;
|
|
146
|
+
}): Promise<CourseReviewView>;
|
|
147
|
+
}
|
|
148
|
+
export {};
|
|
149
|
+
//# sourceMappingURL=course-generation-review-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-generation-review-service.d.ts","sourceRoot":"","sources":["../src/course-generation-review-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import type { EffectiveLessonView } from './course-authoring-contracts.js';
|
|
3
|
+
/**
|
|
4
|
+
* The single rule for which immutable lesson rows apply to a pinned enrollment.
|
|
5
|
+
* Callers authorize the actor and enrollment first; every read here is bound to
|
|
6
|
+
* the supplied executor (so it joins the caller's transaction) and the exact
|
|
7
|
+
* tenant and enrollment. `getEnrollmentRelease` and the learner projections both
|
|
8
|
+
* call this, so the two can never disagree.
|
|
9
|
+
*/
|
|
10
|
+
export type EnrollmentLessonSelection = Readonly<{
|
|
11
|
+
/** The release the enrollment currently follows. */
|
|
12
|
+
currentReleaseId: string;
|
|
13
|
+
/** Every release the enrollment has been pinned to, oldest first. */
|
|
14
|
+
lineage: ReadonlyArray<string>;
|
|
15
|
+
/** Effective lessons, sorted by stable lessonKey. */
|
|
16
|
+
lessons: EffectiveLessonView[];
|
|
17
|
+
/** The materialized Course row of each release that contributes a lesson. */
|
|
18
|
+
releaseCourseIds: ReadonlyMap<string, string>;
|
|
19
|
+
/** Stable lessonKey to lesson row id, per release in the lineage. */
|
|
20
|
+
keysByRelease: ReadonlyMap<string, ReadonlyMap<string, string>>;
|
|
21
|
+
/** Learner ids recorded on the pins (a mismatch with the enrollment fails closed). */
|
|
22
|
+
pinLearnerIds: ReadonlySet<string>;
|
|
23
|
+
}>;
|
|
24
|
+
/**
|
|
25
|
+
* Started lessons stay on the immutable row they were started on, in every
|
|
26
|
+
* release the enrollment has followed; unstarted lessons follow the current
|
|
27
|
+
* release. Returns null for an enrollment that has never been pinned.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveEnrollmentLessons(db: DatabaseInterface, tenantId: string, enrollmentId: string): Promise<EnrollmentLessonSelection | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Orders effective lessons for learners: the current release's own order first,
|
|
32
|
+
* then lessons kept only because they were started (removed from the current
|
|
33
|
+
* release) by release age and their original order. `orderOf` lists a release's
|
|
34
|
+
* lesson row ids in course order.
|
|
35
|
+
*/
|
|
36
|
+
export declare function orderEffectiveLessons(selection: EnrollmentLessonSelection, orderOf: (releaseId: string) => ReadonlyArray<string>): EffectiveLessonView[];
|
|
37
|
+
//# sourceMappingURL=course-release-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"course-release-scope.d.ts","sourceRoot":"","sources":["../src/course-release-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAM3E;;;;;;GAMG;AACH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/B,qDAAqD;IACrD,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,6EAA6E;IAC7E,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,qEAAqE;IACrE,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE,sFAAsF;IACtF,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC,CAAC,CAAC;AAEH;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,iBAAiB,EACrB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAwE3C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,yBAAyB,EACpC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,aAAa,CAAC,MAAM,CAAC,GACpD,mBAAmB,EAAE,CAuBvB"}
|