clawed 2.3.3__tar.gz → 2.3.4__tar.gz

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.
Files changed (232) hide show
  1. {clawed-2.3.3 → clawed-2.3.4}/PKG-INFO +1 -1
  2. {clawed-2.3.3 → clawed-2.3.4}/clawed/__init__.py +1 -1
  3. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/prompt.py +5 -1
  4. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/generate_lesson_bundle.py +4 -1
  5. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/ingest_materials.py +57 -0
  6. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/generate.py +28 -0
  7. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/ingest.py +48 -0
  8. {clawed-2.3.3 → clawed-2.3.4}/clawed/models.py +27 -0
  9. {clawed-2.3.3 → clawed-2.3.4}/clawed/slide_images.py +26 -14
  10. {clawed-2.3.3 → clawed-2.3.4}/clawed/sub_packet.py +7 -0
  11. {clawed-2.3.3 → clawed-2.3.4}/pyproject.toml +1 -1
  12. {clawed-2.3.3 → clawed-2.3.4}/.gitignore +0 -0
  13. {clawed-2.3.3 → clawed-2.3.4}/LICENSE +0 -0
  14. {clawed-2.3.3 → clawed-2.3.4}/README.md +0 -0
  15. {clawed-2.3.3 → clawed-2.3.4}/clawed/__main__.py +0 -0
  16. {clawed-2.3.3 → clawed-2.3.4}/clawed/_legacy_gateway.py +0 -0
  17. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent.py +0 -0
  18. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/__init__.py +0 -0
  19. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/approvals.py +0 -0
  20. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/autonomy.py +0 -0
  21. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/context.py +0 -0
  22. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/core.py +0 -0
  23. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/custom_tools.py +0 -0
  24. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/drive/__init__.py +0 -0
  25. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/drive/auth.py +0 -0
  26. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/drive/client.py +0 -0
  27. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/fake_llm.py +0 -0
  28. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/loop.py +0 -0
  29. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/__init__.py +0 -0
  30. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/curriculum.py +0 -0
  31. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/curriculum_kb.py +0 -0
  32. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/embeddings.py +0 -0
  33. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/episodes.py +0 -0
  34. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/identity.py +0 -0
  35. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/loader.py +0 -0
  36. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/memory/preferences.py +0 -0
  37. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/planner.py +0 -0
  38. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/scheduler.py +0 -0
  39. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/__init__.py +0 -0
  40. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/base.py +0 -0
  41. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/configure_profile.py +0 -0
  42. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/curriculum_map.py +0 -0
  43. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/drive_create_doc.py +0 -0
  44. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/drive_create_slides.py +0 -0
  45. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/drive_list.py +0 -0
  46. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/drive_organize.py +0 -0
  47. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/drive_read.py +0 -0
  48. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/drive_upload.py +0 -0
  49. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/export_document.py +0 -0
  50. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/gap_analysis.py +0 -0
  51. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/generate_assessment.py +0 -0
  52. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/generate_lesson.py +0 -0
  53. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/generate_materials.py +0 -0
  54. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/generate_unit.py +0 -0
  55. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/parent_comm.py +0 -0
  56. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/read_heartbeat.py +0 -0
  57. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/read_workspace.py +0 -0
  58. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/request_approval.py +0 -0
  59. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/schedule_task.py +0 -0
  60. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/search_lessons.py +0 -0
  61. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/search_my_materials.py +0 -0
  62. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/search_standards.py +0 -0
  63. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/student_insights.py +0 -0
  64. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/sub_packet.py +0 -0
  65. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/switch_model.py +0 -0
  66. {clawed-2.3.3 → clawed-2.3.4}/clawed/agent_core/tools/update_soul.py +0 -0
  67. {clawed-2.3.3 → clawed-2.3.4}/clawed/analytics.py +0 -0
  68. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/__init__.py +0 -0
  69. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/deps.py +0 -0
  70. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/__init__.py +0 -0
  71. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/chat.py +0 -0
  72. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/export.py +0 -0
  73. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/feedback.py +0 -0
  74. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/gateway_chat.py +0 -0
  75. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/generate.py +0 -0
  76. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/ingest.py +0 -0
  77. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/lessons.py +0 -0
  78. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/school.py +0 -0
  79. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/settings.py +0 -0
  80. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/routes/tools.py +0 -0
  81. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/server.py +0 -0
  82. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/static/app.js +0 -0
  83. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/static/style.css +0 -0
  84. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/static/widget.js +0 -0
  85. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/analytics.html +0 -0
  86. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/base.html +0 -0
  87. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/dashboard.html +0 -0
  88. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/generate.html +0 -0
  89. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/index.html +0 -0
  90. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/lesson.html +0 -0
  91. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/profile.html +0 -0
  92. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/settings.html +0 -0
  93. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/stats.html +0 -0
  94. {clawed-2.3.3 → clawed-2.3.4}/clawed/api/templates/students.html +0 -0
  95. {clawed-2.3.3 → clawed-2.3.4}/clawed/assessment.py +0 -0
  96. {clawed-2.3.3 → clawed-2.3.4}/clawed/asset_registry.py +0 -0
  97. {clawed-2.3.3 → clawed-2.3.4}/clawed/auth/__init__.py +0 -0
  98. {clawed-2.3.3 → clawed-2.3.4}/clawed/auth/google_auth.py +0 -0
  99. {clawed-2.3.3 → clawed-2.3.4}/clawed/bot_state.py +0 -0
  100. {clawed-2.3.3 → clawed-2.3.4}/clawed/chat.py +0 -0
  101. {clawed-2.3.3 → clawed-2.3.4}/clawed/cli.py +0 -0
  102. {clawed-2.3.3 → clawed-2.3.4}/clawed/cli_chat.py +0 -0
  103. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/__init__.py +0 -0
  104. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/_helpers.py +0 -0
  105. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/bot.py +0 -0
  106. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/config.py +0 -0
  107. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/config_llm.py +0 -0
  108. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/config_profile.py +0 -0
  109. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/export.py +0 -0
  110. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/generate_assessment.py +0 -0
  111. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/generate_unit.py +0 -0
  112. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/queue.py +0 -0
  113. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/schedule_cmd.py +0 -0
  114. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/sub.py +0 -0
  115. {clawed-2.3.3 → clawed-2.3.4}/clawed/commands/workspace_cmd.py +0 -0
  116. {clawed-2.3.3 → clawed-2.3.4}/clawed/config.py +0 -0
  117. {clawed-2.3.3 → clawed-2.3.4}/clawed/corpus.py +0 -0
  118. {clawed-2.3.3 → clawed-2.3.4}/clawed/curriculum_map.py +0 -0
  119. {clawed-2.3.3 → clawed-2.3.4}/clawed/database.py +0 -0
  120. {clawed-2.3.3 → clawed-2.3.4}/clawed/demo/__init__.py +0 -0
  121. {clawed-2.3.3 → clawed-2.3.4}/clawed/demo/demo_assessment.json +0 -0
  122. {clawed-2.3.3 → clawed-2.3.4}/clawed/demo/demo_lesson_science_g6.json +0 -0
  123. {clawed-2.3.3 → clawed-2.3.4}/clawed/demo/demo_lesson_social_studies_g8.json +0 -0
  124. {clawed-2.3.3 → clawed-2.3.4}/clawed/demo/demo_unit_plan.json +0 -0
  125. {clawed-2.3.3 → clawed-2.3.4}/clawed/differentiation.py +0 -0
  126. {clawed-2.3.3 → clawed-2.3.4}/clawed/doc_export.py +0 -0
  127. {clawed-2.3.3 → clawed-2.3.4}/clawed/drive.py +0 -0
  128. {clawed-2.3.3 → clawed-2.3.4}/clawed/evaluation.py +0 -0
  129. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_docx.py +0 -0
  130. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_handout.py +0 -0
  131. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_markdown.py +0 -0
  132. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_pdf.py +0 -0
  133. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_pptx.py +0 -0
  134. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_templates.py +0 -0
  135. {clawed-2.3.3 → clawed-2.3.4}/clawed/export_theme.py +0 -0
  136. {clawed-2.3.3 → clawed-2.3.4}/clawed/exporter.py +0 -0
  137. {clawed-2.3.3 → clawed-2.3.4}/clawed/feedback.py +0 -0
  138. {clawed-2.3.3 → clawed-2.3.4}/clawed/formats/__init__.py +0 -0
  139. {clawed-2.3.3 → clawed-2.3.4}/clawed/formats/flipchart.py +0 -0
  140. {clawed-2.3.3 → clawed-2.3.4}/clawed/formats/notebook.py +0 -0
  141. {clawed-2.3.3 → clawed-2.3.4}/clawed/formats/xbk.py +0 -0
  142. {clawed-2.3.3 → clawed-2.3.4}/clawed/gateway.py +0 -0
  143. {clawed-2.3.3 → clawed-2.3.4}/clawed/gateway_response.py +0 -0
  144. {clawed-2.3.3 → clawed-2.3.4}/clawed/generation.py +0 -0
  145. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/__init__.py +0 -0
  146. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/export.py +0 -0
  147. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/feedback.py +0 -0
  148. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/gaps.py +0 -0
  149. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/generate.py +0 -0
  150. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/misc.py +0 -0
  151. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/onboard.py +0 -0
  152. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/schedule.py +0 -0
  153. {clawed-2.3.3 → clawed-2.3.4}/clawed/handlers/standards.py +0 -0
  154. {clawed-2.3.3 → clawed-2.3.4}/clawed/improver.py +0 -0
  155. {clawed-2.3.3 → clawed-2.3.4}/clawed/ingestor.py +0 -0
  156. {clawed-2.3.3 → clawed-2.3.4}/clawed/io.py +0 -0
  157. {clawed-2.3.3 → clawed-2.3.4}/clawed/lesson.py +0 -0
  158. {clawed-2.3.3 → clawed-2.3.4}/clawed/llm.py +0 -0
  159. {clawed-2.3.3 → clawed-2.3.4}/clawed/materials.py +0 -0
  160. {clawed-2.3.3 → clawed-2.3.4}/clawed/mcp_server.py +0 -0
  161. {clawed-2.3.3 → clawed-2.3.4}/clawed/memory_engine.py +0 -0
  162. {clawed-2.3.3 → clawed-2.3.4}/clawed/model_router.py +0 -0
  163. {clawed-2.3.3 → clawed-2.3.4}/clawed/onboarding.py +0 -0
  164. {clawed-2.3.3 → clawed-2.3.4}/clawed/openclaw_plugin.py +0 -0
  165. {clawed-2.3.3 → clawed-2.3.4}/clawed/parent_comm.py +0 -0
  166. {clawed-2.3.3 → clawed-2.3.4}/clawed/persona.py +0 -0
  167. {clawed-2.3.3 → clawed-2.3.4}/clawed/persona_evolution.py +0 -0
  168. {clawed-2.3.3 → clawed-2.3.4}/clawed/planner.py +0 -0
  169. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/504_accommodations.txt +0 -0
  170. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/admin_lesson_plan.txt +0 -0
  171. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/assessment.txt +0 -0
  172. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/curriculum_gaps.txt +0 -0
  173. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/dbq_assessment.txt +0 -0
  174. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/differentiation.txt +0 -0
  175. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/formative_assessment.txt +0 -0
  176. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/iep_modification.txt +0 -0
  177. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/lesson_plan.txt +0 -0
  178. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/pacing_guide.txt +0 -0
  179. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/parent_note.txt +0 -0
  180. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/persona_extract.txt +0 -0
  181. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/quiz.txt +0 -0
  182. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/rubric.txt +0 -0
  183. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/student_packet.txt +0 -0
  184. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/sub_packet.txt +0 -0
  185. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/summative_assessment.txt +0 -0
  186. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/tiered_assignments.txt +0 -0
  187. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/unit_plan.txt +0 -0
  188. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/worksheet.txt +0 -0
  189. {clawed-2.3.3 → clawed-2.3.4}/clawed/prompts/year_map.txt +0 -0
  190. {clawed-2.3.3 → clawed-2.3.4}/clawed/quality.py +0 -0
  191. {clawed-2.3.3 → clawed-2.3.4}/clawed/reading_report.py +0 -0
  192. {clawed-2.3.3 → clawed-2.3.4}/clawed/router.py +0 -0
  193. {clawed-2.3.3 → clawed-2.3.4}/clawed/sanitize.py +0 -0
  194. {clawed-2.3.3 → clawed-2.3.4}/clawed/scheduler.py +0 -0
  195. {clawed-2.3.3 → clawed-2.3.4}/clawed/school.py +0 -0
  196. {clawed-2.3.3 → clawed-2.3.4}/clawed/search.py +0 -0
  197. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/__init__.py +0 -0
  198. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/art.py +0 -0
  199. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/base.py +0 -0
  200. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/computer_science.py +0 -0
  201. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/ela.py +0 -0
  202. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/foreign_language.py +0 -0
  203. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/history.py +0 -0
  204. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/library.py +0 -0
  205. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/math.py +0 -0
  206. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/music.py +0 -0
  207. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/physical_education.py +0 -0
  208. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/science.py +0 -0
  209. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/social_studies.py +0 -0
  210. {clawed-2.3.3 → clawed-2.3.4}/clawed/skills/special_education.py +0 -0
  211. {clawed-2.3.3 → clawed-2.3.4}/clawed/standards.py +0 -0
  212. {clawed-2.3.3 → clawed-2.3.4}/clawed/state.py +0 -0
  213. {clawed-2.3.3 → clawed-2.3.4}/clawed/state_standards.py +0 -0
  214. {clawed-2.3.3 → clawed-2.3.4}/clawed/student_bot.py +0 -0
  215. {clawed-2.3.3 → clawed-2.3.4}/clawed/student_cli.py +0 -0
  216. {clawed-2.3.3 → clawed-2.3.4}/clawed/student_telegram_bot.py +0 -0
  217. {clawed-2.3.3 → clawed-2.3.4}/clawed/task_queue.py +0 -0
  218. {clawed-2.3.3 → clawed-2.3.4}/clawed/templates_lib.py +0 -0
  219. {clawed-2.3.3 → clawed-2.3.4}/clawed/tools.py +0 -0
  220. {clawed-2.3.3 → clawed-2.3.4}/clawed/transports/__init__.py +0 -0
  221. {clawed-2.3.3 → clawed-2.3.4}/clawed/transports/cli.py +0 -0
  222. {clawed-2.3.3 → clawed-2.3.4}/clawed/transports/openclaw.py +0 -0
  223. {clawed-2.3.3 → clawed-2.3.4}/clawed/transports/student_telegram.py +0 -0
  224. {clawed-2.3.3 → clawed-2.3.4}/clawed/transports/telegram.py +0 -0
  225. {clawed-2.3.3 → clawed-2.3.4}/clawed/transports/web.py +0 -0
  226. {clawed-2.3.3 → clawed-2.3.4}/clawed/tui.py +0 -0
  227. {clawed-2.3.3 → clawed-2.3.4}/clawed/tui_chat.py +0 -0
  228. {clawed-2.3.3 → clawed-2.3.4}/clawed/voice.py +0 -0
  229. {clawed-2.3.3 → clawed-2.3.4}/clawed/voice_check.py +0 -0
  230. {clawed-2.3.3 → clawed-2.3.4}/clawed/workspace.py +0 -0
  231. {clawed-2.3.3 → clawed-2.3.4}/eduagent/__init__.py +0 -0
  232. {clawed-2.3.3 → clawed-2.3.4}/eduagent/_compat.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clawed
