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
docagent_cli/server.py ADDED
@@ -0,0 +1,520 @@
1
+ """LangGraph server lifecycle management for the CLI.
2
+
3
+ Handles starting/stopping a `langgraph dev` server process and generating the
4
+ required `langgraph.json` configuration file.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ import contextlib
11
+ import json
12
+ import logging
13
+ import os
14
+ import signal
15
+ import subprocess # noqa: S404
16
+ import sys
17
+ import tempfile
18
+ import time
19
+ from pathlib import Path
20
+ from typing import TYPE_CHECKING, Any, Self
21
+
22
+ if TYPE_CHECKING:
23
+ from collections.abc import Callable, Iterator
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ _DEFAULT_HOST = "127.0.0.1"
28
+ _DEFAULT_PORT = 2024
29
+ _HEALTH_POLL_INTERVAL_LOCAL = 0.1
30
+ _HEALTH_POLL_INTERVAL_REMOTE = 0.3
31
+ _HEALTH_TIMEOUT = 60
32
+ _SHUTDOWN_TIMEOUT = 5
33
+
34
+
35
+ def _port_in_use(host: str, port: int) -> bool:
36
+ """Check if a port is already in use.
37
+
38
+ Args:
39
+ host: Host to check.
40
+ port: Port to check.
41
+
42
+ Returns:
43
+ `True` if the port is in use.
44
+ """
45
+ import socket
46
+
47
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
48
+ try:
49
+ s.bind((host, port))
50
+ except OSError:
51
+ return True
52
+ else:
53
+ return False
54
+
55
+
56
+ def _find_free_port(host: str) -> int:
57
+ """Find a free port on the given host.
58
+
59
+ Args:
60
+ host: Host to bind to.
61
+
62
+ Returns:
63
+ An available port number.
64
+ """
65
+ import socket
66
+
67
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
68
+ s.bind((host, 0))
69
+ return s.getsockname()[1]
70
+
71
+
72
+ def get_server_url(host: str = _DEFAULT_HOST, port: int = _DEFAULT_PORT) -> str:
73
+ """Build the server base URL.
74
+
75
+ Args:
76
+ host: Server host.
77
+ port: Server port.
78
+
79
+ Returns:
80
+ Base URL string.
81
+ """
82
+ return f"http://{host}:{port}"
83
+
84
+
85
+ def generate_langgraph_json(
86
+ output_dir: str | Path,
87
+ *,
88
+ graph_ref: str = "./server_graph.py:graph",
89
+ env_file: str | None = None,
90
+ checkpointer_path: str | None = None,
91
+ ) -> Path:
92
+ """Generate a `langgraph.json` config file for `langgraph dev`.
93
+
94
+ Args:
95
+ output_dir: Directory to write the config file.
96
+ graph_ref: Python module:variable reference to the graph.
97
+ env_file: Optional path to an env file.
98
+ checkpointer_path: Import path to an async context manager that yields a
99
+ `BaseCheckpointSaver`. When set, the server persists checkpoint data
100
+ to disk instead of in-memory.
101
+
102
+ Returns:
103
+ Path to the generated config file.
104
+ """
105
+ config: dict[str, Any] = {
106
+ "dependencies": ["."],
107
+ "graphs": {
108
+ "agent": graph_ref,
109
+ },
110
+ }
111
+ if env_file:
112
+ config["env"] = env_file
113
+ if checkpointer_path:
114
+ config["checkpointer"] = {"path": checkpointer_path}
115
+
116
+ output_path = Path(output_dir) / "langgraph.json"
117
+ output_path.write_text(json.dumps(config, indent=2))
118
+ return output_path
119
+
120
+
121
+ # ---------------------------------------------------------------------------
122
+ # Scoped env-var management
123
+ # ---------------------------------------------------------------------------
124
+
125
+
126
+ @contextlib.contextmanager
127
+ def _scoped_env_overrides(
128
+ overrides: dict[str, str],
129
+ ) -> Iterator[None]:
130
+ """Apply env-var overrides, rolling back only on exception.
131
+
132
+ Separates the concern of temporary `os.environ` mutations from subprocess
133
+ management, making both independently testable.
134
+
135
+ On normal exit the overrides are left in place (the caller "keeps"
136
+ them). On exception the previous values are restored so the next attempt
137
+ starts from a known-good state.
138
+
139
+ Args:
140
+ overrides: Key/value pairs to set in `os.environ`.
141
+
142
+ Yields:
143
+ Control to the caller.
144
+ """
145
+ prev: dict[str, str | None] = {}
146
+ for key, val in overrides.items():
147
+ prev[key] = os.environ.get(key)
148
+ os.environ[key] = val
149
+ try:
150
+ yield
151
+ except Exception:
152
+ for key, old_val in prev.items():
153
+ if old_val is None:
154
+ os.environ.pop(key, None)
155
+ else:
156
+ os.environ[key] = old_val
157
+ raise
158
+
159
+
160
+ # ---------------------------------------------------------------------------
161
+ # Health checking
162
+ # ---------------------------------------------------------------------------
163
+
164
+
165
+ async def wait_for_server_healthy(
166
+ url: str,
167
+ *,
168
+ timeout: float = _HEALTH_TIMEOUT, # noqa: ASYNC109
169
+ process: subprocess.Popen | None = None,
170
+ read_log: Callable[[], str] | None = None,
171
+ local: bool = False,
172
+ ) -> None:
173
+ """Poll a LangGraph server health endpoint until it responds.
174
+
175
+ Args:
176
+ url: Server base URL (health endpoint is `{url}/ok`).
177
+ timeout: Max seconds to wait.
178
+ process: Optional subprocess handle; if the process exits early
179
+ we fail fast instead of waiting for the timeout.
180
+ read_log: Optional callable returning log file contents (for
181
+ error messages on early exit).
182
+ local: Use a shorter poll interval for local servers.
183
+
184
+ Raises:
185
+ RuntimeError: If the server doesn't become healthy in time.
186
+ """
187
+ import httpx
188
+
189
+ poll_interval = (
190
+ _HEALTH_POLL_INTERVAL_LOCAL if local else _HEALTH_POLL_INTERVAL_REMOTE
191
+ )
192
+ health_url = f"{url}/ok"
193
+ deadline = time.monotonic() + timeout
194
+ last_status: int | None = None
195
+ last_exc: Exception | None = None
196
+
197
+ async with httpx.AsyncClient() as client:
198
+ while time.monotonic() < deadline:
199
+ if process and process.poll() is not None:
200
+ output = read_log() if read_log else ""
201
+ msg = f"Server process exited with code {process.returncode}"
202
+ if output:
203
+ msg += f"\n{output[-3000:]}"
204
+ raise RuntimeError(msg)
205
+
206
+ try:
207
+ resp = await client.get(health_url, timeout=2)
208
+ if resp.status_code == 200: # noqa: PLR2004
209
+ logger.info("Server is healthy at %s", url)
210
+ return
211
+ last_status = resp.status_code
212
+ logger.debug("Health check returned status %d", resp.status_code)
213
+ except (httpx.TransportError, OSError) as exc:
214
+ logger.debug("Health check attempt failed: %s", exc)
215
+ last_exc = exc
216
+
217
+ await asyncio.sleep(poll_interval)
218
+
219
+ msg = f"Server did not become healthy within {timeout}s"
220
+ if last_status is not None:
221
+ msg += f" (last status: {last_status})"
222
+ elif last_exc is not None:
223
+ msg += f" (last error: {last_exc})"
224
+ raise RuntimeError(msg)
225
+
226
+
227
+ # ---------------------------------------------------------------------------
228
+ # Server command / env construction
229
+ # ---------------------------------------------------------------------------
230
+
231
+
232
+ def _build_server_cmd(config_path: Path, *, host: str, port: int) -> list[str]:
233
+ """Build the `langgraph dev` command line.
234
+
235
+ Args:
236
+ config_path: Path to the `langgraph.json` config file.
237
+ host: Host to bind.
238
+ port: Port to bind.
239
+
240
+ Returns:
241
+ Command argv list.
242
+ """
243
+ return [
244
+ sys.executable,
245
+ "-m",
246
+ "langgraph_cli",
247
+ "dev",
248
+ "--host",
249
+ host,
250
+ "--port",
251
+ str(port),
252
+ "--no-browser",
253
+ "--no-reload",
254
+ "--config",
255
+ str(config_path),
256
+ ]
257
+
258
+
259
+ def _build_server_env() -> dict[str, str]:
260
+ """Build the environment dict for the server subprocess.
261
+
262
+ Copies `os.environ`, sets required flags, and strips auth-related variables
263
+ that are not needed (and could interfere) for the local dev server.
264
+
265
+ Returns:
266
+ Environment dict for `subprocess.Popen`.
267
+ """
268
+ env = os.environ.copy()
269
+ env["PYTHONDONTWRITEBYTECODE"] = "1"
270
+ env["LANGGRAPH_AUTH_TYPE"] = "noop"
271
+ for key in (
272
+ "LANGGRAPH_AUTH",
273
+ "LANGGRAPH_CLOUD_LICENSE_KEY",
274
+ "LANGSMITH_CONTROL_PLANE_API_KEY",
275
+ "LANGSMITH_TENANT_ID",
276
+ ):
277
+ env.pop(key, None)
278
+ return env
279
+
280
+
281
+ # ---------------------------------------------------------------------------
282
+ # ServerProcess
283
+ # ---------------------------------------------------------------------------
284
+
285
+
286
+ class ServerProcess:
287
+ """Manages a `langgraph dev` server subprocess.
288
+
289
+ Focuses on subprocess lifecycle (start, stop, restart) and health checking.
290
+ Env-var management for restarts (e.g. configuration changes requiring a full
291
+ restart) is handled by `_scoped_env_overrides`, keeping this class focused
292
+ on process management.
293
+ """
294
+
295
+ def __init__(
296
+ self,
297
+ *,
298
+ host: str = _DEFAULT_HOST,
299
+ port: int = _DEFAULT_PORT,
300
+ config_dir: str | Path | None = None,
301
+ owns_config_dir: bool = False,
302
+ ) -> None:
303
+ """Initialize server process manager.
304
+
305
+ Args:
306
+ host: Host to bind the server to.
307
+ port: Initial port to bind the server to.
308
+
309
+ May be reassigned automatically by `start()` if the port is
310
+ already in use.
311
+ config_dir: Directory containing `langgraph.json`.
312
+ owns_config_dir: When `True`, the server will delete `config_dir`
313
+ on `stop()`.
314
+ """
315
+ self.host = host
316
+ self.port = port
317
+ self.config_dir = Path(config_dir) if config_dir else None
318
+ self._owns_config_dir = owns_config_dir
319
+ self._process: subprocess.Popen | None = None
320
+ self._temp_dir: tempfile.TemporaryDirectory | None = None
321
+ self._log_file: tempfile.NamedTemporaryFile | None = None # type: ignore[type-arg]
322
+ self._env_overrides: dict[str, str] = {}
323
+
324
+ @property
325
+ def url(self) -> str:
326
+ """Server base URL."""
327
+ return get_server_url(self.host, self.port)
328
+
329
+ @property
330
+ def running(self) -> bool:
331
+ """Whether the server process is running."""
332
+ return self._process is not None and self._process.poll() is None
333
+
334
+ def _read_log_file(self) -> str:
335
+ """Read the server log file contents.
336
+
337
+ Returns:
338
+ Log file contents as a string (may be empty).
339
+ """
340
+ if self._log_file is None:
341
+ return ""
342
+ try:
343
+ self._log_file.flush()
344
+ return Path(self._log_file.name).read_text(
345
+ encoding="utf-8", errors="replace"
346
+ )
347
+ except OSError:
348
+ logger.warning(
349
+ "Failed to read server log file %s",
350
+ self._log_file.name,
351
+ exc_info=True,
352
+ )
353
+ return ""
354
+
355
+ async def start(
356
+ self,
357
+ *,
358
+ timeout: float = _HEALTH_TIMEOUT, # noqa: ASYNC109
359
+ ) -> None:
360
+ """Start the `langgraph dev` server and wait for it to be healthy.
361
+
362
+ Args:
363
+ timeout: Max seconds to wait for the server to become healthy.
364
+
365
+ Raises:
366
+ RuntimeError: If the server fails to start or become healthy.
367
+ """
368
+ if self.running:
369
+ return
370
+
371
+ work_dir = self.config_dir
372
+ if work_dir is None:
373
+ self._temp_dir = tempfile.TemporaryDirectory(prefix="docagent_server_")
374
+ work_dir = Path(self._temp_dir.name)
375
+
376
+ config_path = work_dir / "langgraph.json"
377
+ if not config_path.exists():
378
+ msg = (
379
+ f"langgraph.json not found in {work_dir}. "
380
+ "Call generate_langgraph_json() first."
381
+ )
382
+ raise RuntimeError(msg)
383
+
384
+ if _port_in_use(self.host, self.port):
385
+ self.port = _find_free_port(self.host)
386
+ logger.info("Default port in use, using port %d instead", self.port)
387
+
388
+ cmd = _build_server_cmd(config_path, host=self.host, port=self.port)
389
+ env = _build_server_env()
390
+
391
+ logger.info("Starting langgraph dev server: %s", " ".join(cmd))
392
+ self._log_file = tempfile.NamedTemporaryFile( # noqa: SIM115
393
+ prefix="docagent_server_log_",
394
+ suffix=".txt",
395
+ delete=False,
396
+ mode="w",
397
+ encoding="utf-8",
398
+ )
399
+ self._process = subprocess.Popen( # noqa: S603, ASYNC220
400
+ cmd,
401
+ cwd=str(work_dir),
402
+ env=env,
403
+ stdout=self._log_file,
404
+ stderr=subprocess.STDOUT,
405
+ )
406
+
407
+ try:
408
+ await wait_for_server_healthy(
409
+ self.url,
410
+ timeout=timeout,
411
+ process=self._process,
412
+ read_log=self._read_log_file,
413
+ local=True,
414
+ )
415
+ except Exception:
416
+ self.stop()
417
+ raise
418
+
419
+ def _stop_process(self) -> None:
420
+ """Stop only the server subprocess and its log file.
421
+
422
+ Unlike `stop()`, this does NOT clean up the config directory or temp
423
+ directory, so the server can be restarted with the same config.
424
+ """
425
+ if self._process is None:
426
+ return
427
+
428
+ if self._process.poll() is None:
429
+ logger.info("Stopping langgraph dev server (pid=%d)", self._process.pid)
430
+ try:
431
+ self._process.send_signal(signal.SIGTERM)
432
+ self._process.wait(timeout=_SHUTDOWN_TIMEOUT)
433
+ except subprocess.TimeoutExpired:
434
+ logger.warning("Server did not stop gracefully, killing")
435
+ self._process.kill()
436
+ try:
437
+ self._process.wait(timeout=2)
438
+ except subprocess.TimeoutExpired:
439
+ logger.warning(
440
+ "Server process pid=%d did not exit after SIGKILL",
441
+ self._process.pid,
442
+ )
443
+ except OSError:
444
+ logger.warning("Error stopping server", exc_info=True)
445
+
446
+ self._process = None
447
+
448
+ if self._log_file is not None:
449
+ try:
450
+ self._log_file.close()
451
+ Path(self._log_file.name).unlink()
452
+ except OSError:
453
+ logger.debug("Failed to clean up log file", exc_info=True)
454
+ self._log_file = None
455
+
456
+ def stop(self) -> None:
457
+ """Stop the server process and clean up all resources."""
458
+ self._stop_process()
459
+
460
+ if self._temp_dir is not None:
461
+ try:
462
+ self._temp_dir.cleanup()
463
+ except OSError:
464
+ logger.debug("Failed to clean up temp dir", exc_info=True)
465
+ self._temp_dir = None
466
+
467
+ if self._owns_config_dir and self.config_dir is not None:
468
+ import shutil
469
+
470
+ try:
471
+ shutil.rmtree(self.config_dir)
472
+ except OSError:
473
+ logger.debug(
474
+ "Failed to clean up config dir %s", self.config_dir, exc_info=True
475
+ )
476
+ self._owns_config_dir = False
477
+
478
+ def update_env(self, **overrides: str) -> None:
479
+ """Stage env var overrides to apply on the next `restart()`.
480
+
481
+ These are applied to `os.environ` immediately before the subprocess
482
+ starts, keeping mutation scoped to the restart call.
483
+
484
+ Args:
485
+ **overrides: Key/value env var pairs
486
+ (e.g., `DEEPAGENTS_CLI_SERVER_MODEL="anthropic:claude-sonnet-4-6"`).
487
+ """
488
+ self._env_overrides.update(overrides)
489
+
490
+ async def restart(self, *, timeout: float = _HEALTH_TIMEOUT) -> None: # noqa: ASYNC109
491
+ """Restart the server process, reusing the existing config directory.
492
+
493
+ Stops the subprocess, then starts a new one. Any env overrides staged
494
+ via `update_env()` are applied within a `_scoped_env_overrides` context
495
+ manager so that failures automatically roll back the environment to the
496
+ last known-good state.
497
+
498
+ Args:
499
+ timeout: Max seconds to wait for the server to become healthy.
500
+ """
501
+ logger.info("Restarting langgraph dev server")
502
+ self._stop_process()
503
+
504
+ with _scoped_env_overrides(self._env_overrides):
505
+ await self.start(timeout=timeout)
506
+
507
+ self._env_overrides.clear()
508
+
509
+ async def __aenter__(self) -> Self:
510
+ """Async context manager entry.
511
+
512
+ Returns:
513
+ The server process instance.
514
+ """
515
+ await self.start()
516
+ return self
517
+
518
+ async def __aexit__(self, *args: object) -> None:
519
+ """Async context manager exit."""
520
+ self.stop()
@@ -0,0 +1,196 @@
1
+ """Server-side graph entry point for `langgraph dev`.
2
+
3
+ This module is referenced by the generated `langgraph.json` and exposes the CLI
4
+ agent graph as a module-level variable that the LangGraph server can load
5
+ and serve.
6
+
7
+ The graph is created at module import time via `make_graph()`, which reads
8
+ configuration from `ServerConfig.from_env()` — the same dataclass the CLI uses
9
+ to *write* the configuration via `ServerConfig.to_env()`. This shared schema
10
+ ensures the two sides stay in sync.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import atexit
16
+ import logging
17
+ import sys
18
+ import traceback
19
+ from typing import Any
20
+
21
+ from docagent_cli._server_config import ServerConfig
22
+ from docagent_cli.project_utils import ProjectContext, get_server_project_context
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+ # Module-level sandbox state kept alive for the server process lifetime.
27
+ _sandbox_cm: Any = None
28
+ _sandbox_backend: Any = None
29
+
30
+
31
+ def _build_tools(
32
+ config: ServerConfig,
33
+ project_context: ProjectContext | None,
34
+ ) -> tuple[list[Any], list[Any] | None]:
35
+ """Assemble the tool list based on server config.
36
+
37
+ Loads built-in tools (conditionally including web search when Tavily is
38
+ available) and MCP tools when enabled.
39
+
40
+ MCP discovery runs synchronously via `asyncio.run` because this function is
41
+ called during module-level graph construction (before the server's async
42
+ event loop is available).
43
+
44
+ Args:
45
+ config: Deserialized server configuration.
46
+ project_context: Resolved project context for MCP discovery.
47
+
48
+ Returns:
49
+ Tuple of `(tools, mcp_server_info)`.
50
+
51
+ Raises:
52
+ FileNotFoundError: If the MCP config file is not found.
53
+ RuntimeError: If MCP tool loading fails.
54
+ """
55
+ from docagent_cli.config import settings
56
+ from docagent_cli.tools import fetch_url, http_request, web_search
57
+
58
+ tools: list[Any] = [fetch_url, http_request]
59
+ if settings.has_tavily:
60
+ tools.append(web_search)
61
+
62
+ mcp_server_info: list[Any] | None = None
63
+ if not config.no_mcp:
64
+ import asyncio
65
+
66
+ from docagent_cli.mcp_tools import resolve_and_load_mcp_tools
67
+
68
+ try:
69
+ mcp_tools, _, mcp_server_info = asyncio.run(
70
+ resolve_and_load_mcp_tools(
71
+ explicit_config_path=config.mcp_config_path,
72
+ no_mcp=config.no_mcp,
73
+ trust_project_mcp=config.trust_project_mcp,
74
+ project_context=project_context,
75
+ )
76
+ )
77
+ except FileNotFoundError:
78
+ logger.exception("MCP config file not found: %s", config.mcp_config_path)
79
+ raise
80
+ except RuntimeError:
81
+ logger.exception(
82
+ "Failed to load MCP tools (config: %s)", config.mcp_config_path
83
+ )
84
+ raise
85
+
86
+ tools.extend(mcp_tools)
87
+ if mcp_tools:
88
+ logger.info("Loaded %d MCP tool(s)", len(mcp_tools))
89
+
90
+ return tools, mcp_server_info
91
+
92
+
93
+ def make_graph() -> Any: # noqa: ANN401
94
+ """Create the CLI agent graph from environment-based configuration.
95
+
96
+ Reads `DEEPAGENTS_CLI_SERVER_*` env vars via `ServerConfig.from_env()`
97
+ (the inverse of `ServerConfig.to_env()` used by the CLI process), resolves a
98
+ model, assembles tools, and compiles the agent graph.
99
+
100
+ Returns:
101
+ Compiled LangGraph agent graph.
102
+ """
103
+ config = ServerConfig.from_env()
104
+ project_context = get_server_project_context()
105
+
106
+ from docagent_cli.agent import create_cli_agent, load_async_subagents
107
+ from docagent_cli.config import create_model, settings
108
+
109
+ if project_context is not None:
110
+ settings.reload_from_environment(start_path=project_context.user_cwd)
111
+
112
+ result = create_model(config.model, extra_kwargs=config.model_params)
113
+ result.apply_to_settings()
114
+
115
+ tools, mcp_server_info = _build_tools(config, project_context)
116
+
117
+ # Create sandbox backend if a sandbox provider is configured.
118
+ # The context manager is held open at module level and cleaned up via
119
+ # atexit so the sandbox lives for the entire server process lifetime.
120
+ global _sandbox_cm, _sandbox_backend # noqa: PLW0603
121
+ sandbox_backend = None
122
+ if config.sandbox_type:
123
+ from docagent_cli.integrations.sandbox_factory import create_sandbox
124
+
125
+ try:
126
+ _sandbox_cm = create_sandbox(
127
+ config.sandbox_type,
128
+ sandbox_id=config.sandbox_id,
129
+ setup_script_path=config.sandbox_setup,
130
+ )
131
+ _sandbox_backend = _sandbox_cm.__enter__() # noqa: PLC2801 # Context manager kept open for server process lifetime
132
+ sandbox_backend = _sandbox_backend
133
+
134
+ def _cleanup_sandbox() -> None:
135
+ if _sandbox_cm is not None:
136
+ _sandbox_cm.__exit__(None, None, None)
137
+
138
+ atexit.register(_cleanup_sandbox)
139
+ except ImportError:
140
+ logger.exception(
141
+ "Sandbox provider '%s' is not installed", config.sandbox_type
142
+ )
143
+ print( # noqa: T201 # stderr fallback — logger may not reach parent process
144
+ f"Sandbox provider '{config.sandbox_type}' is not installed",
145
+ file=sys.stderr,
146
+ )
147
+ sys.exit(1)
148
+ except NotImplementedError:
149
+ logger.exception("Sandbox type '%s' is not supported", config.sandbox_type)
150
+ print( # noqa: T201 # stderr fallback — logger may not reach parent process
151
+ f"Sandbox type '{config.sandbox_type}' is not supported",
152
+ file=sys.stderr,
153
+ )
154
+ sys.exit(1)
155
+ except Exception as exc:
156
+ logger.exception("Sandbox creation failed for '%s'", config.sandbox_type)
157
+ print( # noqa: T201 # stderr fallback — logger may not reach parent process
158
+ f"Sandbox creation failed for '{config.sandbox_type}': {exc}",
159
+ file=sys.stderr,
160
+ )
161
+ sys.exit(1)
162
+
163
+ async_subagents = load_async_subagents() or None
164
+
165
+ agent, _ = create_cli_agent(
166
+ model=result.model,
167
+ assistant_id=config.assistant_id,
168
+ tools=tools,
169
+ sandbox=sandbox_backend,
170
+ sandbox_type=config.sandbox_type,
171
+ system_prompt=config.system_prompt,
172
+ interactive=config.interactive,
173
+ auto_approve=config.auto_approve,
174
+ interrupt_shell_only=config.interrupt_shell_only,
175
+ shell_allow_list=config.shell_allow_list,
176
+ enable_ask_user=config.enable_ask_user,
177
+ enable_memory=config.enable_memory,
178
+ enable_skills=config.enable_skills,
179
+ enable_shell=config.enable_shell,
180
+ mcp_server_info=mcp_server_info,
181
+ cwd=project_context.user_cwd if project_context is not None else config.cwd,
182
+ project_context=project_context,
183
+ async_subagents=async_subagents,
184
+ )
185
+ return agent
186
+
187
+
188
+ try:
189
+ graph = make_graph()
190
+ except Exception as exc:
191
+ logger.critical("Failed to initialize server graph", exc_info=True)
192
+ print( # noqa: T201 # stderr fallback — logger may not reach parent process
193
+ f"Failed to initialize server graph: {exc}\n{traceback.format_exc()}",
194
+ file=sys.stderr,
195
+ )
196
+ sys.exit(1)