clawed 2.3.0__tar.gz → 2.3.1__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 (230) hide show
  1. {clawed-2.3.0 → clawed-2.3.1}/PKG-INFO +1 -1
  2. {clawed-2.3.0 → clawed-2.3.1}/clawed/__init__.py +1 -1
  3. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_pptx.py +100 -44
  4. {clawed-2.3.0 → clawed-2.3.1}/clawed/onboarding.py +22 -5
  5. {clawed-2.3.0 → clawed-2.3.1}/pyproject.toml +1 -1
  6. {clawed-2.3.0 → clawed-2.3.1}/.gitignore +0 -0
  7. {clawed-2.3.0 → clawed-2.3.1}/LICENSE +0 -0
  8. {clawed-2.3.0 → clawed-2.3.1}/README.md +0 -0
  9. {clawed-2.3.0 → clawed-2.3.1}/clawed/__main__.py +0 -0
  10. {clawed-2.3.0 → clawed-2.3.1}/clawed/_legacy_gateway.py +0 -0
  11. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent.py +0 -0
  12. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/__init__.py +0 -0
  13. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/approvals.py +0 -0
  14. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/autonomy.py +0 -0
  15. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/context.py +0 -0
  16. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/core.py +0 -0
  17. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/custom_tools.py +0 -0
  18. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/drive/__init__.py +0 -0
  19. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/drive/auth.py +0 -0
  20. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/drive/client.py +0 -0
  21. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/fake_llm.py +0 -0
  22. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/loop.py +0 -0
  23. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/__init__.py +0 -0
  24. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/curriculum.py +0 -0
  25. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/curriculum_kb.py +0 -0
  26. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/embeddings.py +0 -0
  27. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/episodes.py +0 -0
  28. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/identity.py +0 -0
  29. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/loader.py +0 -0
  30. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/memory/preferences.py +0 -0
  31. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/planner.py +0 -0
  32. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/prompt.py +0 -0
  33. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/scheduler.py +0 -0
  34. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/__init__.py +0 -0
  35. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/base.py +0 -0
  36. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/configure_profile.py +0 -0
  37. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/curriculum_map.py +0 -0
  38. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/drive_create_doc.py +0 -0
  39. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/drive_create_slides.py +0 -0
  40. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/drive_list.py +0 -0
  41. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/drive_organize.py +0 -0
  42. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/drive_read.py +0 -0
  43. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/drive_upload.py +0 -0
  44. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/export_document.py +0 -0
  45. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/gap_analysis.py +0 -0
  46. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/generate_assessment.py +0 -0
  47. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/generate_lesson.py +0 -0
  48. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/generate_lesson_bundle.py +0 -0
  49. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/generate_materials.py +0 -0
  50. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/generate_unit.py +0 -0
  51. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/ingest_materials.py +0 -0
  52. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/parent_comm.py +0 -0
  53. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/read_heartbeat.py +0 -0
  54. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/read_workspace.py +0 -0
  55. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/request_approval.py +0 -0
  56. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/schedule_task.py +0 -0
  57. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/search_lessons.py +0 -0
  58. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/search_my_materials.py +0 -0
  59. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/search_standards.py +0 -0
  60. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/student_insights.py +0 -0
  61. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/sub_packet.py +0 -0
  62. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/switch_model.py +0 -0
  63. {clawed-2.3.0 → clawed-2.3.1}/clawed/agent_core/tools/update_soul.py +0 -0
  64. {clawed-2.3.0 → clawed-2.3.1}/clawed/analytics.py +0 -0
  65. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/__init__.py +0 -0
  66. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/deps.py +0 -0
  67. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/__init__.py +0 -0
  68. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/chat.py +0 -0
  69. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/export.py +0 -0
  70. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/feedback.py +0 -0
  71. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/gateway_chat.py +0 -0
  72. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/generate.py +0 -0
  73. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/ingest.py +0 -0
  74. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/lessons.py +0 -0
  75. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/school.py +0 -0
  76. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/settings.py +0 -0
  77. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/routes/tools.py +0 -0
  78. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/server.py +0 -0
  79. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/static/app.js +0 -0
  80. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/static/style.css +0 -0
  81. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/static/widget.js +0 -0
  82. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/analytics.html +0 -0
  83. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/base.html +0 -0
  84. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/dashboard.html +0 -0
  85. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/generate.html +0 -0
  86. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/index.html +0 -0
  87. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/lesson.html +0 -0
  88. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/profile.html +0 -0
  89. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/settings.html +0 -0
  90. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/stats.html +0 -0
  91. {clawed-2.3.0 → clawed-2.3.1}/clawed/api/templates/students.html +0 -0
  92. {clawed-2.3.0 → clawed-2.3.1}/clawed/assessment.py +0 -0
  93. {clawed-2.3.0 → clawed-2.3.1}/clawed/asset_registry.py +0 -0
  94. {clawed-2.3.0 → clawed-2.3.1}/clawed/auth/__init__.py +0 -0
  95. {clawed-2.3.0 → clawed-2.3.1}/clawed/auth/google_auth.py +0 -0
  96. {clawed-2.3.0 → clawed-2.3.1}/clawed/bot_state.py +0 -0
  97. {clawed-2.3.0 → clawed-2.3.1}/clawed/chat.py +0 -0
  98. {clawed-2.3.0 → clawed-2.3.1}/clawed/cli.py +0 -0
  99. {clawed-2.3.0 → clawed-2.3.1}/clawed/cli_chat.py +0 -0
  100. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/__init__.py +0 -0
  101. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/_helpers.py +0 -0
  102. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/bot.py +0 -0
  103. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/config.py +0 -0
  104. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/config_llm.py +0 -0
  105. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/config_profile.py +0 -0
  106. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/export.py +0 -0
  107. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/generate.py +0 -0
  108. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/generate_assessment.py +0 -0
  109. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/generate_unit.py +0 -0
  110. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/queue.py +0 -0
  111. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/schedule_cmd.py +0 -0
  112. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/sub.py +0 -0
  113. {clawed-2.3.0 → clawed-2.3.1}/clawed/commands/workspace_cmd.py +0 -0
  114. {clawed-2.3.0 → clawed-2.3.1}/clawed/config.py +0 -0
  115. {clawed-2.3.0 → clawed-2.3.1}/clawed/corpus.py +0 -0
  116. {clawed-2.3.0 → clawed-2.3.1}/clawed/curriculum_map.py +0 -0
  117. {clawed-2.3.0 → clawed-2.3.1}/clawed/database.py +0 -0
  118. {clawed-2.3.0 → clawed-2.3.1}/clawed/demo/__init__.py +0 -0
  119. {clawed-2.3.0 → clawed-2.3.1}/clawed/demo/demo_assessment.json +0 -0
  120. {clawed-2.3.0 → clawed-2.3.1}/clawed/demo/demo_lesson_science_g6.json +0 -0
  121. {clawed-2.3.0 → clawed-2.3.1}/clawed/demo/demo_lesson_social_studies_g8.json +0 -0
  122. {clawed-2.3.0 → clawed-2.3.1}/clawed/demo/demo_unit_plan.json +0 -0
  123. {clawed-2.3.0 → clawed-2.3.1}/clawed/differentiation.py +0 -0
  124. {clawed-2.3.0 → clawed-2.3.1}/clawed/doc_export.py +0 -0
  125. {clawed-2.3.0 → clawed-2.3.1}/clawed/drive.py +0 -0
  126. {clawed-2.3.0 → clawed-2.3.1}/clawed/evaluation.py +0 -0
  127. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_docx.py +0 -0
  128. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_handout.py +0 -0
  129. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_markdown.py +0 -0
  130. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_pdf.py +0 -0
  131. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_templates.py +0 -0
  132. {clawed-2.3.0 → clawed-2.3.1}/clawed/export_theme.py +0 -0
  133. {clawed-2.3.0 → clawed-2.3.1}/clawed/exporter.py +0 -0
  134. {clawed-2.3.0 → clawed-2.3.1}/clawed/feedback.py +0 -0
  135. {clawed-2.3.0 → clawed-2.3.1}/clawed/formats/__init__.py +0 -0
  136. {clawed-2.3.0 → clawed-2.3.1}/clawed/formats/flipchart.py +0 -0
  137. {clawed-2.3.0 → clawed-2.3.1}/clawed/formats/notebook.py +0 -0
  138. {clawed-2.3.0 → clawed-2.3.1}/clawed/formats/xbk.py +0 -0
  139. {clawed-2.3.0 → clawed-2.3.1}/clawed/gateway.py +0 -0
  140. {clawed-2.3.0 → clawed-2.3.1}/clawed/gateway_response.py +0 -0
  141. {clawed-2.3.0 → clawed-2.3.1}/clawed/generation.py +0 -0
  142. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/__init__.py +0 -0
  143. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/export.py +0 -0
  144. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/feedback.py +0 -0
  145. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/gaps.py +0 -0
  146. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/generate.py +0 -0
  147. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/ingest.py +0 -0
  148. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/misc.py +0 -0
  149. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/onboard.py +0 -0
  150. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/schedule.py +0 -0
  151. {clawed-2.3.0 → clawed-2.3.1}/clawed/handlers/standards.py +0 -0
  152. {clawed-2.3.0 → clawed-2.3.1}/clawed/improver.py +0 -0
  153. {clawed-2.3.0 → clawed-2.3.1}/clawed/ingestor.py +0 -0
  154. {clawed-2.3.0 → clawed-2.3.1}/clawed/io.py +0 -0
  155. {clawed-2.3.0 → clawed-2.3.1}/clawed/lesson.py +0 -0
  156. {clawed-2.3.0 → clawed-2.3.1}/clawed/llm.py +0 -0
  157. {clawed-2.3.0 → clawed-2.3.1}/clawed/materials.py +0 -0
  158. {clawed-2.3.0 → clawed-2.3.1}/clawed/mcp_server.py +0 -0
  159. {clawed-2.3.0 → clawed-2.3.1}/clawed/memory_engine.py +0 -0
  160. {clawed-2.3.0 → clawed-2.3.1}/clawed/model_router.py +0 -0
  161. {clawed-2.3.0 → clawed-2.3.1}/clawed/models.py +0 -0
  162. {clawed-2.3.0 → clawed-2.3.1}/clawed/openclaw_plugin.py +0 -0
  163. {clawed-2.3.0 → clawed-2.3.1}/clawed/parent_comm.py +0 -0
  164. {clawed-2.3.0 → clawed-2.3.1}/clawed/persona.py +0 -0
  165. {clawed-2.3.0 → clawed-2.3.1}/clawed/planner.py +0 -0
  166. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/504_accommodations.txt +0 -0
  167. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/admin_lesson_plan.txt +0 -0
  168. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/assessment.txt +0 -0
  169. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/curriculum_gaps.txt +0 -0
  170. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/dbq_assessment.txt +0 -0
  171. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/differentiation.txt +0 -0
  172. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/formative_assessment.txt +0 -0
  173. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/iep_modification.txt +0 -0
  174. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/lesson_plan.txt +0 -0
  175. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/pacing_guide.txt +0 -0
  176. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/parent_note.txt +0 -0
  177. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/persona_extract.txt +0 -0
  178. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/quiz.txt +0 -0
  179. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/rubric.txt +0 -0
  180. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/student_packet.txt +0 -0
  181. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/sub_packet.txt +0 -0
  182. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/summative_assessment.txt +0 -0
  183. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/tiered_assignments.txt +0 -0
  184. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/unit_plan.txt +0 -0
  185. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/worksheet.txt +0 -0
  186. {clawed-2.3.0 → clawed-2.3.1}/clawed/prompts/year_map.txt +0 -0
  187. {clawed-2.3.0 → clawed-2.3.1}/clawed/quality.py +0 -0
  188. {clawed-2.3.0 → clawed-2.3.1}/clawed/reading_report.py +0 -0
  189. {clawed-2.3.0 → clawed-2.3.1}/clawed/router.py +0 -0
  190. {clawed-2.3.0 → clawed-2.3.1}/clawed/sanitize.py +0 -0
  191. {clawed-2.3.0 → clawed-2.3.1}/clawed/scheduler.py +0 -0
  192. {clawed-2.3.0 → clawed-2.3.1}/clawed/school.py +0 -0
  193. {clawed-2.3.0 → clawed-2.3.1}/clawed/search.py +0 -0
  194. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/__init__.py +0 -0
  195. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/art.py +0 -0
  196. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/base.py +0 -0
  197. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/computer_science.py +0 -0
  198. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/ela.py +0 -0
  199. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/foreign_language.py +0 -0
  200. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/history.py +0 -0
  201. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/library.py +0 -0
  202. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/math.py +0 -0
  203. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/music.py +0 -0
  204. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/physical_education.py +0 -0
  205. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/science.py +0 -0
  206. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/social_studies.py +0 -0
  207. {clawed-2.3.0 → clawed-2.3.1}/clawed/skills/special_education.py +0 -0
  208. {clawed-2.3.0 → clawed-2.3.1}/clawed/slide_images.py +0 -0
  209. {clawed-2.3.0 → clawed-2.3.1}/clawed/standards.py +0 -0
  210. {clawed-2.3.0 → clawed-2.3.1}/clawed/state.py +0 -0
  211. {clawed-2.3.0 → clawed-2.3.1}/clawed/state_standards.py +0 -0
  212. {clawed-2.3.0 → clawed-2.3.1}/clawed/student_bot.py +0 -0
  213. {clawed-2.3.0 → clawed-2.3.1}/clawed/student_cli.py +0 -0
  214. {clawed-2.3.0 → clawed-2.3.1}/clawed/student_telegram_bot.py +0 -0
  215. {clawed-2.3.0 → clawed-2.3.1}/clawed/sub_packet.py +0 -0
  216. {clawed-2.3.0 → clawed-2.3.1}/clawed/task_queue.py +0 -0
  217. {clawed-2.3.0 → clawed-2.3.1}/clawed/templates_lib.py +0 -0
  218. {clawed-2.3.0 → clawed-2.3.1}/clawed/tools.py +0 -0
  219. {clawed-2.3.0 → clawed-2.3.1}/clawed/transports/__init__.py +0 -0
  220. {clawed-2.3.0 → clawed-2.3.1}/clawed/transports/cli.py +0 -0
  221. {clawed-2.3.0 → clawed-2.3.1}/clawed/transports/openclaw.py +0 -0
  222. {clawed-2.3.0 → clawed-2.3.1}/clawed/transports/student_telegram.py +0 -0
  223. {clawed-2.3.0 → clawed-2.3.1}/clawed/transports/telegram.py +0 -0
  224. {clawed-2.3.0 → clawed-2.3.1}/clawed/transports/web.py +0 -0
  225. {clawed-2.3.0 → clawed-2.3.1}/clawed/tui.py +0 -0
  226. {clawed-2.3.0 → clawed-2.3.1}/clawed/tui_chat.py +0 -0
  227. {clawed-2.3.0 → clawed-2.3.1}/clawed/voice.py +0 -0
  228. {clawed-2.3.0 → clawed-2.3.1}/clawed/workspace.py +0 -0
  229. {clawed-2.3.0 → clawed-2.3.1}/eduagent/__init__.py +0 -0
  230. {clawed-2.3.0 → clawed-2.3.1}/eduagent/_compat.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clawed
