@pie-players/pie-assessment-toolkit 0.3.58 → 0.3.60
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/components/ItemToolBar.custom-element.js +347 -151
- package/dist/components/PieAssessmentToolkit.custom-element.js +30 -5
- package/dist/components/SectionToolBar.custom-element.js +345 -151
- package/dist/context/assessment-toolkit-context.d.ts +7 -0
- package/dist/context/assessment-toolkit-context.js.map +1 -1
- package/dist/runtime/core/engine-resolver.d.ts +16 -0
- package/dist/runtime/core/engine-resolver.js.map +1 -1
- package/dist/services/ToolCoordinator.d.ts +24 -0
- package/dist/services/ToolCoordinator.js +46 -3
- package/dist/services/ToolCoordinator.js.map +1 -1
- package/dist/services/interfaces.d.ts +7 -1
- package/dist/services/interfaces.js.map +1 -1
- package/dist/services/tool-context.js +2 -0
- package/dist/services/tool-context.js.map +1 -1
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-context.js","sourceRoot":"","sources":["../../src/services/tool-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool Context Types\n *\n * Defines the context types passed to tools for making visibility and behavior decisions.\n * Each context level provides increasingly specific information about where the tool is being used.\n */\n\nimport type {\n\tAssessmentEntity,\n\tAssessmentItemRef,\n\tAssessmentSection,\n\tItemEntity,\n\tPassageEntity,\n\tRubricBlock,\n} from \"@pie-players/pie-players-shared/types\";\n\n/**\n * Tool placement levels - where a tool can appear in the UI\n */\nexport type ToolLevel =\n\t| \"assessment\" // Assessment-wide tools (e.g., global calculator)\n\t| \"section\" // Section toolbar tools\n\t| \"item\" // Item-level tools (question toolbar)\n\t| \"passage\" // Passage header tools (stimulus rubric blocks)\n\t| \"rubric\" // Rubric block tools (instructions, rubrics)\n\t| \"element\"; // Element-specific tools (inline with interaction)\n\n/**\n * Base context available to all tools\n */\nexport interface BaseToolContext {\n\t/** The level at which this tool is being evaluated */\n\tlevel: ToolLevel;\n\n\t/** The full assessment entity */\n\tassessment: AssessmentEntity;\n\n\t/** Current section, if applicable */\n\tsection?: AssessmentSection;\n\n\t/** Reference to the current item (always available except at assessment level) */\n\titemRef?: AssessmentItemRef;\n\n\t/** DOM container where the tool will be rendered */\n\tcontainer?: HTMLElement;\n}\n\n/**\n * Context for assessment-level tools\n */\nexport interface AssessmentToolContext extends BaseToolContext {\n\tlevel: \"assessment\";\n}\n\n/**\n * Context for section-level tools\n */\nexport interface SectionToolContext extends BaseToolContext {\n\tlevel: \"section\";\n\tsection: AssessmentSection;\n}\n\n/**\n * Context for item-level tools (question toolbar)\n */\nexport interface ItemToolContext extends BaseToolContext {\n\tlevel: \"item\";\n\titemRef: AssessmentItemRef;\n\titem: ItemEntity;\n\n\t/** Passage entity if this item is associated with a passage */\n\tpassage?: PassageEntity;\n}\n\n/**\n * Context for passage-level tools (passage header)\n *\n * Passages can appear as:\n * - Standalone passage entities associated with items\n * - RubricBlock with class=\"stimulus\" containing embedded passage\n */\nexport interface PassageToolContext extends BaseToolContext {\n\tlevel: \"passage\";\n\titemRef?: AssessmentItemRef;\n\tpassage: PassageEntity;\n\n\t/** Items associated with this passage (if applicable) */\n\titems?: ItemEntity[];\n\n\t/** RubricBlock containing this passage (if from rubric) */\n\trubricBlock?: RubricBlock;\n}\n\n/**\n * Context for rubric block tools\n *\n * RubricBlocks can contain:\n * - Instructions (class=\"instructions\")\n * - Rubrics (class=\"rubric\")\n * - Stimulus/passages (class=\"stimulus\" with embedded passage)\n * - Simple HTML content\n */\nexport interface RubricToolContext extends BaseToolContext {\n\tlevel: \"rubric\";\n\trubricBlock: RubricBlock;\n\n\t/** Section containing this rubric block */\n\tsection: AssessmentSection;\n\n\t/** If rubric contains a passage (class=\"stimulus\") */\n\tpassage?: PassageEntity;\n}\n\n/**\n * Context for element-level tools (inline with interaction)\n *\n * Note: Element-level context uses the PIE interaction element ID\n * and provides access to the full item config for content inspection.\n */\nexport interface ElementToolContext extends BaseToolContext {\n\tlevel: \"element\";\n\titemRef: AssessmentItemRef;\n\titem: ItemEntity;\n\n\t/** The PIE element/interaction ID */\n\telementId: string;\n\n\t/** Passage entity if this item is associated with a passage */\n\tpassage?: PassageEntity;\n\n\t/** DOM element that triggered the tool (e.g., the specific input field) */\n\ttriggerElement?: HTMLElement;\n}\n\n/**\n * Union type of all tool contexts\n */\nexport type ToolContext =\n\t| AssessmentToolContext\n\t| SectionToolContext\n\t| ItemToolContext\n\t| PassageToolContext\n\t| RubricToolContext\n\t| ElementToolContext;\n\n/**\n * Type guard to check if context is at assessment level\n */\nexport function isAssessmentContext(\n\tcontext: ToolContext,\n): context is AssessmentToolContext {\n\treturn context.level === \"assessment\";\n}\n\n/**\n * Type guard to check if context is at section level\n */\nexport function isSectionContext(\n\tcontext: ToolContext,\n): context is SectionToolContext {\n\treturn context.level === \"section\";\n}\n\n/**\n * Type guard to check if context is at item level\n */\nexport function isItemContext(\n\tcontext: ToolContext,\n): context is ItemToolContext {\n\treturn context.level === \"item\";\n}\n\n/**\n * Type guard to check if context is at passage level\n */\nexport function isPassageContext(\n\tcontext: ToolContext,\n): context is PassageToolContext {\n\treturn context.level === \"passage\";\n}\n\n/**\n * Type guard to check if context is at rubric level\n */\nexport function isRubricContext(\n\tcontext: ToolContext,\n): context is RubricToolContext {\n\treturn context.level === \"rubric\";\n}\n\n/**\n * Type guard to check if context is at element level\n */\nexport function isElementContext(\n\tcontext: ToolContext,\n): context is ElementToolContext {\n\treturn context.level === \"element\";\n}\n\n/**\n * Helper to extract text content from an item or element for analysis\n */\nexport function extractTextContent(context: ToolContext): string {\n\tif (isElementContext(context)) {\n\t\tconst config = context.item.config;\n\t\tif (!config) return \"\";\n\t\tconst textChunks: string[] = [];\n\t\tconst stripHtml = (value: string) => value.replace(/<[^>]*>/g, \" \").trim();\n\n\t\t// Try to find element markup by element id.\n\t\tconst elementMarkup = config.elements?.[context.elementId];\n\t\tif (elementMarkup) {\n\t\t\tif (typeof elementMarkup === \"string\") {\n\t\t\t\ttextChunks.push(stripHtml(elementMarkup));\n\t\t\t}\n\t\t}\n\n\t\t// Also inspect model data keyed by this element id.\n\t\t// In many items, math appears in model.prompt/labels rather than elements[elementId].\n\t\tconst modelsRaw = config.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\tconst model = models.find(\n\t\t\t(m: any) => m && typeof m === \"object\" && m.id === context.elementId,\n\t\t) as Record<string, unknown> | undefined;\n\t\tif (model) {\n\t\t\tfor (const value of Object.values(model)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(value));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\tif (entry && typeof entry === \"object\") {\n\t\t\t\t\t\t\tfor (const nested of Object.values(\n\t\t\t\t\t\t\t\tentry as Record<string, unknown>,\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tif (typeof nested === \"string\") {\n\t\t\t\t\t\t\t\t\ttextChunks.push(stripHtml(nested));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn textChunks.filter(Boolean).join(\" \").trim();\n\t}\n\n\tif (isItemContext(context)) {\n\t\tconst item = context.item;\n\t\tif (!item?.config) return \"\";\n\n\t\tconst config = item.config as Record<string, unknown>;\n\t\tconst textChunks: string[] = [];\n\t\tconst stripHtml = (value: string) => value.replace(/<[^>]*>/g, \" \").trim();\n\n\t\t// Primary item markup\n\t\tif (typeof config.markup === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.markup));\n\t\t}\n\n\t\t// Element markup snippets\n\t\tconst elements = config.elements as Record<string, unknown> | undefined;\n\t\tif (elements && typeof elements === \"object\") {\n\t\t\tfor (const elementMarkup of Object.values(elements)) {\n\t\t\t\tif (typeof elementMarkup === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(elementMarkup));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Model-level text (prompts, labels, etc.)\n\t\tconst modelsRaw = config.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\tfor (const model of models) {\n\t\t\tif (!model || typeof model !== \"object\") continue;\n\t\t\tfor (const value of Object.values(model as Record<string, unknown>)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(value));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\tif (entry && typeof entry === \"object\") {\n\t\t\t\t\t\t\tfor (const nested of Object.values(\n\t\t\t\t\t\t\t\tentry as Record<string, unknown>,\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tif (typeof nested === \"string\") {\n\t\t\t\t\t\t\t\t\ttextChunks.push(stripHtml(nested));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn textChunks.filter(Boolean).join(\" \").trim();\n\t}\n\n\tif (isPassageContext(context)) {\n\t\tconst passage = context.passage;\n\t\tif (!passage?.config) return \"\";\n\n\t\tconst config = passage.config as Record<string, unknown>;\n\t\tconst textChunks: string[] = [];\n\t\tconst stripHtml = (value: string) => value.replace(/<[^>]*>/g, \" \").trim();\n\n\t\t// Primary passage markup/content\n\t\tif (typeof config.markup === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.markup));\n\t\t}\n\t\tif (typeof config.content === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.content));\n\t\t}\n\t\tif (typeof config.prompt === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.prompt));\n\t\t}\n\n\t\t// Element markup snippets\n\t\tconst elements = config.elements as Record<string, unknown> | undefined;\n\t\tif (elements && typeof elements === \"object\") {\n\t\t\tfor (const elementMarkup of Object.values(elements)) {\n\t\t\t\tif (typeof elementMarkup === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(elementMarkup));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Model-level text (prompts, labels, etc.)\n\t\tconst modelsRaw = config.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\tfor (const model of models) {\n\t\t\tif (!model || typeof model !== \"object\") continue;\n\t\t\tfor (const value of Object.values(model as Record<string, unknown>)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(value));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\tif (entry && typeof entry === \"object\") {\n\t\t\t\t\t\t\tfor (const nested of Object.values(\n\t\t\t\t\t\t\t\tentry as Record<string, unknown>,\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tif (typeof nested === \"string\") {\n\t\t\t\t\t\t\t\t\ttextChunks.push(stripHtml(nested));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn textChunks.filter(Boolean).join(\" \").trim();\n\t}\n\n\tif (isRubricContext(context)) {\n\t\tconst rubric = context.rubricBlock;\n\n\t\t// If rubric has embedded passage, extract from passage config\n\t\tif (rubric.passage?.config) {\n\t\t\tconst markup = rubric.passage.config.markup || \"\";\n\t\t\treturn markup.replace(/<[^>]*>/g, \" \").trim();\n\t\t}\n\n\t\t// Otherwise, use simple content string\n\t\tconst content = rubric.content || \"\";\n\t\treturn content.replace(/<[^>]*>/g, \" \").trim();\n\t}\n\n\treturn \"\";\n}\n\n/**\n * Helper to check if context contains mathematical content\n * (Basic heuristic - can be overridden by tools)\n */\nexport function hasMathContent(context: ToolContext): boolean {\n\tconst text = extractTextContent(context);\n\n\t// Look for common math indicators\n\tconst mathIndicators = [\n\t\t/<math[>\\s]/i, // MathML\n\t\t/\\\\\\[([^\\]]+)\\\\\\]/, // LaTeX display math\n\t\t/\\$\\$[^$]+\\$\\$/, // LaTeX display math ($$...$$)\n\t\t/\\\\\\(/, // LaTeX inline math\n\t\t/[+\\-*/=<>≤≥∑∫√π]/, // Math symbols\n\t\t/\\d+\\s*[+\\-*/=]\\s*\\d+/, // Simple arithmetic\n\t];\n\n\treturn mathIndicators.some((pattern) => pattern.test(text));\n}\n\n/**\n * Helper to check if context contains choice-based interactions\n */\nexport function hasChoiceInteraction(context: ToolContext): boolean {\n\tconst interactionTypes = [\n\t\t\"pie-multiple-choice\",\n\t\t\"pie-inline-choice\",\n\t\t\"pie-select-text\",\n\t\t\"multiple-choice\",\n\t\t\"inline-choice\",\n\t\t\"select-text\",\n\t];\n\n\tif (isElementContext(context)) {\n\t\tconst config = context.item.config;\n\t\tif (!config?.models) return false;\n\n\t\t// Find model for this element\n\t\tconst models = Array.isArray(config.models)\n\t\t\t? config.models\n\t\t\t: Object.values(config.models as Record<string, unknown>);\n\t\tconst model = models.find(\n\t\t\t(m: any) => m && typeof m === \"object\" && m.id === context.elementId,\n\t\t);\n\t\tif (!model) return false;\n\n\t\tconst type = (model as any).element || \"\";\n\t\treturn interactionTypes.includes(type);\n\t}\n\n\tif (isItemContext(context)) {\n\t\tconst modelsRaw = context.item.config?.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\treturn models.some((m: any) => {\n\t\t\tif (!m || typeof m !== \"object\") return false;\n\t\t\tconst type = m.element || \"\";\n\t\t\tif (interactionTypes.includes(type)) return true;\n\t\t\t// Fallback for configs that don't provide canonical element names.\n\t\t\treturn Array.isArray(m.choices) && m.choices.length > 0;\n\t\t});\n\t}\n\n\treturn false;\n}\n\n/**\n * Helper to check if context contains text that can be read aloud\n */\nexport function hasReadableText(context: ToolContext): boolean {\n\tconst text = extractTextContent(context);\n\t// Must have at least 10 characters of text (arbitrary threshold)\n\treturn text.trim().length >= 10;\n}\n\n/**\n * Helper to check if context contains science content\n * (Basic heuristic - can be overridden by tools)\n */\nexport function hasScienceContent(context: ToolContext): boolean {\n\tconst text = extractTextContent(context);\n\n\t// Look for common science indicators\n\tconst scienceIndicators = [\n\t\t/chemistry|chemical|element|atom|molecule|compound/i,\n\t\t/periodic\\s+table/i,\n\t\t/H₂O|CO₂|NaCl|O₂|N₂/i, // Chemical formulas\n\t\t/\\b[A-Z][a-z]?\\d*\\b/, // Element symbols (H, He, Li, etc.)\n\t\t/biology|organism|cell|DNA|RNA|protein/i,\n\t\t/physics|force|energy|velocity|acceleration/i,\n\t];\n\n\treturn scienceIndicators.some((pattern) => pattern.test(text));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-context.js","sourceRoot":"","sources":["../../src/services/tool-context.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tool Context Types\n *\n * Defines the context types passed to tools for making visibility and behavior decisions.\n * Each context level provides increasingly specific information about where the tool is being used.\n */\n\nimport type {\n\tAssessmentEntity,\n\tAssessmentItemRef,\n\tAssessmentSection,\n\tItemEntity,\n\tPassageEntity,\n\tRubricBlock,\n} from \"@pie-players/pie-players-shared/types\";\n\n/**\n * Tool placement levels - where a tool can appear in the UI\n */\nexport type ToolLevel =\n\t| \"assessment\" // Assessment-wide tools (e.g., global calculator)\n\t| \"section\" // Section toolbar tools\n\t| \"item\" // Item-level tools (question toolbar)\n\t| \"passage\" // Passage header tools (stimulus rubric blocks)\n\t| \"rubric\" // Rubric block tools (instructions, rubrics)\n\t| \"element\"; // Element-specific tools (inline with interaction)\n\n/**\n * Base context available to all tools\n */\nexport interface BaseToolContext {\n\t/** The level at which this tool is being evaluated */\n\tlevel: ToolLevel;\n\n\t/** The full assessment entity */\n\tassessment: AssessmentEntity;\n\n\t/** Current section, if applicable */\n\tsection?: AssessmentSection;\n\n\t/** Reference to the current item (always available except at assessment level) */\n\titemRef?: AssessmentItemRef;\n\n\t/** DOM container where the tool will be rendered */\n\tcontainer?: HTMLElement;\n}\n\n/**\n * Context for assessment-level tools\n */\nexport interface AssessmentToolContext extends BaseToolContext {\n\tlevel: \"assessment\";\n}\n\n/**\n * Context for section-level tools\n */\nexport interface SectionToolContext extends BaseToolContext {\n\tlevel: \"section\";\n\tsection: AssessmentSection;\n}\n\n/**\n * Context for item-level tools (question toolbar)\n */\nexport interface ItemToolContext extends BaseToolContext {\n\tlevel: \"item\";\n\titemRef: AssessmentItemRef;\n\titem: ItemEntity;\n\n\t/** Passage entity if this item is associated with a passage */\n\tpassage?: PassageEntity;\n}\n\n/**\n * Context for passage-level tools (passage header)\n *\n * Passages can appear as:\n * - Standalone passage entities associated with items\n * - RubricBlock with class=\"stimulus\" containing embedded passage\n */\nexport interface PassageToolContext extends BaseToolContext {\n\tlevel: \"passage\";\n\titemRef?: AssessmentItemRef;\n\tpassage: PassageEntity;\n\n\t/** Items associated with this passage (if applicable) */\n\titems?: ItemEntity[];\n\n\t/** RubricBlock containing this passage (if from rubric) */\n\trubricBlock?: RubricBlock;\n}\n\n/**\n * Context for rubric block tools\n *\n * RubricBlocks can contain:\n * - Instructions (class=\"instructions\")\n * - Rubrics (class=\"rubric\")\n * - Stimulus/passages (class=\"stimulus\" with embedded passage)\n * - Simple HTML content\n */\nexport interface RubricToolContext extends BaseToolContext {\n\tlevel: \"rubric\";\n\trubricBlock: RubricBlock;\n\n\t/** Section containing this rubric block */\n\tsection: AssessmentSection;\n\n\t/** If rubric contains a passage (class=\"stimulus\") */\n\tpassage?: PassageEntity;\n}\n\n/**\n * Context for element-level tools (inline with interaction)\n *\n * Note: Element-level context uses the PIE interaction element ID\n * and provides access to the full item config for content inspection.\n */\nexport interface ElementToolContext extends BaseToolContext {\n\tlevel: \"element\";\n\titemRef: AssessmentItemRef;\n\titem: ItemEntity;\n\n\t/** The PIE element/interaction ID */\n\telementId: string;\n\n\t/** Passage entity if this item is associated with a passage */\n\tpassage?: PassageEntity;\n\n\t/** DOM element that triggered the tool (e.g., the specific input field) */\n\ttriggerElement?: HTMLElement;\n}\n\n/**\n * Union type of all tool contexts\n */\nexport type ToolContext =\n\t| AssessmentToolContext\n\t| SectionToolContext\n\t| ItemToolContext\n\t| PassageToolContext\n\t| RubricToolContext\n\t| ElementToolContext;\n\n/**\n * Type guard to check if context is at assessment level\n */\nexport function isAssessmentContext(\n\tcontext: ToolContext,\n): context is AssessmentToolContext {\n\treturn context.level === \"assessment\";\n}\n\n/**\n * Type guard to check if context is at section level\n */\nexport function isSectionContext(\n\tcontext: ToolContext,\n): context is SectionToolContext {\n\treturn context.level === \"section\";\n}\n\n/**\n * Type guard to check if context is at item level\n */\nexport function isItemContext(\n\tcontext: ToolContext,\n): context is ItemToolContext {\n\treturn context.level === \"item\";\n}\n\n/**\n * Type guard to check if context is at passage level\n */\nexport function isPassageContext(\n\tcontext: ToolContext,\n): context is PassageToolContext {\n\treturn context.level === \"passage\";\n}\n\n/**\n * Type guard to check if context is at rubric level\n */\nexport function isRubricContext(\n\tcontext: ToolContext,\n): context is RubricToolContext {\n\treturn context.level === \"rubric\";\n}\n\n/**\n * Type guard to check if context is at element level\n */\nexport function isElementContext(\n\tcontext: ToolContext,\n): context is ElementToolContext {\n\treturn context.level === \"element\";\n}\n\n/**\n * Helper to extract text content from an item or element for analysis\n */\nexport function extractTextContent(context: ToolContext): string {\n\tif (isElementContext(context)) {\n\t\tconst config = context.item.config;\n\t\tif (!config) return \"\";\n\t\tconst textChunks: string[] = [];\n\t\tconst stripHtml = (value: string) => value.replace(/<[^>]*>/g, \" \").trim();\n\n\t\t// Try to find element markup by element id.\n\t\tconst elementMarkup = config.elements?.[context.elementId];\n\t\tif (elementMarkup) {\n\t\t\tif (typeof elementMarkup === \"string\") {\n\t\t\t\ttextChunks.push(stripHtml(elementMarkup));\n\t\t\t}\n\t\t}\n\n\t\t// Also inspect model data keyed by this element id.\n\t\t// In many items, math appears in model.prompt/labels rather than elements[elementId].\n\t\tconst modelsRaw = config.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\tconst model = models.find(\n\t\t\t(m: any) => m && typeof m === \"object\" && m.id === context.elementId,\n\t\t) as Record<string, unknown> | undefined;\n\t\tif (model) {\n\t\t\tfor (const value of Object.values(model)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(value));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\tif (entry && typeof entry === \"object\") {\n\t\t\t\t\t\t\tfor (const nested of Object.values(\n\t\t\t\t\t\t\t\tentry as Record<string, unknown>,\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tif (typeof nested === \"string\") {\n\t\t\t\t\t\t\t\t\ttextChunks.push(stripHtml(nested));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn textChunks.filter(Boolean).join(\" \").trim();\n\t}\n\n\tif (isItemContext(context)) {\n\t\tconst item = context.item;\n\t\tif (!item?.config) return \"\";\n\n\t\tconst config = item.config as Record<string, unknown>;\n\t\tconst textChunks: string[] = [];\n\t\tconst stripHtml = (value: string) => value.replace(/<[^>]*>/g, \" \").trim();\n\n\t\t// Primary item markup\n\t\tif (typeof config.markup === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.markup));\n\t\t}\n\n\t\t// Element markup snippets\n\t\tconst elements = config.elements as Record<string, unknown> | undefined;\n\t\tif (elements && typeof elements === \"object\") {\n\t\t\tfor (const elementMarkup of Object.values(elements)) {\n\t\t\t\tif (typeof elementMarkup === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(elementMarkup));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Model-level text (prompts, labels, etc.)\n\t\tconst modelsRaw = config.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\tfor (const model of models) {\n\t\t\tif (!model || typeof model !== \"object\") continue;\n\t\t\tfor (const value of Object.values(model as Record<string, unknown>)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(value));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\tif (entry && typeof entry === \"object\") {\n\t\t\t\t\t\t\tfor (const nested of Object.values(\n\t\t\t\t\t\t\t\tentry as Record<string, unknown>,\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tif (typeof nested === \"string\") {\n\t\t\t\t\t\t\t\t\ttextChunks.push(stripHtml(nested));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn textChunks.filter(Boolean).join(\" \").trim();\n\t}\n\n\tif (isPassageContext(context)) {\n\t\tconst passage = context.passage;\n\t\tif (!passage?.config) return \"\";\n\n\t\tconst config = passage.config as Record<string, unknown>;\n\t\tconst textChunks: string[] = [];\n\t\tconst stripHtml = (value: string) => value.replace(/<[^>]*>/g, \" \").trim();\n\n\t\t// Primary passage markup/content\n\t\tif (typeof config.markup === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.markup));\n\t\t}\n\t\tif (typeof config.content === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.content));\n\t\t}\n\t\tif (typeof config.prompt === \"string\") {\n\t\t\ttextChunks.push(stripHtml(config.prompt));\n\t\t}\n\n\t\t// Element markup snippets\n\t\tconst elements = config.elements as Record<string, unknown> | undefined;\n\t\tif (elements && typeof elements === \"object\") {\n\t\t\tfor (const elementMarkup of Object.values(elements)) {\n\t\t\t\tif (typeof elementMarkup === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(elementMarkup));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Model-level text (prompts, labels, etc.)\n\t\tconst modelsRaw = config.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\tfor (const model of models) {\n\t\t\tif (!model || typeof model !== \"object\") continue;\n\t\t\tfor (const value of Object.values(model as Record<string, unknown>)) {\n\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\ttextChunks.push(stripHtml(value));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\tfor (const entry of value) {\n\t\t\t\t\t\tif (entry && typeof entry === \"object\") {\n\t\t\t\t\t\t\tfor (const nested of Object.values(\n\t\t\t\t\t\t\t\tentry as Record<string, unknown>,\n\t\t\t\t\t\t\t)) {\n\t\t\t\t\t\t\t\tif (typeof nested === \"string\") {\n\t\t\t\t\t\t\t\t\ttextChunks.push(stripHtml(nested));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn textChunks.filter(Boolean).join(\" \").trim();\n\t}\n\n\tif (isRubricContext(context)) {\n\t\tconst rubric = context.rubricBlock;\n\n\t\t// If rubric has embedded passage, extract from passage config\n\t\tif (rubric.passage?.config) {\n\t\t\tconst markup = rubric.passage.config.markup || \"\";\n\t\t\treturn markup.replace(/<[^>]*>/g, \" \").trim();\n\t\t}\n\n\t\t// Otherwise, use simple content string\n\t\tconst content = rubric.content || \"\";\n\t\treturn content.replace(/<[^>]*>/g, \" \").trim();\n\t}\n\n\treturn \"\";\n}\n\n/**\n * Helper to check if context contains mathematical content\n * (Basic heuristic - can be overridden by tools)\n */\nexport function hasMathContent(context: ToolContext): boolean {\n\tconst text = extractTextContent(context);\n\n\t// Look for common math indicators\n\tconst mathIndicators = [\n\t\t/<math[>\\s]/i, // MathML\n\t\t/\\\\\\[([^\\]]+)\\\\\\]/, // LaTeX display math\n\t\t/\\$\\$[^$]+\\$\\$/, // LaTeX display math ($$...$$)\n\t\t/\\\\\\(/, // LaTeX inline math\n\t\t/[+\\-*/=<>≤≥∑∫√π]/, // Math symbols\n\t\t/\\d+\\s*[+\\-*/=]\\s*\\d+/, // Simple arithmetic\n\t];\n\n\treturn mathIndicators.some((pattern) => pattern.test(text));\n}\n\n/**\n * Helper to check if context contains choice-based interactions\n */\nexport function hasChoiceInteraction(context: ToolContext): boolean {\n\tconst interactionTypes = [\n\t\t\"pie-multiple-choice\",\n\t\t\"pie-inline-choice\",\n\t\t\"pie-select-text\",\n\t\t\"pie-ebsr\",\n\t\t\"multiple-choice\",\n\t\t\"inline-choice\",\n\t\t\"select-text\",\n\t\t\"ebsr\",\n\t];\n\n\tif (isElementContext(context)) {\n\t\tconst config = context.item.config;\n\t\tif (!config?.models) return false;\n\n\t\t// Find model for this element\n\t\tconst models = Array.isArray(config.models)\n\t\t\t? config.models\n\t\t\t: Object.values(config.models as Record<string, unknown>);\n\t\tconst model = models.find(\n\t\t\t(m: any) => m && typeof m === \"object\" && m.id === context.elementId,\n\t\t);\n\t\tif (!model) return false;\n\n\t\tconst type = (model as any).element || \"\";\n\t\treturn interactionTypes.includes(type);\n\t}\n\n\tif (isItemContext(context)) {\n\t\tconst modelsRaw = context.item.config?.models;\n\t\tconst models = Array.isArray(modelsRaw)\n\t\t\t? modelsRaw\n\t\t\t: modelsRaw && typeof modelsRaw === \"object\"\n\t\t\t\t? Object.values(modelsRaw as Record<string, unknown>)\n\t\t\t\t: [];\n\t\treturn models.some((m: any) => {\n\t\t\tif (!m || typeof m !== \"object\") return false;\n\t\t\tconst type = m.element || \"\";\n\t\t\tif (interactionTypes.includes(type)) return true;\n\t\t\t// Fallback for configs that don't provide canonical element names.\n\t\t\treturn Array.isArray(m.choices) && m.choices.length > 0;\n\t\t});\n\t}\n\n\treturn false;\n}\n\n/**\n * Helper to check if context contains text that can be read aloud\n */\nexport function hasReadableText(context: ToolContext): boolean {\n\tconst text = extractTextContent(context);\n\t// Must have at least 10 characters of text (arbitrary threshold)\n\treturn text.trim().length >= 10;\n}\n\n/**\n * Helper to check if context contains science content\n * (Basic heuristic - can be overridden by tools)\n */\nexport function hasScienceContent(context: ToolContext): boolean {\n\tconst text = extractTextContent(context);\n\n\t// Look for common science indicators\n\tconst scienceIndicators = [\n\t\t/chemistry|chemical|element|atom|molecule|compound/i,\n\t\t/periodic\\s+table/i,\n\t\t/H₂O|CO₂|NaCl|O₂|N₂/i, // Chemical formulas\n\t\t/\\b[A-Z][a-z]?\\d*\\b/, // Element symbols (H, He, Li, etc.)\n\t\t/biology|organism|cell|DNA|RNA|protein/i,\n\t\t/physics|force|energy|velocity|acceleration/i,\n\t];\n\n\treturn scienceIndicators.some((pattern) => pattern.test(text));\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-players/pie-assessment-toolkit",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.60",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "PIE assessment toolkit: composable services + reference implementation for assessment players and tool coordination",
|
|
6
6
|
"license": "MIT",
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
"test": "bun test"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@pie-players/pie-calculator": "0.3.
|
|
79
|
-
"@pie-players/pie-context": "0.3.
|
|
80
|
-
"@pie-players/pie-players-shared": "0.3.
|
|
81
|
-
"@pie-players/pie-tts": "0.3.
|
|
78
|
+
"@pie-players/pie-calculator": "0.3.60",
|
|
79
|
+
"@pie-players/pie-context": "0.3.60",
|
|
80
|
+
"@pie-players/pie-players-shared": "0.3.60",
|
|
81
|
+
"@pie-players/pie-tts": "0.3.60",
|
|
82
82
|
"speech-rule-engine": "^5.0.0-rc.1"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
|
-
"@pie-players/pie-calculator-desmos": "0.3.
|
|
86
|
-
"@pie-players/tts-client-server": "0.3.
|
|
85
|
+
"@pie-players/pie-calculator-desmos": "0.3.60",
|
|
86
|
+
"@pie-players/tts-client-server": "0.3.60"
|
|
87
87
|
},
|
|
88
88
|
"peerDependenciesMeta": {
|
|
89
89
|
"@pie-players/pie-calculator-desmos": {
|