docagent-cli 0.0.35__py3-none-any.whl

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 (300) hide show
  1. docagent_cli/__init__.py +36 -0
  2. docagent_cli/__main__.py +6 -0
  3. docagent_cli/_ask_user_types.py +90 -0
  4. docagent_cli/_cli_context.py +27 -0
  5. docagent_cli/_debug.py +52 -0
  6. docagent_cli/_env_vars.py +56 -0
  7. docagent_cli/_server_config.py +352 -0
  8. docagent_cli/_session_stats.py +114 -0
  9. docagent_cli/_testing_models.py +144 -0
  10. docagent_cli/_version.py +17 -0
  11. docagent_cli/agent.py +1193 -0
  12. docagent_cli/app.py +4979 -0
  13. docagent_cli/app.tcss +283 -0
  14. docagent_cli/ask_user.py +301 -0
  15. docagent_cli/built_in_skills/__init__.py +5 -0
  16. docagent_cli/built_in_skills/doc-coauthoring/SKILL.md +375 -0
  17. docagent_cli/built_in_skills/docx/LICENSE.txt +30 -0
  18. docagent_cli/built_in_skills/docx/SKILL.md +590 -0
  19. docagent_cli/built_in_skills/docx/scripts/__init__.py +1 -0
  20. docagent_cli/built_in_skills/docx/scripts/accept_changes.py +135 -0
  21. docagent_cli/built_in_skills/docx/scripts/comment.py +318 -0
  22. docagent_cli/built_in_skills/docx/scripts/office/helpers/__init__.py +0 -0
  23. docagent_cli/built_in_skills/docx/scripts/office/helpers/merge_runs.py +199 -0
  24. docagent_cli/built_in_skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
  25. docagent_cli/built_in_skills/docx/scripts/office/pack.py +159 -0
  26. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  27. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  28. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  29. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  30. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  31. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  32. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  33. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  34. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  35. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  36. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  37. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  38. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  39. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  40. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  41. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  42. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  43. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  44. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  45. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  46. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  47. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  48. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  49. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  50. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  51. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  52. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  53. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  54. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  55. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  56. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  57. docagent_cli/built_in_skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
  58. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  59. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  60. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  61. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  62. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  63. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  64. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  65. docagent_cli/built_in_skills/docx/scripts/office/soffice.py +183 -0
  66. docagent_cli/built_in_skills/docx/scripts/office/unpack.py +132 -0
  67. docagent_cli/built_in_skills/docx/scripts/office/validate.py +111 -0
  68. docagent_cli/built_in_skills/docx/scripts/office/validators/__init__.py +15 -0
  69. docagent_cli/built_in_skills/docx/scripts/office/validators/base.py +847 -0
  70. docagent_cli/built_in_skills/docx/scripts/office/validators/docx.py +446 -0
  71. docagent_cli/built_in_skills/docx/scripts/office/validators/pptx.py +275 -0
  72. docagent_cli/built_in_skills/docx/scripts/office/validators/redlining.py +247 -0
  73. docagent_cli/built_in_skills/docx/scripts/templates/comments.xml +3 -0
  74. docagent_cli/built_in_skills/docx/scripts/templates/commentsExtended.xml +3 -0
  75. docagent_cli/built_in_skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  76. docagent_cli/built_in_skills/docx/scripts/templates/commentsIds.xml +3 -0
  77. docagent_cli/built_in_skills/docx/scripts/templates/people.xml +3 -0
  78. docagent_cli/built_in_skills/pdf/LICENSE.txt +30 -0
  79. docagent_cli/built_in_skills/pdf/SKILL.md +314 -0
  80. docagent_cli/built_in_skills/pdf/forms.md +294 -0
  81. docagent_cli/built_in_skills/pdf/reference.md +612 -0
  82. docagent_cli/built_in_skills/pdf/scripts/check_bounding_boxes.py +65 -0
  83. docagent_cli/built_in_skills/pdf/scripts/check_fillable_fields.py +11 -0
  84. docagent_cli/built_in_skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  85. docagent_cli/built_in_skills/pdf/scripts/create_validation_image.py +37 -0
  86. docagent_cli/built_in_skills/pdf/scripts/extract_form_field_info.py +122 -0
  87. docagent_cli/built_in_skills/pdf/scripts/extract_form_structure.py +115 -0
  88. docagent_cli/built_in_skills/pdf/scripts/fill_fillable_fields.py +98 -0
  89. docagent_cli/built_in_skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  90. docagent_cli/built_in_skills/pptx/LICENSE.txt +30 -0
  91. docagent_cli/built_in_skills/pptx/SKILL.md +232 -0
  92. docagent_cli/built_in_skills/pptx/editing.md +205 -0
  93. docagent_cli/built_in_skills/pptx/pptxgenjs.md +420 -0
  94. docagent_cli/built_in_skills/pptx/scripts/__init__.py +0 -0
  95. docagent_cli/built_in_skills/pptx/scripts/add_slide.py +195 -0
  96. docagent_cli/built_in_skills/pptx/scripts/clean.py +286 -0
  97. docagent_cli/built_in_skills/pptx/scripts/office/helpers/__init__.py +0 -0
  98. docagent_cli/built_in_skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
  99. docagent_cli/built_in_skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  100. docagent_cli/built_in_skills/pptx/scripts/office/pack.py +159 -0
  101. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  102. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  103. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  104. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  105. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  106. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  107. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  108. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  109. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  110. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  111. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  112. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  113. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  114. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  115. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  116. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  117. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  118. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  119. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  120. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  121. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  122. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  123. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  124. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  125. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  126. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  127. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  128. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  129. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  130. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  131. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  132. docagent_cli/built_in_skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  133. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  134. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  135. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  136. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  137. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  138. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  139. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  140. docagent_cli/built_in_skills/pptx/scripts/office/soffice.py +183 -0
  141. docagent_cli/built_in_skills/pptx/scripts/office/unpack.py +132 -0
  142. docagent_cli/built_in_skills/pptx/scripts/office/validate.py +111 -0
  143. docagent_cli/built_in_skills/pptx/scripts/office/validators/__init__.py +15 -0
  144. docagent_cli/built_in_skills/pptx/scripts/office/validators/base.py +847 -0
  145. docagent_cli/built_in_skills/pptx/scripts/office/validators/docx.py +446 -0
  146. docagent_cli/built_in_skills/pptx/scripts/office/validators/pptx.py +275 -0
  147. docagent_cli/built_in_skills/pptx/scripts/office/validators/redlining.py +247 -0
  148. docagent_cli/built_in_skills/pptx/scripts/thumbnail.py +289 -0
  149. docagent_cli/built_in_skills/remember/SKILL.md +118 -0
  150. docagent_cli/built_in_skills/skill-creator/LICENSE.txt +202 -0
  151. docagent_cli/built_in_skills/skill-creator/SKILL.md +485 -0
  152. docagent_cli/built_in_skills/skill-creator/agents/analyzer.md +274 -0
  153. docagent_cli/built_in_skills/skill-creator/agents/comparator.md +202 -0
  154. docagent_cli/built_in_skills/skill-creator/agents/grader.md +223 -0
  155. docagent_cli/built_in_skills/skill-creator/assets/eval_review.html +146 -0
  156. docagent_cli/built_in_skills/skill-creator/eval-viewer/generate_review.py +471 -0
  157. docagent_cli/built_in_skills/skill-creator/eval-viewer/viewer.html +1325 -0
  158. docagent_cli/built_in_skills/skill-creator/references/schemas.md +430 -0
  159. docagent_cli/built_in_skills/skill-creator/scripts/__init__.py +0 -0
  160. docagent_cli/built_in_skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  161. docagent_cli/built_in_skills/skill-creator/scripts/generate_report.py +326 -0
  162. docagent_cli/built_in_skills/skill-creator/scripts/improve_description.py +247 -0
  163. docagent_cli/built_in_skills/skill-creator/scripts/package_skill.py +136 -0
  164. docagent_cli/built_in_skills/skill-creator/scripts/quick_validate.py +103 -0
  165. docagent_cli/built_in_skills/skill-creator/scripts/run_eval.py +310 -0
  166. docagent_cli/built_in_skills/skill-creator/scripts/run_loop.py +328 -0
  167. docagent_cli/built_in_skills/skill-creator/scripts/utils.py +47 -0
  168. docagent_cli/built_in_skills/theme-factory/LICENSE.txt +202 -0
  169. docagent_cli/built_in_skills/theme-factory/SKILL.md +59 -0
  170. docagent_cli/built_in_skills/theme-factory/theme-showcase.pdf +0 -0
  171. docagent_cli/built_in_skills/theme-factory/themes/arctic-frost.md +19 -0
  172. docagent_cli/built_in_skills/theme-factory/themes/botanical-garden.md +19 -0
  173. docagent_cli/built_in_skills/theme-factory/themes/desert-rose.md +19 -0
  174. docagent_cli/built_in_skills/theme-factory/themes/forest-canopy.md +19 -0
  175. docagent_cli/built_in_skills/theme-factory/themes/golden-hour.md +19 -0
  176. docagent_cli/built_in_skills/theme-factory/themes/midnight-galaxy.md +19 -0
  177. docagent_cli/built_in_skills/theme-factory/themes/modern-minimalist.md +19 -0
  178. docagent_cli/built_in_skills/theme-factory/themes/ocean-depths.md +19 -0
  179. docagent_cli/built_in_skills/theme-factory/themes/sunset-boulevard.md +19 -0
  180. docagent_cli/built_in_skills/theme-factory/themes/tech-innovation.md +19 -0
  181. docagent_cli/built_in_skills/xlsx/LICENSE.txt +30 -0
  182. docagent_cli/built_in_skills/xlsx/SKILL.md +292 -0
  183. docagent_cli/built_in_skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  184. docagent_cli/built_in_skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  185. docagent_cli/built_in_skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  186. docagent_cli/built_in_skills/xlsx/scripts/office/pack.py +159 -0
  187. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  188. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  189. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  190. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  191. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  192. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  193. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  194. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  195. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  196. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  197. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  198. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  199. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  200. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  201. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  202. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  203. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  204. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  205. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  206. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  207. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  208. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  209. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  210. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  211. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  212. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  213. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  214. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  215. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  216. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  217. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  218. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  219. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  220. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  221. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  222. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  223. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  224. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  225. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  226. docagent_cli/built_in_skills/xlsx/scripts/office/soffice.py +183 -0
  227. docagent_cli/built_in_skills/xlsx/scripts/office/unpack.py +132 -0
  228. docagent_cli/built_in_skills/xlsx/scripts/office/validate.py +111 -0
  229. docagent_cli/built_in_skills/xlsx/scripts/office/validators/__init__.py +15 -0
  230. docagent_cli/built_in_skills/xlsx/scripts/office/validators/base.py +847 -0
  231. docagent_cli/built_in_skills/xlsx/scripts/office/validators/docx.py +446 -0
  232. docagent_cli/built_in_skills/xlsx/scripts/office/validators/pptx.py +275 -0
  233. docagent_cli/built_in_skills/xlsx/scripts/office/validators/redlining.py +247 -0
  234. docagent_cli/built_in_skills/xlsx/scripts/recalc.py +184 -0
  235. docagent_cli/clipboard.py +128 -0
  236. docagent_cli/command_registry.py +284 -0
  237. docagent_cli/config.py +2418 -0
  238. docagent_cli/configurable_model.py +162 -0
  239. docagent_cli/default_agent_prompt.md +12 -0
  240. docagent_cli/editor.py +142 -0
  241. docagent_cli/file_ops.py +473 -0
  242. docagent_cli/formatting.py +28 -0
  243. docagent_cli/hooks.py +206 -0
  244. docagent_cli/input.py +787 -0
  245. docagent_cli/integrations/__init__.py +1 -0
  246. docagent_cli/integrations/sandbox_factory.py +873 -0
  247. docagent_cli/integrations/sandbox_provider.py +71 -0
  248. docagent_cli/local_context.py +718 -0
  249. docagent_cli/main.py +1641 -0
  250. docagent_cli/mcp_tools.py +707 -0
  251. docagent_cli/mcp_trust.py +168 -0
  252. docagent_cli/media_utils.py +478 -0
  253. docagent_cli/model_config.py +1620 -0
  254. docagent_cli/non_interactive.py +948 -0
  255. docagent_cli/offload.py +371 -0
  256. docagent_cli/output.py +69 -0
  257. docagent_cli/project_utils.py +188 -0
  258. docagent_cli/py.typed +0 -0
  259. docagent_cli/remote_client.py +515 -0
  260. docagent_cli/server.py +520 -0
  261. docagent_cli/server_graph.py +196 -0
  262. docagent_cli/server_manager.py +365 -0
  263. docagent_cli/sessions.py +1262 -0
  264. docagent_cli/skills/__init__.py +18 -0
  265. docagent_cli/skills/commands.py +1090 -0
  266. docagent_cli/skills/load.py +192 -0
  267. docagent_cli/subagents.py +173 -0
  268. docagent_cli/system_prompt.md +247 -0
  269. docagent_cli/textual_adapter.py +1352 -0
  270. docagent_cli/theme.py +842 -0
  271. docagent_cli/token_state.py +31 -0
  272. docagent_cli/tool_display.py +298 -0
  273. docagent_cli/tools.py +236 -0
  274. docagent_cli/ui.py +420 -0
  275. docagent_cli/unicode_security.py +516 -0
  276. docagent_cli/update_check.py +454 -0
  277. docagent_cli/widgets/__init__.py +9 -0
  278. docagent_cli/widgets/_links.py +63 -0
  279. docagent_cli/widgets/approval.py +442 -0
  280. docagent_cli/widgets/ask_user.py +398 -0
  281. docagent_cli/widgets/autocomplete.py +691 -0
  282. docagent_cli/widgets/chat_input.py +1827 -0
  283. docagent_cli/widgets/diff.py +248 -0
  284. docagent_cli/widgets/history.py +188 -0
  285. docagent_cli/widgets/loading.py +177 -0
  286. docagent_cli/widgets/mcp_viewer.py +362 -0
  287. docagent_cli/widgets/message_store.py +675 -0
  288. docagent_cli/widgets/messages.py +1751 -0
  289. docagent_cli/widgets/model_selector.py +964 -0
  290. docagent_cli/widgets/status.py +372 -0
  291. docagent_cli/widgets/theme_selector.py +164 -0
  292. docagent_cli/widgets/thread_selector.py +1905 -0
  293. docagent_cli/widgets/tool_renderers.py +148 -0
  294. docagent_cli/widgets/tool_widgets.py +274 -0
  295. docagent_cli/widgets/welcome.py +339 -0
  296. docagent_cli-0.0.35.data/data/docagent_cli/default_agent_prompt.md +12 -0
  297. docagent_cli-0.0.35.dist-info/METADATA +200 -0
  298. docagent_cli-0.0.35.dist-info/RECORD +300 -0
  299. docagent_cli-0.0.35.dist-info/WHEEL +4 -0
  300. docagent_cli-0.0.35.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,31 @@