3
- Version: 2.3.0
3
+ Version: 2.3.1
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.0"
20
+ __version__ = "2.3.1"
21
21
  __author__ = "Jon Maccarello & Claw-ED contributors"
22
22
  __description__ = "Personal AI teaching agent. Learns your voice, works while you sleep."
23
23
 
@@ -455,7 +455,7 @@ def export_lesson_pptx(
455
455
 
456
456
  # Lesson title -- 44pt white bold, centered
457
457
  tb = slide.shapes.add_textbox(
458
- Inches(1.5), Inches(2.0), slide_w - Inches(3.0), Inches(2.5),
458
+ Inches(1.5), Inches(1.5), slide_w - Inches(3.0), Inches(2.5),
459
459
  )
460
460
  tf = tb.text_frame
461
461
  tf.word_wrap = True
@@ -465,9 +465,30 @@ def export_lesson_pptx(
465
465
  run.text = lesson.title
466
466
  _set_text_props(run, 44, theme["text_light"], bold=True)
467
467
 
468
- # Subtitle: "Lesson N | Teacher Name | Date" -- 20pt white
468
+ # Aim -- the driving question, centered below title
469
+ aim_text = lesson.objective
470
+ if aim_text and not aim_text.lower().startswith("students will"):
471
+ aim_display = f"Aim: {aim_text}"
472
+ elif aim_text:
473
+ aim_display = aim_text
474
+ else:
475
+ aim_display = ""
476
+ if aim_display:
477
+ tb_aim = slide.shapes.add_textbox(
478
+ Inches(1.5), Inches(4.0), slide_w - Inches(3.0), Inches(1.0),
479
+ )
480
+ tf_aim = tb_aim.text_frame
481
+ tf_aim.word_wrap = True
482
+ p_aim = tf_aim.paragraphs[0]
483
+ p_aim.alignment = PP_ALIGN.CENTER
484
+ run_aim = p_aim.add_run()
485
+ run_aim.text = aim_display
486
+ _set_text_props(run_aim, 20, "EEEEEE")
487
+ run_aim.font.italic = True
488
+
489
+ # Subtitle: "Teacher Name | Date" -- 16pt
469
490
  tb2 = slide.shapes.add_textbox(
470
- Inches(1.5), Inches(4.8), slide_w - Inches(3.0), Inches(1.0),
491
+ Inches(1.5), Inches(5.2), slide_w - Inches(3.0), Inches(0.8),
471
492
  )
472
493
  tf2 = tb2.text_frame
473
494
  tf2.word_wrap = True
@@ -475,11 +496,10 @@ def export_lesson_pptx(
475
496
  p2.alignment = PP_ALIGN.CENTER
476
497
  run2 = p2.add_run()
477
498
  run2.text = (
478
- f"Lesson {lesson.lesson_number} | "
479
499
  f"{teacher_display_name} | "
480
500
  f"{date.today().strftime('%B %d, %Y')}"
481
501
  )
482
- _set_text_props(run2, 20, "DDDDDD")
502
+ _set_text_props(run2, 16, "BBBBBB")
483
503
 
484
504
  # Bottom accent bar in subject color
485
505
  _bar(slide, Emu(0), slide_h - Inches(0.15), slide_w, Inches(0.15), theme["secondary"])
@@ -663,41 +683,45 @@ def export_lesson_pptx(
663
683
 
664
684
  _add_footer(slide, slide_num[0])
665
685
 
666
- # ── Vocabulary slide (if terms detected) ───────────────────
667
- # Try multiple patterns for vocabulary extraction
668
- di_text_raw = lesson.direct_instruction or ""
669
- vocab_patterns: list[tuple[str, str]] = []
670
-
671
- # Pattern 1: **Bold Term** definition
672
- vocab_patterns = re.findall(
673
- r'\*\*([A-Z][^*]{2,30})\*\*\s*[-—:]+\s*([^*\n]{15,200})',
674
- di_text_raw,
675
- )
676
- # Pattern 2: KEY TERM: definition or Term: definition (capitalized)
677
- if not vocab_patterns:
686
+ # ── Vocabulary slide ───────────────────────────────────────
687
+ # Prefer structured vocabulary from v2.3 model fields
688
+ vocab_pairs: list[tuple[str, str]] = []
689
+ if hasattr(lesson, "vocabulary") and lesson.vocabulary:
690
+ for vt in lesson.vocabulary:
691
+ term = getattr(vt, "term", "") if hasattr(vt, "term") else vt.get("term", "")
692
+ defn = getattr(vt, "definition", "") if hasattr(vt, "definition") else vt.get("definition", "")
693
+ if term and defn:
694
+ vocab_pairs.append((term, defn))
695
+
696
+ # Fallback: regex extraction from DI text
697
+ if not vocab_pairs:
698
+ di_text_raw = lesson.direct_instruction or ""
678
699
  vocab_patterns = re.findall(
679
- r'(?:^|\n)\s*\*?\*?([A-Z][a-z]+(?:\s+[A-Za-z]+){0,3})\*?\*?\s*[-—:]+\s+'
680
- r'([A-Za-z][^\n]{15,200})',
700
+ r'\*\*([A-Z][^*]{2,30})\*\*\s*[-—:]+\s*([^*\n]{15,200})',
681
701
  di_text_raw,
682
702
  )
683
-
684
- # Filter out instructional directions and non-vocabulary content
685
- INSTRUCTIONAL_WORDS = {
686
- "check", "ask", "call", "facilitate", "transition", "minutes",
687
- "discuss", "display", "distribute", "brief", "move", "moved",
688
- "students", "responses", "excellent", "turn", "now", "let",
689
- "today", "good", "morning", "scholars", "friends", "class",
690
- "next", "first", "take", "look", "read", "write", "complete",
691
- }
692
- vocab_patterns = [
693
- (term.strip(), defn.strip()) for term, defn in vocab_patterns
694
- if 1 <= len(term.split()) <= 4
695
- and len(defn.split()) >= 3
696
- and not any(w in defn.lower().split()[:3] for w in INSTRUCTIONAL_WORDS)
697
- and not any(w in term.lower().split() for w in INSTRUCTIONAL_WORDS)
698
- ]
699
-
700
- if vocab_patterns:
703
+ if not vocab_patterns:
704
+ vocab_patterns = re.findall(
705
+ r'(?:^|\n)\s*\*?\*?([A-Z][a-z]+(?:\s+[A-Za-z]+){0,3})\*?\*?\s*[-—:]+\s+'
706
+ r'([A-Za-z][^\n]{15,200})',
707
+ di_text_raw,
708
+ )
709
+ INSTRUCTIONAL_WORDS = {
710
+ "check", "ask", "call", "facilitate", "transition", "minutes",
711
+ "discuss", "display", "distribute", "brief", "move", "moved",
712
+ "students", "responses", "excellent", "turn", "now", "let",
713
+ "today", "good", "morning", "scholars", "friends", "class",
714
+ "next", "first", "take", "look", "read", "write", "complete",
715
+ }
716
+ vocab_pairs = [
717
+ (term.strip(), defn.strip()) for term, defn in vocab_patterns
718
+ if 1 <= len(term.split()) <= 4
719
+ and len(defn.split()) >= 3
720
+ and not any(w in defn.lower().split()[:3] for w in INSTRUCTIONAL_WORDS)
721
+ and not any(w in term.lower().split() for w in INSTRUCTIONAL_WORDS)
722
+ ]
723
+
724
+ if vocab_pairs:
701
725
  slide = _next_slide()
702
726
  _white_bg(slide)
703
727
 
@@ -724,7 +748,7 @@ def export_lesson_pptx(
724
748
  tf = tb.text_frame
725
749
  tf.word_wrap = True
726
750
 
727
- for idx, (term, definition) in enumerate(vocab_patterns[:8]):
751
+ for idx, (term, definition) in enumerate(vocab_pairs[:8]):
728
752
  p = tf.paragraphs[0] if idx == 0 else tf.add_paragraph()
729
753
  p.space_before = Pt(10)
730
754
  p.line_spacing = Pt(36)
@@ -808,7 +832,11 @@ def export_lesson_pptx(
808
832
  # SECTION DIVIDER: "Let's Practice Together"
809
833
  # ═══════════════════════════════════════════════════════════════════
810
834
  if lesson.guided_practice:
811
- _section_divider(prs, slide_num, "Let's Practice Together", theme, slide_w, slide_h)
835
+ gp_min = lesson.time_estimates.get("guided_practice", 15)
836
+ _section_divider(
837
+ prs, slide_num, f"Let's Practice Together\n({gp_min} minutes)",
838
+ theme, slide_w, slide_h,
839
+ )
812
840
 
813
841
  # ═══════════════════════════════════════════════════════════════════
814
842
  # GUIDED PRACTICE -- "Your Turn" header
@@ -832,7 +860,16 @@ def export_lesson_pptx(
832
860
 
833
861
  # No image on Guided Practice -- keep clean for readability
834
862
 
835
- # Activity instructions -- 24pt
863
+ # Brief student-facing instructions on slide face (first 2-3 sentences)
864
+ gp_text = lesson.guided_practice
865
+ gp_summary = gp_text
866
+ if len(gp_text) > 250:
867
+ cutoff = gp_text[:250].rfind(". ")
868
+ if cutoff > 80:
869
+ gp_summary = gp_text[:cutoff + 1]
870
+ else:
871
+ gp_summary = gp_text[:250].rsplit(" ", 1)[0] + "..."
872
+
836
873
  tb = slide.shapes.add_textbox(
837
874
  Inches(0.8), Inches(1.8), slide_w - Inches(2.0), Inches(4.5),
838
875
  )
@@ -841,9 +878,14 @@ def export_lesson_pptx(
841
878
  p = tf.paragraphs[0]
842
879
  p.line_spacing = Pt(34)
843
880
  run = p.add_run()
844
- run.text = lesson.guided_practice
881
+ run.text = gp_summary
845
882
  _set_text_props(run, 24, theme["text_dark"])
846
883
 
884
+ # Full guided practice in speaker notes
885
+ notes_slide = slide.notes_slide
886
+ notes_tf = notes_slide.notes_text_frame
887
+ notes_tf.text = gp_text
888
+
847
889
  # Time estimate
848
890
  minutes = lesson.time_estimates.get("guided_practice", 15)
849
891
  tb_time = slide.shapes.add_textbox(
@@ -883,7 +925,16 @@ def export_lesson_pptx(
883
925
 
884
926
  # No image on Independent Work -- keep clean for readability
885
927
 
886
- # Task description -- 24pt
928
+ # Brief student-facing instructions on slide face
929
+ iw_text = lesson.independent_work
930
+ iw_summary = iw_text
931
+ if len(iw_text) > 250:
932
+ cutoff = iw_text[:250].rfind(". ")
933
+ if cutoff > 80:
934
+ iw_summary = iw_text[:cutoff + 1]
935
+ else:
936
+ iw_summary = iw_text[:250].rsplit(" ", 1)[0] + "..."
937
+
887
938
  tb = slide.shapes.add_textbox(
888
939
  Inches(1.0), Inches(1.8), slide_w - Inches(2.0), Inches(4.5),
889
940
  )
@@ -892,9 +943,14 @@ def export_lesson_pptx(
892
943
  p = tf.paragraphs[0]
893
944
  p.line_spacing = Pt(34)
894
945
  run = p.add_run()
895
- run.text = lesson.independent_work
946
+ run.text = iw_summary
896
947
  _set_text_props(run, 24, theme["text_dark"])
897
948
 
949
+ # Full independent work in speaker notes
950
+ notes_slide = slide.notes_slide
951
+ notes_tf = notes_slide.notes_text_frame
952
+ notes_tf.text = iw_text
953
+
898
954
  # Time estimate in corner
899
955
  minutes = lesson.time_estimates.get("independent_work", 10)
900
956
  _rounded_card(
@@ -919,7 +975,7 @@ def export_lesson_pptx(
919
975
  # SECTION DIVIDER: "Show What You Know"
920
976
  # ═══════════════════════════════════════════════════════════════════
921
977
  if lesson.exit_ticket:
922
- _section_divider(prs, slide_num, "Show What You Know", theme, slide_w, slide_h)
978
+ _section_divider(prs, slide_num, "Show What You Know\n(Exit Ticket)", theme, slide_w, slide_h)
923
979
 
924
980
  # ═══════════════════════════════════════════════════════════════════
925
981
  # EXIT TICKET -- distinctive assessment design
@@ -73,22 +73,35 @@ def _ask_provider() -> tuple[LLMProvider, str | None]:
73
73
  table.add_column("Provider")
74
74
  table.add_column("Cost")
75
75
  table.add_column("Notes")
76
- table.add_row("1", "Anthropic (Claude)", "Pay per token", "Best quality")
77
- table.add_row("2", "OpenAI (GPT-4o)", "Pay per token", "Widely used")
78
- table.add_row("3", "Ollama", "Free", "Runs locally \u2014 no API key needed")
76
+ table.add_row("1", "Google Gemini", "Free tier available", "Best for getting started \u2014 generous free quota")
77
+ table.add_row("2", "Anthropic (Claude)", "Pay per token", "Highest quality")
78
+ table.add_row("3", "OpenAI (GPT-4o)", "Pay per token", "Widely used")
79
+ table.add_row("4", "Ollama (local)", "Free", "Runs on your machine \u2014 no internet needed")
79
80
  console.print()
80
81
  console.print(table)
81
82
 
82
83
  while True:
83
- choice = Prompt.ask("\n[bold]Pick a provider[/bold]", choices=["1", "2", "3"], default="1")
84
+ choice = Prompt.ask(
85
+ "\n[bold]Pick a provider[/bold]", choices=["1", "2", "3", "4"], default="1",
86
+ )
84
87
  if choice == "1":
88
+ provider = LLMProvider.GOOGLE
89
+ console.print(
90
+ "\n [dim]Get a free API key at: https://aistudio.google.com/apikey[/dim]",
91
+ )
92
+ key = Prompt.ask(" [bold]Google AI API key[/bold] [dim](AIza...)[/dim]")
93
+ if not key.strip():
94
+ console.print(" [red]API key cannot be empty.[/red]")
95
+ continue
96
+ return provider, key.strip()
97
+ elif choice == "2":
85
98
  provider = LLMProvider.ANTHROPIC
86
99
  key = Prompt.ask(" [bold]Anthropic API key[/bold] [dim](sk-ant-...)[/dim]")
87
100
  if not key.strip():
88
101
  console.print(" [red]API key cannot be empty.[/red]")
89
102
  continue
90
103
  return provider, key.strip()
91
- elif choice == "2":
104
+ elif choice == "3":
92
105
  provider = LLMProvider.OPENAI
93
106
  key = Prompt.ask(" [bold]OpenAI API key[/bold] [dim](sk-...)[/dim]")
94
107
  if not key.strip():
@@ -126,6 +139,10 @@ def _detect_available_models() -> tuple[LLMProvider | None, str]:
126
139
  and Ollama running locally.
127
140
  Returns (provider, description) or (None, message).
128
141
  """
142
+ # Check Google Gemini (free tier)
143
+ if os.environ.get("GOOGLE_API_KEY"):
144
+ return LLMProvider.GOOGLE, "Google Gemini API key found in environment"
145
+
129
146
  # Check Anthropic
130
147
  if os.environ.get("ANTHROPIC_API_KEY"):
131
148
  return LLMProvider.ANTHROPIC, "Anthropic API key found in environment"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "clawed"
7
- version = "2.3.0"
7
+ version = "2.3.1"
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes