@happyvertical/smrt-education 0.57.45 → 0.57.47
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 +5 -0
- package/README.md +7 -1
- package/agents/learner-service.md +31 -2
- package/agents/question-extraction.md +108 -0
- package/agents/submission-service.md +15 -0
- package/dist/chunks/{workbook-photo-service-DKgoUHeb.js → workbook-photo-service-B7Tujv__.js} +6494 -1153
- package/dist/chunks/workbook-photo-service-B7Tujv__.js.map +1 -0
- package/dist/collections.d.ts +4 -1
- package/dist/collections.d.ts.map +1 -1
- package/dist/course-authoring-contracts.d.ts +1 -1
- package/dist/course-authoring-contracts.d.ts.map +1 -1
- package/dist/index.d.ts +11 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1049 -4628
- package/dist/index.js.map +1 -1
- package/dist/ingestion.d.ts +2 -0
- package/dist/ingestion.d.ts.map +1 -1
- package/dist/ingestion.js +197 -2
- package/dist/ingestion.js.map +1 -1
- package/dist/learner-history.d.ts +50 -0
- package/dist/learner-history.d.ts.map +1 -0
- package/dist/learner-service.d.ts +78 -2
- package/dist/learner-service.d.ts.map +1 -1
- package/dist/manifest.json +4255 -1444
- package/dist/question-extraction-contracts.d.ts +231 -0
- package/dist/question-extraction-contracts.d.ts.map +1 -0
- package/dist/question-extraction-ingestion.d.ts +44 -0
- package/dist/question-extraction-ingestion.d.ts.map +1 -0
- package/dist/question-extraction-models.d.ts +56 -0
- package/dist/question-extraction-models.d.ts.map +1 -0
- package/dist/question-extraction-service.d.ts +71 -0
- package/dist/question-extraction-service.d.ts.map +1 -0
- package/dist/question-extraction.d.ts +317 -0
- package/dist/question-extraction.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +961 -143
- package/dist/submission-service.d.ts +34 -1
- package/dist/submission-service.d.ts.map +1 -1
- package/dist/submissions.d.ts +25 -1
- package/dist/submissions.d.ts.map +1 -1
- package/package.json +10 -10
- package/dist/chunks/workbook-photo-service-DKgoUHeb.js.map +0 -1
package/dist/ingestion.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export declare function captureEducationIntake(input: {
|
|
|
73
73
|
}>;
|
|
74
74
|
awaitingParentRelease?: boolean;
|
|
75
75
|
sourceRequiresParentRelease?: boolean;
|
|
76
|
+
selfReported?: boolean;
|
|
76
77
|
grade: null | {
|
|
77
78
|
id: string;
|
|
78
79
|
graderKind: import("./submissions.js").Grade["graderKind"];
|
|
@@ -138,5 +139,6 @@ export declare function preserveWorkbookIntakeAnalysis(input: {
|
|
|
138
139
|
}): Promise<WorkbookPreservationResult>;
|
|
139
140
|
export { receiveFamilyIntake, retainFamilyIntakeReceipt, } from './family-intake-ingestion.js';
|
|
140
141
|
export { FamilyIntakeService } from './family-intake-service.js';
|
|
142
|
+
export { educationQuestionExtractionHandler, preserveQuestionExtractionAnalysis, QUESTION_EXTRACTION_HANDLER_ID, questionExtractionGrounding, } from './question-extraction-ingestion.js';
|
|
141
143
|
export { preserveWorkbookPhotoIdentification, processWorkbookPhotoAnalysis, receiveWorkbookPhotoIntake, retainWorkbookPhotoReceipt, WORKBOOK_PHOTO_HANDLER, workbookPhotoIntakeHandlers, workbookPhotoIntakeTargetResolver, } from './workbook-photo-ingestion.js';
|
|
142
144
|
//# sourceMappingURL=ingestion.d.ts.map
|
package/dist/ingestion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingestion.d.ts","sourceRoot":"","sources":["../src/ingestion.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EAGrB,KAAK,gBAAgB,EAGtB,MAAM,sCAAsC,CAAC;AAM9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAEvE,oFAAoF;AACpF,MAAM,WAAW,gCAAgC;IAC/C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,gBAAgB,EAC3B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,gCAAgC,EAC/C,YAAY,CAAC,EAAE,MAAM;;;GAOtB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IACpD,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,UAAU,EAAE,gCAAgC,CAAC;CAC9C,GAAG,OAAO,CACP;IAAE,IAAI,EAAE,WAAW,GAAG,uBAAuB,GAAG,aAAa,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAClD,CAsCA;AAGD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAG3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAIL,KAAK,kBAAkB,EAGxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,6BAA6B,GAAG,cAAc,GAAG;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,yBAAyB,EAAE,kBAAkB,CAAC;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAAC;IAC3C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,SAAS,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAChC,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,EAAE,6BAA6B,CAAC;CACxC
|
|
1
|
+
{"version":3,"file":"ingestion.d.ts","sourceRoot":"","sources":["../src/ingestion.ts"],"names":[],"mappings":"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"}
|
package/dist/ingestion.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as LearnerAuthorizationError, At as workbookAggregateFeedback, Bt as FamilyIntakeAssetCollection, D as QUESTION_EXTRACTION_ARGS_SCHEMA, Et as WorkbookAssessmentValidationError, Ot as aggregateWorkbookQuestions, S as questionExtractionProposalDigest, Tt as WORKBOOK_MATH_VOCABULARY, Ut as FamilyIntakeDecisionCollection, Vt as FamilyIntakeCollection, Wt as familyIntakeScopeId, X as QuestionExtractionValidationError, Y as QuestionExtractionPendingError, d as WorkbookPhotoIntakeCollection, f as validateWorkbookPhotoIdentification, kt as validateWorkbookAssessment, m as normalizeWorkbookAnswerRegions, n as preservePhotoProposal, p as normalizeWorkbookObservedLayout, r as WorkbookService, s as WorkbookPhotoAssetCollection, t as WorkbookPhotoService } from "./chunks/workbook-photo-service-B7Tujv__.js";
|
|
2
2
|
import { getCurrentTenant, withTenant } from "@happyvertical/smrt-tenancy";
|
|
3
3
|
import { withPrivateAssetAccess } from "@happyvertical/smrt-assets";
|
|
4
4
|
import { registerPermissionDefinitions } from "@happyvertical/smrt-users";
|
|
@@ -438,6 +438,201 @@ var FamilyIntakeService = class FamilyIntakeService extends WorkbookPhotoService
|
|
|
438
438
|
}
|
|
439
439
|
};
|
|
440
440
|
//#endregion
|
|
441
|
+
//#region src/question-extraction-ingestion.ts
|
|
442
|
+
var QUESTION_EXTRACTION_HANDLER_ID = "@happyvertical/smrt-education:extract-questions";
|
|
443
|
+
var QUESTION = "@happyvertical/smrt-education:Question";
|
|
444
|
+
var MEDIA_TYPES = [
|
|
445
|
+
"image/jpeg",
|
|
446
|
+
"image/png",
|
|
447
|
+
"image/webp",
|
|
448
|
+
"application/pdf"
|
|
449
|
+
];
|
|
450
|
+
registerPermissionDefinitions([{
|
|
451
|
+
slug: "questions.create",
|
|
452
|
+
collection: "questions",
|
|
453
|
+
qualifiedName: QUESTION,
|
|
454
|
+
name: "Apply reviewed question extractions"
|
|
455
|
+
}]);
|
|
456
|
+
var DESCRIPTION = "Extract the printed questions of a scanned worksheet or imported course file as structured data for extraction review. Report every source page in pages with its role (exercise, example, instructions, cover, answer_key, mixed, unknown) and readability; never drop a page. questions holds printed task text only: prompt, numbering exactly as printed, subparts, choices, section, diagram/table/image references and any answer key or rubric printed in the source (origin source). Mark anything you supply yourself origin inferred; never present an inferred key, type or points as printed. Unreadable or unsupported tasks keep their key and numbering with status unreadable/unsupported and prompt null; content you cannot extract goes in omissions. Worked examples use role example. Learner handwriting goes only in studentWork (observed text, or null when illegible), never in prompts or keys; never solve a task and report it as observed work. Keys: printed numbering path (for example 3, 3b), else u:<short printed-task slug>:<occurrence>. worksheetVersionId only when a wsv1- id is printed on the page. Anchors cite original evidenceId, the physical source page (1-based, or null when unknown; printed page numbers are not pages) and regionId only from that evidence observedRegions catalog, else null; never coordinates. Applying needs a human extraction decision; it creates or links question records and never grades or attaches learner work.";
|
|
457
|
+
function bound(request, context, work) {
|
|
458
|
+
if (context.scope.tenantId !== request.tenantId || context.scope.actorId !== request.actorUserId || !context.policy.requireReview) throw new Error("Question extraction scope mismatch");
|
|
459
|
+
if (!context.principal) return work();
|
|
460
|
+
const tenant = getCurrentTenant();
|
|
461
|
+
if (!tenant || tenant.tenantId !== request.tenantId || tenant.userId !== context.principal.context.userId || context.principal.context.tenantId !== request.tenantId) throw new Error("Question extraction principal tenant mismatch");
|
|
462
|
+
return withTenant({
|
|
463
|
+
...tenant,
|
|
464
|
+
tenantId: request.tenantId,
|
|
465
|
+
userId: request.actorUserId,
|
|
466
|
+
superAdminBypass: false
|
|
467
|
+
}, work);
|
|
468
|
+
}
|
|
469
|
+
function summary(view) {
|
|
470
|
+
const count = (outcome) => view.match.questions.filter((m) => m.outcome === outcome).length;
|
|
471
|
+
return {
|
|
472
|
+
extractionId: view.extractionId,
|
|
473
|
+
sourceKind: view.extraction.sourceKind,
|
|
474
|
+
worksheetVersionId: view.match.worksheetVersionId,
|
|
475
|
+
worksheetKnown: view.match.worksheetKnown,
|
|
476
|
+
questions: view.extraction.questions.length,
|
|
477
|
+
matched: count("matched"),
|
|
478
|
+
ambiguous: count("ambiguous"),
|
|
479
|
+
unmatched: count("unmatched"),
|
|
480
|
+
unreadable: view.extraction.questions.filter((q) => q.status === "unreadable" || q.status === "unsupported").length,
|
|
481
|
+
studentWork: view.studentWork.length,
|
|
482
|
+
omissions: view.extraction.omissions.length,
|
|
483
|
+
sourceWarnings: view.extraction.sourceWarnings,
|
|
484
|
+
extractionReviewRequired: true
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
function educationQuestionExtractionHandler(input) {
|
|
488
|
+
const { extractions, request } = input;
|
|
489
|
+
const preserved = async (args, context) => {
|
|
490
|
+
const view = await bound(request, context, () => extractions.withExecutor(context.db).findExtraction({
|
|
491
|
+
...request,
|
|
492
|
+
intakeItemId: context.itemId,
|
|
493
|
+
proposalDigest: questionExtractionProposalDigest(args)
|
|
494
|
+
}));
|
|
495
|
+
if (!view) throw new Error("Question extraction must be preserved before review");
|
|
496
|
+
return view;
|
|
497
|
+
};
|
|
498
|
+
return {
|
|
499
|
+
id: QUESTION_EXTRACTION_HANDLER_ID,
|
|
500
|
+
version: "1",
|
|
501
|
+
label: "Extract questions",
|
|
502
|
+
description: DESCRIPTION,
|
|
503
|
+
operation: {
|
|
504
|
+
model: QUESTION,
|
|
505
|
+
action: "create",
|
|
506
|
+
version: "1"
|
|
507
|
+
},
|
|
508
|
+
capability: {
|
|
509
|
+
effect: "write",
|
|
510
|
+
idempotent: true,
|
|
511
|
+
openWorld: false
|
|
512
|
+
},
|
|
513
|
+
argsSchema: QUESTION_EXTRACTION_ARGS_SCHEMA,
|
|
514
|
+
resultSchema: {
|
|
515
|
+
type: "object",
|
|
516
|
+
additionalProperties: false,
|
|
517
|
+
required: ["extractionId"],
|
|
518
|
+
properties: { extractionId: {
|
|
519
|
+
type: "string",
|
|
520
|
+
minLength: 1,
|
|
521
|
+
maxLength: 64
|
|
522
|
+
} }
|
|
523
|
+
},
|
|
524
|
+
resultModels: {},
|
|
525
|
+
discovery: {
|
|
526
|
+
mediaTypes: MEDIA_TYPES,
|
|
527
|
+
references: {}
|
|
528
|
+
},
|
|
529
|
+
validate: async (args, context) => {
|
|
530
|
+
await preserved(args, context);
|
|
531
|
+
return { ok: true };
|
|
532
|
+
},
|
|
533
|
+
preview: async (args, context) => ({
|
|
534
|
+
display: summary(await preserved(args, context)),
|
|
535
|
+
normalizedArgs: args,
|
|
536
|
+
targetPreconditions: []
|
|
537
|
+
}),
|
|
538
|
+
execution: {
|
|
539
|
+
kind: "database",
|
|
540
|
+
apply: async (args, context) => {
|
|
541
|
+
const view = await preserved(args, context);
|
|
542
|
+
await bound(request, context, () => extractions.withExecutor(context.db).applyExtraction({
|
|
543
|
+
...request,
|
|
544
|
+
extractionId: view.extractionId
|
|
545
|
+
}));
|
|
546
|
+
return { extractionId: view.extractionId };
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function questionExtractionGrounding(snapshot, warnings = []) {
|
|
552
|
+
const results = Array.isArray(snapshot.result.output?.results) ? snapshot.result.output.results : [];
|
|
553
|
+
const originals = intakeOriginalEvidence(snapshot.evidence ?? []).filter((e) => e.mediaType !== "application/json");
|
|
554
|
+
const pagesOf = (location) => {
|
|
555
|
+
const valid = (n) => Number.isSafeInteger(n) && n > 0;
|
|
556
|
+
if (location?.kind === "page" && valid(location.page)) return [location.page];
|
|
557
|
+
if (location?.kind === "pages" && valid(location.startPage) && valid(location.endPage) && location.endPage >= location.startPage) {
|
|
558
|
+
if (location.endPage - location.startPage >= 1e3) throw new QuestionExtractionValidationError("Too many source pages");
|
|
559
|
+
return Array.from({ length: location.endPage - location.startPage + 1 }, (_, i) => location.startPage + i);
|
|
560
|
+
}
|
|
561
|
+
return [];
|
|
562
|
+
};
|
|
563
|
+
const sources = originals.map((evidence) => {
|
|
564
|
+
const base = {
|
|
565
|
+
evidenceId: evidence.id,
|
|
566
|
+
sha256: evidence.contentHash,
|
|
567
|
+
mediaType: evidence.mediaType
|
|
568
|
+
};
|
|
569
|
+
const result = results.find((value) => !!value && typeof value === "object" && value.evidence?.id === evidence.id && value.evidence?.contentHash === evidence.contentHash);
|
|
570
|
+
if (!result) return {
|
|
571
|
+
...base,
|
|
572
|
+
pages: [],
|
|
573
|
+
extracted: false
|
|
574
|
+
};
|
|
575
|
+
const segments = Array.isArray(result.segments) ? result.segments : [];
|
|
576
|
+
const failed = [...Array.isArray(result.omitted) ? result.omitted : [], ...Array.isArray(result.errors) ? result.errors.map((e) => e?.location) : []];
|
|
577
|
+
const extractedPages = segments.flatMap((s) => pagesOf(s.location));
|
|
578
|
+
const omittedPages = [...new Set(failed.flatMap((l) => pagesOf(l)))].filter((p) => !extractedPages.includes(p)).sort((a, b) => a - b);
|
|
579
|
+
const pages = [.../* @__PURE__ */ new Set([...extractedPages, ...omittedPages])].sort((a, b) => a - b);
|
|
580
|
+
if (pages.length > 1e3) throw new QuestionExtractionValidationError("Too many source pages");
|
|
581
|
+
const catalogs = evidence.mediaType.startsWith("image/") ? segments.filter((s) => s.location?.kind === "source").map((s) => normalizeObservedImageRegions(s.observedRegions)).filter((c) => c !== void 0) : [];
|
|
582
|
+
const incomplete = result.truncated === true || failed.length > 0;
|
|
583
|
+
return {
|
|
584
|
+
...base,
|
|
585
|
+
pages,
|
|
586
|
+
...omittedPages.length ? { omittedPages } : {},
|
|
587
|
+
...incomplete ? { incomplete: true } : {},
|
|
588
|
+
...catalogs.length === 1 ? { observedRegions: catalogs[0] } : {}
|
|
589
|
+
};
|
|
590
|
+
});
|
|
591
|
+
const codes = [.../* @__PURE__ */ new Set([...warnings.filter((w) => /^[a-z][a-z0-9_.-]{0,47}$/.test(w)), ...snapshot.result.output?.truncated === true ? ["source_incomplete"] : []])].sort().slice(0, 16);
|
|
592
|
+
return {
|
|
593
|
+
version: 1,
|
|
594
|
+
extractionAttemptId: snapshot.attemptId,
|
|
595
|
+
...codes.length ? { warnings: codes } : {},
|
|
596
|
+
sources
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
async function preserveQuestionExtractionAnalysis(input) {
|
|
600
|
+
let snapshot;
|
|
601
|
+
try {
|
|
602
|
+
snapshot = await input.ingestion.getCompletedAnalysis(input.itemId);
|
|
603
|
+
} catch (error) {
|
|
604
|
+
if (error instanceof Error && error.message === "Analysis unavailable") throw new QuestionExtractionPendingError("pending");
|
|
605
|
+
throw error;
|
|
606
|
+
}
|
|
607
|
+
if (snapshot.configuration.stage !== "interpret" || !["completed", "partial"].includes(snapshot.result.status)) throw new QuestionExtractionPendingError("pending");
|
|
608
|
+
const generation = snapshot.result.output.proposals;
|
|
609
|
+
if (generation?.version !== 1 || !Array.isArray(generation.suggestions)) throw new QuestionExtractionValidationError("Malformed generation output");
|
|
610
|
+
if (generation.outcome === "ambiguous") throw new QuestionExtractionPendingError("ambiguous");
|
|
611
|
+
if (!["proposals", "needs_review"].includes(generation.outcome)) throw new QuestionExtractionPendingError("no_proposal");
|
|
612
|
+
const suggestions = generation.suggestions.filter((s) => s.handlerId === QUESTION_EXTRACTION_HANDLER_ID);
|
|
613
|
+
if (!suggestions.length) throw new QuestionExtractionPendingError("no_proposal");
|
|
614
|
+
if (suggestions.length > 1) throw new QuestionExtractionPendingError("ambiguous");
|
|
615
|
+
const suggestion = suggestions[0];
|
|
616
|
+
if (suggestion.missingFields.length) throw new QuestionExtractionValidationError("Incomplete question extraction");
|
|
617
|
+
const generative = generation.provenance.generative;
|
|
618
|
+
return input.extractions.preserveExtraction({
|
|
619
|
+
...input.request,
|
|
620
|
+
intakeItemId: input.itemId,
|
|
621
|
+
analysisAttemptId: snapshot.attemptId,
|
|
622
|
+
grounding: questionExtractionGrounding(snapshot, generation.warnings ?? []),
|
|
623
|
+
extractor: {
|
|
624
|
+
provider: generative.provider,
|
|
625
|
+
model: generative.model,
|
|
626
|
+
version: generative.version,
|
|
627
|
+
configurationVersion: generation.provenance.configurationVersion,
|
|
628
|
+
promptVersion: generation.provenance.promptVersion
|
|
629
|
+
},
|
|
630
|
+
extraction: suggestion.args,
|
|
631
|
+
...input.expectedWorksheetVersionId ? { expectedWorksheetVersionId: input.expectedWorksheetVersionId } : {},
|
|
632
|
+
...input.worksheets ? { worksheets: input.worksheets } : {}
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
//#endregion
|
|
441
636
|
//#region src/workbook-photo-ingestion.ts
|
|
442
637
|
var MODEL = "@happyvertical/smrt-education:WorkbookPhotoIntake";
|
|
443
638
|
var WORKBOOK_PHOTO_HANDLER = "@happyvertical/smrt-education:identify-workbook-photo";
|
|
@@ -1581,6 +1776,6 @@ async function preserveWorkbookIntakeAnalysis(input) {
|
|
|
1581
1776
|
}
|
|
1582
1777
|
}
|
|
1583
1778
|
//#endregion
|
|
1584
|
-
export { FamilyIntakeService, WORKBOOK_PHOTO_HANDLER, captureEducationIntake, educationIntakeHandlers, educationIntakeTargetResolver, preserveWorkbookIntakeAnalysis, preserveWorkbookPhotoIdentification, processEducationAnalysis, processWorkbookPhotoAnalysis, queueEducationExtraction, receiveFamilyIntake, receiveWorkbookPhotoIntake, requireIngestionMemoryLimit, retainFamilyIntakeReceipt, retainWorkbookPhotoReceipt, workbookPhotoIntakeHandlers, workbookPhotoIntakeTargetResolver };
|
|
1779
|
+
export { FamilyIntakeService, QUESTION_EXTRACTION_HANDLER_ID, WORKBOOK_PHOTO_HANDLER, captureEducationIntake, educationIntakeHandlers, educationIntakeTargetResolver, educationQuestionExtractionHandler, preserveQuestionExtractionAnalysis, preserveWorkbookIntakeAnalysis, preserveWorkbookPhotoIdentification, processEducationAnalysis, processWorkbookPhotoAnalysis, questionExtractionGrounding, queueEducationExtraction, receiveFamilyIntake, receiveWorkbookPhotoIntake, requireIngestionMemoryLimit, retainFamilyIntakeReceipt, retainWorkbookPhotoReceipt, workbookPhotoIntakeHandlers, workbookPhotoIntakeTargetResolver };
|
|
1585
1780
|
|
|
1586
1781
|
//# sourceMappingURL=ingestion.js.map
|