1
+ """Middleware that adds a `_context_tokens` channel to the graph state.
2
+
3
+ The field is checkpointed (survives across sessions) but not passed to the
4
+ model (`PrivateStateAttr`). The CLI writes the latest total-context token
5
+ count here after every LLM response and context offload, and reads it back
6
+ when resuming a thread so that `/tokens` and the status bar show accurate
7
+ values immediately.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import Annotated, NotRequired
13
+
14
+ from langchain.agents.middleware.types import (
15
+ AgentMiddleware,
16
+ AgentState,
17
+ PrivateStateAttr,
18
+ )
19
+
20
+
21
+ class TokenTrackingState(AgentState):
22
+ """Extends agent state with a persisted context-token counter."""
23
+
24
+ _context_tokens: Annotated[NotRequired[int], PrivateStateAttr]
25
+ """Total context tokens reported by the model's last `usage_metadata`."""
26
+
27
+
28
+ class TokenStateMiddleware(AgentMiddleware):
29
+ """Schema-only middleware that registers `_context_tokens` in the state schema."""
30
+
31
+ state_schema = TokenTrackingState
@@ -0,0 +1,298 @@
1
+ """Formatting utilities for tool call display in the CLI.
2
+
3
+ This module handles rendering tool calls and tool messages for the TUI.
4
+
5
+ Imported at module level by `textual_adapter` (itself deferred from the startup
6
+ path). Heavy SDK dependencies (e.g., `backends`) are deferred to function bodies.
7
+ """
8
+
9
+ import json
10
+ from contextlib import suppress
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+ from docagent_cli.config import MAX_ARG_LENGTH, get_glyphs
15
+ from docagent_cli.unicode_security import strip_dangerous_unicode
16
+
17
+ _HIDDEN_CHAR_MARKER = " [hidden chars removed]"
18
+ """Marker appended to display values that had dangerous Unicode stripped, so
19
+ users know the value was modified for safety."""
20
+
21
+
22
+ def _format_timeout(seconds: int) -> str:
23
+ """Format timeout in human-readable units (e.g., 300 -> '5m', 3600 -> '1h').
24
+
25
+ Args:
26
+ seconds: The timeout value in seconds to format.
27
+
28
+ Returns:
29
+ Human-readable timeout string (e.g., '5m', '1h', '300s').
30
+ """
31
+ if seconds < 60: # noqa: PLR2004 # Time unit boundary
32
+ return f"{seconds}s"
33
+ if seconds < 3600 and seconds % 60 == 0: # noqa: PLR2004 # Time unit boundaries
34
+ return f"{seconds // 60}m"
35
+ if seconds % 3600 == 0:
36
+ return f"{seconds // 3600}h"
37
+ # For odd values, just show seconds
38
+ return f"{seconds}s"
39
+
40
+
41
+ def _coerce_timeout_seconds(timeout: int | str | None) -> int | None:
42
+ """Normalize timeout values to seconds for display.
43
+
44
+ Accepts integer values and numeric strings. Returns `None` for invalid
45
+ values so display formatting never raises.
46
+
47
+ Args:
48
+ timeout: Raw timeout value from tool arguments.
49
+
50
+ Returns:
51
+ Integer timeout in seconds, or `None` if unavailable/invalid.
52
+ """
53
+ if type(timeout) is int:
54
+ return timeout
55
+ if isinstance(timeout, str):
56
+ stripped = timeout.strip()
57
+ if not stripped:
58
+ return None
59
+ try:
60
+ return int(stripped)
61
+ except ValueError:
62
+ return None
63
+ return None
64
+
65
+
66
+ def truncate_value(value: str, max_length: int = MAX_ARG_LENGTH) -> str:
67
+ """Truncate a string value if it exceeds max_length.
68
+
69
+ Returns:
70
+ Truncated string with ellipsis suffix if exceeded, otherwise original.
71
+ """
72
+ if len(value) > max_length:
73
+ return value[:max_length] + get_glyphs().ellipsis
74
+ return value
75
+
76
+
77
+ def _sanitize_display_value(value: object, *, max_length: int = MAX_ARG_LENGTH) -> str:
78
+ """Sanitize a value for safe, compact terminal display.
79
+
80
+ Hidden/deceptive Unicode controls are stripped. When stripping occurs, a
81
+ marker is appended so users know the value changed for display safety.
82
+
83
+ Args:
84
+ value: Any value to display.
85
+ max_length: Maximum display length before truncation.
86
+
87
+ Returns:
88
+ Sanitized display string.
89
+ """
90
+ raw = str(value)
91
+ sanitized = strip_dangerous_unicode(raw)
92
+ display = truncate_value(sanitized, max_length)
93
+ if sanitized != raw:
94
+ return display + _HIDDEN_CHAR_MARKER
95
+ return display
96
+
97
+
98
+ def format_tool_display(tool_name: str, tool_args: dict) -> str:
99
+ """Format tool calls for display with tool-specific smart formatting.
100
+
101
+ Shows the most relevant information for each tool type rather than all arguments.
102
+
103
+ Args:
104
+ tool_name: Name of the tool being called
105
+ tool_args: Dictionary of tool arguments
106
+
107
+ Returns:
108
+ Formatted string for display (e.g., "(*) read_file(config.py)" in ASCII mode)
109
+
110
+ Examples:
111
+ read_file(path="/long/path/file.py") → "<prefix> read_file(file.py)"
112
+ web_search(query="how to code") → '<prefix> web_search("how to code")'
113
+ execute(command="pip install foo") → '<prefix> execute("pip install foo")'
114
+ """
115
+ prefix = get_glyphs().tool_prefix
116
+
117
+ def abbreviate_path(path_str: str, max_length: int = 60) -> str:
118
+ """Abbreviate a file path intelligently - show basename or relative path.
119
+
120
+ Returns:
121
+ Shortened path string suitable for display.
122
+ """
123
+ try:
124
+ path = Path(path_str)
125
+
126
+ # If it's just a filename (no directory parts), return as-is
127
+ if len(path.parts) == 1:
128
+ return path_str
129
+
130
+ # Try to get relative path from current working directory
131
+ with suppress(
132
+ ValueError, # ValueError: path is not relative to cwd
133
+ OSError, # OSError: filesystem errors when resolving paths
134
+ ):
135
+ rel_path = path.relative_to(Path.cwd())
136
+ rel_str = str(rel_path)
137
+ # Use relative if it's shorter and not too long
138
+ if len(rel_str) < len(path_str) and len(rel_str) <= max_length:
139
+ return rel_str
140
+
141
+ # If absolute path is reasonable length, use it
142
+ if len(path_str) <= max_length:
143
+ return path_str
144
+ except Exception: # noqa: BLE001 # Fallback to original string on any path resolution error
145
+ return truncate_value(path_str, max_length)
146
+ else:
147
+ # Otherwise, just show basename (filename only)
148
+ return path.name
149
+
150
+ # Tool-specific formatting - show the most important argument(s)
151
+ if tool_name in {"read_file", "write_file", "edit_file"}:
152
+ # File operations: show the primary file path argument (file_path or path)
153
+ path_value = tool_args.get("file_path")
154
+ if path_value is None:
155
+ path_value = tool_args.get("path")
156
+ if path_value is not None:
157
+ path_raw = strip_dangerous_unicode(str(path_value))
158
+ path = abbreviate_path(path_raw)
159
+ if path_raw != str(path_value):
160
+ path += _HIDDEN_CHAR_MARKER
161
+ return f"{prefix} {tool_name}({path})"
162
+
163
+ elif tool_name == "web_search":
164
+ # Web search: show the query string
165
+ if "query" in tool_args:
166
+ query = _sanitize_display_value(tool_args["query"], max_length=100)
167
+ return f'{prefix} {tool_name}("{query}")'
168
+
169
+ elif tool_name == "grep":
170
+ # Grep: show the search pattern
171
+ if "pattern" in tool_args:
172
+ pattern = _sanitize_display_value(tool_args["pattern"], max_length=70)
173
+ return f'{prefix} {tool_name}("{pattern}")'
174
+
175
+ elif tool_name == "execute":
176
+ # Execute: show the command, and timeout only if non-default
177
+ if "command" in tool_args:
178
+ command = _sanitize_display_value(tool_args["command"], max_length=120)
179
+ timeout = _coerce_timeout_seconds(tool_args.get("timeout"))
180
+ from deepagents.backends import DEFAULT_EXECUTE_TIMEOUT
181
+
182
+ if timeout is not None and timeout != DEFAULT_EXECUTE_TIMEOUT:
183
+ timeout_str = _format_timeout(timeout)
184
+ return f'{prefix} {tool_name}("{command}", timeout={timeout_str})'
185
+ return f'{prefix} {tool_name}("{command}")'
186
+
187
+ elif tool_name == "ls":
188
+ # ls: show directory, or empty if current directory
189
+ if tool_args.get("path"):
190
+ path_raw = strip_dangerous_unicode(str(tool_args["path"]))
191
+ path = abbreviate_path(path_raw)
192
+ if path_raw != str(tool_args["path"]):
193
+ path += _HIDDEN_CHAR_MARKER
194
+ return f"{prefix} {tool_name}({path})"
195
+ return f"{prefix} {tool_name}()"
196
+
197
+ elif tool_name == "glob":
198
+ # Glob: show the pattern
199
+ if "pattern" in tool_args:
200
+ pattern = _sanitize_display_value(tool_args["pattern"], max_length=80)
201
+ return f'{prefix} {tool_name}("{pattern}")'
202
+
203
+ elif tool_name == "fetch_url":
204
+ # Fetch URL: show the URL being fetched
205
+ if "url" in tool_args:
206
+ url = _sanitize_display_value(tool_args["url"], max_length=80)
207
+ return f'{prefix} {tool_name}("{url}")'
208
+
209
+ elif tool_name == "task":
210
+ # Task: show subagent type badge
211
+ agent_type = tool_args.get("subagent_type", "")
212
+ if agent_type:
213
+ agent_type = _sanitize_display_value(agent_type, max_length=40)
214
+ return f"{prefix} {tool_name} [{agent_type}]"
215
+ return f"{prefix} {tool_name}"
216
+
217
+ elif tool_name == "ask_user":
218
+ if "questions" in tool_args and isinstance(tool_args["questions"], list):
219
+ count = len(tool_args["questions"])
220
+ label = "question" if count == 1 else "questions"
221
+ return f"{prefix} {tool_name}({count} {label})"
222
+
223
+ elif tool_name == "compact_conversation":
224
+ return f"{prefix} {tool_name}()"
225
+
226
+ elif tool_name == "write_todos":
227
+ if "todos" in tool_args and isinstance(tool_args["todos"], list):
228
+ count = len(tool_args["todos"])
229
+ return f"{prefix} {tool_name}({count} items)"
230
+
231
+ # Fallback: generic formatting for unknown tools
232
+ # Show all arguments in key=value format
233
+ args_str = ", ".join(
234
+ f"{_sanitize_display_value(k, max_length=30)}="
235
+ f"{_sanitize_display_value(v, max_length=50)}"
236
+ for k, v in tool_args.items()
237
+ )
238
+ return f"{prefix} {tool_name}({args_str})"
239
+
240
+
241
+ def _format_content_block(block: dict) -> str:
242
+ """Format a single content block dict for display.
243
+
244
+ Replaces large binary payloads (e.g. base64 image/video data) with a
245
+ human-readable placeholder so they don't flood the terminal.
246
+
247
+ Args:
248
+ block: An `ImageContentBlock`, `VideoContentBlock`, or `FileContentBlock`
249
+ dictionary.
250
+
251
+ Returns:
252
+ A display-friendly string for the block.
253
+ """
254
+ if block.get("type") == "image" and isinstance(block.get("base64"), str):
255
+ b64 = block["base64"]
256
+ size_kb = len(b64) * 3 // 4 // 1024 # approximate decoded size
257
+ mime = block.get("mime_type", "image")
258
+ return f"[Image: {mime}, ~{size_kb}KB]"
259
+ if block.get("type") == "video" and isinstance(block.get("base64"), str):
260
+ b64 = block["base64"]
261
+ size_kb = len(b64) * 3 // 4 // 1024 # approximate decoded size
262
+ mime = block.get("mime_type", "video")
263
+ return f"[Video: {mime}, ~{size_kb}KB]"
264
+ if block.get("type") == "file" and isinstance(block.get("base64"), str):
265
+ b64 = block["base64"]
266
+ size_kb = len(b64) * 3 // 4 // 1024 # approximate decoded size
267
+ mime = block.get("mime_type", "file")
268
+ return f"[File: {mime}, ~{size_kb}KB]"
269
+ try:
270
+ # Preserve non-ASCII characters (CJK, emoji, etc.) instead of \uXXXX escapes
271
+ return json.dumps(block, ensure_ascii=False)
272
+ except (TypeError, ValueError):
273
+ return str(block)
274
+
275
+
276
+ def format_tool_message_content(content: Any) -> str: # noqa: ANN401 # Content can be str, list, or dict
277
+ """Convert `ToolMessage` content into a printable string.
278
+
279
+ Returns:
280
+ Formatted string representation of the tool message content.
281
+ """
282
+ if content is None:
283
+ return ""
284
+ if isinstance(content, list):
285
+ parts = []
286
+ for item in content:
287
+ if isinstance(item, str):
288
+ parts.append(item)
289
+ elif isinstance(item, dict):
290
+ parts.append(_format_content_block(item))
291
+ else:
292
+ try:
293
+ # Preserve non-ASCII characters (CJK, emoji, etc.)
294
+ parts.append(json.dumps(item, ensure_ascii=False))
295
+ except (TypeError, ValueError):
296
+ parts.append(str(item))
297
+ return "\n".join(parts)
298
+ return str(content)
docagent_cli/tools.py ADDED
@@ -0,0 +1,236 @@
1
+ """Custom tools for the CLI agent."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Literal
6
+
7
+ if TYPE_CHECKING:
8
+ from tavily import TavilyClient
9
+
10
+ _UNSET = object()
11
+ _tavily_client: TavilyClient | object | None = _UNSET
12
+
13
+
14
+ def _get_tavily_client() -> TavilyClient | None:
15
+ """Get or initialize the lazy Tavily client singleton.
16
+
17
+ Returns:
18
+ TavilyClient instance, or None if API key is not configured.
19
+ """
20
+ global _tavily_client # noqa: PLW0603 # Module-level cache requires global statement
21
+ if _tavily_client is not _UNSET:
22
+ return _tavily_client # type: ignore[return-value] # narrowed by sentinel check
23
+
24
+ from docagent_cli.config import settings
25
+
26
+ if settings.has_tavily:
27
+ from tavily import TavilyClient as _TavilyClient
28
+
29
+ _tavily_client = _TavilyClient(api_key=settings.tavily_api_key)
30
+ else:
31
+ _tavily_client = None
32
+ return _tavily_client
33
+
34
+
35
+ def http_request(
36
+ url: str,
37
+ method: str = "GET",
38
+ headers: dict[str, str] | None = None,
39
+ data: str | dict | None = None,
40
+ params: dict[str, str] | None = None,
41
+ timeout: int = 30,
42
+ ) -> dict[str, Any]:
43
+ """Make HTTP requests to APIs and web services.
44
+
45
+ Args:
46
+ url: Target URL
47
+ method: HTTP method (GET, POST, PUT, DELETE, etc.)
48
+ headers: HTTP headers to include
49
+ data: Request body data (string or dict)
50
+ params: URL query parameters
51
+ timeout: Request timeout in seconds
52
+
53
+ Returns:
54
+ Dictionary with response data including status, headers, and content
55
+ """
56
+ import requests
57
+
58
+ try:
59
+ kwargs: dict[str, Any] = {}
60
+
61
+ if headers:
62
+ kwargs["headers"] = headers
63
+ if params:
64
+ kwargs["params"] = params
65
+ if data:
66
+ if isinstance(data, dict):
67
+ kwargs["json"] = data
68
+ else:
69
+ kwargs["data"] = data
70
+
71
+ response = requests.request(method.upper(), url, timeout=timeout, **kwargs)
72
+
73
+ try:
74
+ content = response.json()
75
+ except (ValueError, requests.exceptions.JSONDecodeError):
76
+ content = response.text
77
+
78
+ return {
79
+ "success": response.status_code < 400, # noqa: PLR2004 # HTTP status code threshold
80
+ "status_code": response.status_code,
81
+ "headers": dict(response.headers),
82
+ "content": content,
83
+ "url": response.url,
84
+ }
85
+
86
+ except requests.exceptions.Timeout:
87
+ return {
88
+ "success": False,
89
+ "status_code": 0,
90
+ "headers": {},
91
+ "content": f"Request timed out after {timeout} seconds",
92
+ "url": url,
93
+ }
94
+ except requests.exceptions.RequestException as e:
95
+ return {
96
+ "success": False,
97
+ "status_code": 0,
98
+ "headers": {},
99
+ "content": f"Request error: {e!s}",
100
+ "url": url,
101
+ }
102
+
103
+
104
+ def web_search( # noqa: ANN201 # Return type depends on dynamic tool configuration
105
+ query: str,
106
+ max_results: int = 5,
107
+ topic: Literal["general", "news", "finance"] = "general",
108
+ include_raw_content: bool = False,
109
+ ):
110
+ """Search the web using Tavily for current information and documentation.
111
+
112
+ This tool searches the web and returns relevant results. After receiving results,
113
+ you MUST synthesize the information into a natural, helpful response for the user.
114
+
115
+ Args:
116
+ query: The search query (be specific and detailed)
117
+ max_results: Number of results to return (default: 5)
118
+ topic: Search topic type - "general" for most queries, "news" for current events
119
+ include_raw_content: Include full page content (warning: uses more tokens)
120
+
121
+ Returns:
122
+ Dictionary containing:
123
+ - results: List of search results, each with:
124
+ - title: Page title
125
+ - url: Page URL
126
+ - content: Relevant excerpt from the page
127
+ - score: Relevance score (0-1)
128
+ - query: The original search query
129
+
130
+ IMPORTANT: After using this tool:
131
+ 1. Read through the 'content' field of each result
132
+ 2. Extract relevant information that answers the user's question
133
+ 3. Synthesize this into a clear, natural language response
134
+ 4. Cite sources by mentioning the page titles or URLs
135
+ 5. NEVER show the raw JSON to the user - always provide a formatted response
136
+ """
137
+ try:
138
+ import requests
139
+ from tavily import (
140
+ BadRequestError,
141
+ InvalidAPIKeyError,
142
+ MissingAPIKeyError,
143
+ UsageLimitExceededError,
144
+ )
145
+ from tavily.errors import ForbiddenError, TimeoutError as TavilyTimeoutError
146
+ except ImportError as exc:
147
+ return {
148
+ "error": f"Required package not installed: {exc.name}. "
149
+ "Install with: pip install 'docagent[cli]'",
150
+ "query": query,
151
+ }
152
+
153
+ client = _get_tavily_client()
154
+ if client is None:
155
+ return {
156
+ "error": "Tavily API key not configured. "
157
+ "Please set TAVILY_API_KEY environment variable.",
158
+ "query": query,
159
+ }
160
+
161
+ try:
162
+ return client.search(
163
+ query,
164
+ max_results=max_results,
165
+ include_raw_content=include_raw_content,
166
+ topic=topic,
167
+ )
168
+ except (
169
+ requests.exceptions.RequestException,
170
+ ValueError,
171
+ TypeError,
172
+ # Tavily-specific exceptions
173
+ BadRequestError,
174
+ ForbiddenError,
175
+ InvalidAPIKeyError,
176
+ MissingAPIKeyError,
177
+ TavilyTimeoutError,
178
+ UsageLimitExceededError,
179
+ ) as e:
180
+ return {"error": f"Web search error: {e!s}", "query": query}
181
+
182
+
183
+ def fetch_url(url: str, timeout: int = 30) -> dict[str, Any]:
184
+ """Fetch content from a URL and convert HTML to markdown format.
185
+
186
+ This tool fetches web page content and converts it to clean markdown text,
187
+ making it easy to read and process HTML content. After receiving the markdown,
188
+ you MUST synthesize the information into a natural, helpful response for the user.
189
+
190
+ Args:
191
+ url: The URL to fetch (must be a valid HTTP/HTTPS URL)
192
+ timeout: Request timeout in seconds (default: 30)
193
+
194
+ Returns:
195
+ Dictionary containing:
196
+ - success: Whether the request succeeded
197
+ - url: The final URL after redirects
198
+ - markdown_content: The page content converted to markdown
199
+ - status_code: HTTP status code
200
+ - content_length: Length of the markdown content in characters
201
+
202
+ IMPORTANT: After using this tool:
203
+ 1. Read through the markdown content
204
+ 2. Extract relevant information that answers the user's question
205
+ 3. Synthesize this into a clear, natural language response
206
+ 4. NEVER show the raw markdown to the user unless specifically requested
207
+ """
208
+ try:
209
+ import requests
210
+ from markdownify import markdownify
211
+ except ImportError as exc:
212
+ return {
213
+ "error": f"Required package not installed: {exc.name}. "
214
+ "Install with: pip install 'docagent[cli]'",
215
+ "url": url,
216
+ }
217
+
218
+ try:
219
+ response = requests.get(
220
+ url,
221
+ timeout=timeout,
222
+ headers={"User-Agent": "Mozilla/5.0 (compatible; DeepAgents/1.0)"},
223
+ )
224
+ response.raise_for_status()
225
+
226
+ # Convert HTML content to markdown
227
+ markdown_content = markdownify(response.text)
228
+
229
+ return {
230
+ "url": str(response.url),
231
+ "markdown_content": markdown_content,
232
+ "status_code": response.status_code,
233
+ "content_length": len(markdown_content),
234
+ }
235
+ except requests.exceptions.RequestException as e:
236
+ return {"error": f"Fetch URL error: {e!s}", "url": url}