3
- Version: 2.3.3
3
+ Version: 2.3.4
4
4
  Summary: Claw-ED — personal AI teaching agent. Learns your voice, works while you sleep.
5
5
  Project-URL: Homepage, https://github.com/SirhanMacx/Claw-ED
6
6
  Project-URL: Documentation, https://github.com/SirhanMacx/Claw-ED#readme
@@ -17,7 +17,7 @@ if hasattr(sys.stderr, "reconfigure"):
17
17
  except Exception:
18
18
  pass
19
19
 
20
- __version__ = "2.3.3"
20
+ __version__ = "2.3.4"
21
21
  __author__ = "Jon Maccarello & Claw-ED contributors"
22
22
  __description__ = "Personal AI teaching agent. Learns your voice, works while you sleep."
23
23
 
@@ -91,7 +91,11 @@ def build_system_prompt(
91
91
  " 'Building your lesson package now — plan, handout, and slides coming up.'\n"
92
92
  "The teacher should always know you're working, not stuck.\n"
93
93
  "1. Read SOUL.md to know your voice and values\n"
94
- "2. Search the teacher's curriculum files for relevant prior work\n"
94
+ "2. **MANDATORY: Before calling generate_lesson_bundle, ALWAYS call "
95
+ "search_my_materials first** with the lesson topic. This is non-negotiable. "
96
+ "The teacher has uploaded materials — if you skip this step, you will "
97
+ "generate generic content instead of building on their prior work. "
98
+ "Tell the teacher what you found before generating.\n"
95
99
  "3. Generate complete packages (lesson plan + student handout + slideshow) "
96
100
  "using generate_lesson_bundle\n"
97
101
  "4. Never ask 'want me to create materials?' -- just create them\n"
@@ -22,7 +22,10 @@ class GenerateLessonBundleTool:
22
22
  "description": (
23
23
  "Generate a COMPLETE teaching package for a topic: "
24
24
  "a lesson plan (DOCX), a student handout (DOCX), and "
25
- "a slideshow (PPTX). All three files are created at once."
25
+ "a slideshow (PPTX). All three files are created at once. "
26
+ "IMPORTANT: Always call search_my_materials FIRST to find "
27
+ "the teacher's existing materials on this topic before "
28
+ "calling this tool."
26
29
  ),
27
30
  "parameters": {
28
31
  "type": "object",
@@ -65,7 +65,31 @@ class IngestMaterialsTool:
65
65
  from clawed.persona import extract_persona, save_persona
66
66
 
67
67
  persona = await extract_persona(docs, context.config)
68
+ # Override LLM-inferred name with configured teacher name
69
+ try:
70
+ if context.config and context.config.teacher_profile and context.config.teacher_profile.name:
71
+ persona.name = f"{context.config.teacher_profile.name} Teaching Persona"
72
+ except Exception:
73
+ pass
74
+ try:
75
+ _id_path = Path.home() / ".eduagent" / "workspace" / "identity.md"
76
+ if _id_path.exists():
77
+ import re as _re
78
+ _id_content = _id_path.read_text(encoding="utf-8")
79
+ _name_match = _re.match(r"^#\s+(.+)", _id_content)
80
+ if _name_match:
81
+ _tname = _name_match.group(1).strip()
82
+ if _tname and _tname != "Teacher":
83
+ persona.name = f"{_tname} Teaching Persona"
84
+ except Exception:
85
+ pass
68
86
  save_persona(persona, Path.home() / ".eduagent")
87
+ # Track persona changes for evolution
88
+ try:
89
+ from clawed.persona_evolution import record_ingestion_changes
90
+ record_ingestion_changes(old_persona=None, new_persona=persona)
91
+ except Exception:
92
+ pass
69
93
  except Exception:
70
94
  pass
71
95
 
@@ -129,6 +153,39 @@ class IngestMaterialsTool:
129
153
  except Exception as e:
130
154
  logger.debug("KB indexing failed: %s", e)
131
155
 
156
+ # Register assets for file-level search
157
+ try:
158
+ from clawed.asset_registry import AssetRegistry
159
+ registry = AssetRegistry()
160
+ asset_count = 0
161
+ for doc in docs:
162
+ doc_type_val = (
163
+ doc.doc_type.value
164
+ if hasattr(doc.doc_type, "value")
165
+ else str(doc.doc_type)
166
+ )
167
+ extraction = None
168
+ if doc.source_path:
169
+ try:
170
+ from clawed.ingestor import extract_rich
171
+ extraction = extract_rich(Path(doc.source_path))
172
+ except Exception:
173
+ pass
174
+ aid = registry.register_asset(
175
+ teacher_id=context.teacher_id,
176
+ source_path=doc.source_path or "",
177
+ title=doc.title,
178
+ doc_type=doc_type_val,
179
+ text=doc.content,
180
+ extraction=extraction,
181
+ )
182
+ if aid:
183
+ asset_count += 1
184
+ if asset_count:
185
+ summary += f" ({asset_count} files catalogued for search)"
186
+ except Exception as e:
187
+ logger.debug("Asset registration failed: %s", e)
188
+
132
189
  # Update SOUL.md with what we learned
133
190
  try:
134
191
  soul_path = Path.home() / ".eduagent" / "workspace" / "SOUL.md"
@@ -130,8 +130,36 @@ def ingest(
130
130
  persona = _run_async(extract_persona(documents))
131
131
  progress.update(task, description="Persona extracted!")
132
132
 
133
+ # Override LLM-inferred name with configured teacher name
134
+ try:
135
+ cfg = AppConfig.load()
136
+ if cfg.teacher_profile and cfg.teacher_profile.name:
137
+ persona.name = f"{cfg.teacher_profile.name} Teaching Persona"
138
+ except Exception:
139
+ pass
140
+ # Also check identity.md
141
+ try:
142
+ identity_path = Path.home() / ".eduagent" / "workspace" / "identity.md"
143
+ if identity_path.exists():
144
+ import re
145
+ content = identity_path.read_text(encoding="utf-8")
146
+ name_match = re.match(r"^#\s+(.+)", content)
147
+ if name_match:
148
+ teacher_name = name_match.group(1).strip()
149
+ if teacher_name and teacher_name != "Teacher":
150
+ persona.name = f"{teacher_name} Teaching Persona"
151
+ except Exception:
152
+ pass
153
+
133
154
  out = save_persona(persona, _output_dir())
134
155
 
156
+ # Track persona changes for evolution
157
+ try:
158
+ from clawed.persona_evolution import record_ingestion_changes
159
+ record_ingestion_changes(old_persona=None, new_persona=persona)
160
+ except Exception:
161
+ pass
162
+
135
163
  # Index documents into curriculum knowledge base for KB search
136
164
  kb_msg = ""
137
165
  try:
@@ -60,6 +60,25 @@ class IngestHandler:
60
60
  try:
61
61
  from clawed.models import AppConfig
62
62
  persona = await extract_persona(documents, AppConfig.load())
63
+ # Override LLM-inferred name with configured teacher name
64
+ try:
65
+ config = AppConfig.load()
66
+ if config.teacher_profile and config.teacher_profile.name:
67
+ persona.name = f"{config.teacher_profile.name} Teaching Persona"
68
+ except Exception:
69
+ pass
70
+ try:
71
+ _id_path = Path.home() / ".eduagent" / "workspace" / "identity.md"
72
+ if _id_path.exists():
73
+ import re as _re
74
+ _id_content = _id_path.read_text(encoding="utf-8")
75
+ _name_match = _re.match(r"^#\s+(.+)", _id_content)
76
+ if _name_match:
77
+ _tname = _name_match.group(1).strip()
78
+ if _tname and _tname != "Teacher":
79
+ persona.name = f"{_tname} Teaching Persona"
80
+ except Exception:
81
+ pass
63
82
  from clawed.persona import save_persona
64
83
  save_persona(persona, Path.home() / ".eduagent")
65
84
  style_info = f"\nLearned teaching style: {persona.teaching_style}"
@@ -97,6 +116,35 @@ class IngestHandler:
97
116
  except Exception as e:
98
117
  logger.debug("KB indexing skipped: %s", e)
99
118
 
119
+ # Register assets (files, images, YouTube links) for search
120
+ try:
121
+ from clawed.asset_registry import AssetRegistry
122
+ registry = AssetRegistry()
123
+ asset_count = 0
124
+ for doc in documents:
125
+ doc_type_val = doc.doc_type.value if hasattr(doc.doc_type, "value") else str(doc.doc_type)
126
+ extraction = None
127
+ if doc.source_path:
128
+ try:
129
+ from clawed.ingestor import extract_rich
130
+ extraction = extract_rich(Path(doc.source_path))
131
+ except Exception:
132
+ pass
133
+ aid = registry.register_asset(
134
+ teacher_id=teacher_id,
135
+ source_path=doc.source_path or "",
136
+ title=doc.title,
137
+ doc_type=doc_type_val,
138
+ text=doc.content,
139
+ extraction=extraction,
140
+ )
141
+ if aid:
142
+ asset_count += 1
143
+ if asset_count:
144
+ kb_info += f" ({asset_count} files catalogued with images and links)"
145
+ except Exception as e:
146
+ logger.debug("Asset registration skipped: %s", e)
147
+
100
148
  return GatewayResponse(
101
149
  text=f"Ingested {len(documents)} document(s).{style_info}{kb_info}"
102
150
  )
@@ -488,6 +488,15 @@ class WorksheetItem(BaseModel):
488
488
  answer_key: str = ""
489
489
  point_value: int = 1
490
490
 
491
+ @field_validator("point_value", mode="before")
492
+ @classmethod
493
+ def _coerce_point_value(cls, v):
494
+ if isinstance(v, str):
495
+ import re
496
+ match = re.match(r"(\d+)", v.strip())
497
+ return int(match.group(1)) if match else 1
498
+ return v
499
+
491
500
 
492
501
  class AssessmentQuestion(BaseModel):
493
502
  """A single assessment question."""
@@ -499,6 +508,15 @@ class AssessmentQuestion(BaseModel):
499
508
  correct_answer: str = ""
500
509
  point_value: int = 1
501
510
 
511
+ @field_validator("point_value", mode="before")
512
+ @classmethod
513
+ def _coerce_point_value(cls, v):
514
+ if isinstance(v, str):
515
+ import re
516
+ match = re.match(r"(\d+)", v.strip())
517
+ return int(match.group(1)) if match else 1
518
+ return v
519
+
502
520
 
503
521
  class RubricCriterion(BaseModel):
504
522
  """A single rubric criterion with levels."""
@@ -674,6 +692,15 @@ class SummativeQuestion(BaseModel):
674
692
  point_value: int = 1
675
693
  standard_aligned: str = ""
676
694
 
695
+ @field_validator("point_value", mode="before")
696
+ @classmethod
697
+ def _coerce_point_value(cls, v):
698
+ if isinstance(v, str):
699
+ import re
700
+ match = re.match(r"(\d+)", v.strip())
701
+ return int(match.group(1)) if match else 1
702
+ return v
703
+
677
704
 
678
705
  class SummativeAssessment(BaseModel):
679
706
  """Unit test — mix of MC, short answer, DBQ/essay aligned to all unit objectives."""
@@ -253,16 +253,17 @@ def _select_sources(subject: str, topic: str = "") -> list[str]:
253
253
 
254
254
  Returns an ordered list of source identifiers to try.
255
255
  Teacher's own images are always checked first.
256
+ Only uses academic sources (LOC, Wikimedia). No stock photos.
256
257
  """
257
258
  subject_lower = subject.strip().lower()
258
259
  if any(s in subject_lower for s in ("history", "social", "civics", "government")):
259
- return ["teacher_files", "loc", "wikimedia", "unsplash"]
260
+ return ["teacher_files", "loc", "wikimedia"]
260
261
  elif any(s in subject_lower for s in ("science", "biology", "chemistry", "physics")):
261
- return ["teacher_files", "wikimedia", "loc", "unsplash"]
262
+ return ["teacher_files", "wikimedia", "loc"]
262
263
  elif any(s in subject_lower for s in ("art", "music")):
263
- return ["teacher_files", "wikimedia", "loc", "unsplash"]
264
+ return ["teacher_files", "wikimedia", "loc"]
264
265
  else:
265
- return ["teacher_files", "loc", "wikimedia", "unsplash"]
266
+ return ["teacher_files", "loc", "wikimedia"]
266
267
 
267
268
 
268
269
  # ── Cache helpers ────────────────────────────────────────────────────
@@ -497,14 +498,25 @@ async def _fetch_teacher_image(
497
498
 
498
499
  with sqlite3.connect(db_path) as conn:
499
500
  conn.row_factory = sqlite3.Row
500
- # Join asset_images to assets to search by context + title
501
- rows = conn.execute(
502
- "SELECT ai.image_path, ai.context_text, a.title "
503
- "FROM asset_images ai "
504
- "JOIN assets a ON ai.asset_id = a.id "
505
- "WHERE ai.image_path != '' "
506
- "LIMIT 500",
507
- ).fetchall()
501
+ # Pre-filter by topic keywords in SQL for efficiency
502
+ if keywords:
503
+ like_clauses = " OR ".join(
504
+ "(lower(ai.context_text) LIKE '%' || ? || '%' OR lower(a.title) LIKE '%' || ? || '%')"
505
+ for _ in keywords[:5]
506
+ )
507
+ params = []
508
+ for kw in keywords[:5]:
509
+ params.extend([kw, kw])
510
+ rows = conn.execute(
511
+ f"SELECT ai.image_path, ai.context_text, a.title "
512
+ f"FROM asset_images ai "
513
+ f"JOIN assets a ON ai.asset_id = a.id "
514
+ f"WHERE ai.image_path != '' AND ({like_clauses}) "
515
+ f"LIMIT 100",
516
+ params,
517
+ ).fetchall()
518
+ else:
519
+ rows = []
508
520
 
509
521
  best_path: Optional[str] = None
510
522
  best_score = 0
@@ -540,8 +552,8 @@ async def _fetch_teacher_image(
540
552
  best_score = score
541
553
  best_path = row["image_path"]
542
554
 
543
- # Require minimum score of 2 (at least one keyword match)
544
- if best_path and best_score >= 2 and Path(best_path).exists():
555
+ # Require minimum score of 6 (exact phrase match or 3+ keyword hits)
556
+ if best_path and best_score >= 6 and Path(best_path).exists():
545
557
  logger.info("Using teacher's own image for '%s' -> %s", query, best_path)
546
558
  return Path(best_path)
547
559
  except Exception as e:
@@ -43,6 +43,13 @@ class SubPacket(BaseModel):
43
43
  closing_notes: str = ""
44
44
  generated_at: datetime = Field(default_factory=datetime.now)
45
45
 
46
+ @field_validator("student_notes", mode="before")
47
+ @classmethod
48
+ def _coerce_student_notes(cls, v):
49
+ if isinstance(v, list):
50
+ return "\n".join(str(item) for item in v)
51
+ return v
52
+
46
53
  @field_validator("emergency_info", mode="before")
47
54
  @classmethod
48
55
  def coerce_emergency_info(cls, v):
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "clawed"
7
- version = "2.3.3"
7
+ version = "2.3.4"
8
8
  description = "Claw-ED — personal AI teaching agent. Learns your voice, works while you sleep."
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes