devrev-Python-SDK 2.12.2__tar.gz → 2.14.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/docs.yml +1 -1
  2. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/integration-tests.yml +1 -1
  3. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/release.yml +1 -1
  4. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/PKG-INFO +1 -1
  5. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/changelog.md +52 -0
  6. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/pyproject.toml +1 -1
  7. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/client.py +13 -0
  8. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/__init__.py +35 -0
  9. devrev_python_sdk-2.14.0/src/devrev/models/rev_orgs.py +159 -0
  10. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/__init__.py +4 -0
  11. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/articles.py +112 -13
  12. devrev_python_sdk-2.14.0/src/devrev/services/rev_orgs.py +271 -0
  13. devrev_python_sdk-2.14.0/src/devrev/utils/__init__.py +34 -0
  14. devrev_python_sdk-2.14.0/src/devrev/utils/content_converter.py +831 -0
  15. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/server.py +1 -0
  16. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/accounts.py +6 -0
  17. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/articles.py +16 -2
  18. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/conversations.py +4 -0
  19. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/engagements.py +4 -0
  20. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/groups.py +3 -0
  21. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/incidents.py +4 -0
  22. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/links.py +3 -0
  23. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/parts.py +4 -0
  24. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/question_answers.py +4 -0
  25. devrev_python_sdk-2.14.0/src/devrev_mcp/tools/rev_orgs.py +158 -0
  26. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/slas.py +4 -0
  27. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/tags.py +4 -0
  28. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/timeline.py +4 -0
  29. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/users.py +3 -0
  30. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/works.py +4 -0
  31. devrev_python_sdk-2.14.0/src/devrev_mcp/utils/don_id.py +177 -0
  32. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_content_converter.py +287 -1
  33. devrev_python_sdk-2.14.0/tests/unit/test_don_id_validation.py +165 -0
  34. devrev_python_sdk-2.14.0/tests/unit/test_rev_orgs.py +351 -0
  35. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/uv.lock +52 -52
  36. devrev_python_sdk-2.12.2/src/devrev/utils/__init__.py +0 -16
  37. devrev_python_sdk-2.12.2/src/devrev/utils/content_converter.py +0 -358
  38. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/bug-fixer.md +0 -0
  39. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/builder.md +0 -0
  40. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/documentation.md +0 -0
  41. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/foreman.md +0 -0
  42. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/pr-review-boss.md +0 -0
  43. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/release-manager.md +0 -0
  44. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/simplifier.md +0 -0
  45. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/agents/tester.md +0 -0
  46. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/commands/foreman-work.md +0 -0
  47. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/commands/release-prepare.md +0 -0
  48. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/commands/review-start.md +0 -0
  49. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/commands/simplify-code.md +0 -0
  50. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/code-quality.md +0 -0
  51. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/data-modeling.md +0 -0
  52. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/devrev-sdk.md +0 -0
  53. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/git-workflow.md +0 -0
  54. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/pull-requests.md +0 -0
  55. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/python-development.md +0 -0
  56. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/security.md +0 -0
  57. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.augment/rules/testing.md +0 -0
  58. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.dockerignore +0 -0
  59. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.env.sample +0 -0
  60. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/ISSUE_TEMPLATE/article-artifact-simplification.md +0 -0
  61. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  62. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  63. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  64. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  65. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/dependabot.yml +0 -0
  66. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/pull_request_template.md +0 -0
  67. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/api-check.yml +0 -0
  68. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/ci.yml +0 -0
  69. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/claude-code-review.yml +0 -0
  70. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/claude.yml +0 -0
  71. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/deploy.yml +0 -0
  72. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.github/workflows/sync-openapi.yml +0 -0
  73. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.gitignore +0 -0
  74. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/.pre-commit-config.yaml +0 -0
  75. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/CLAUDE.md +0 -0
  76. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/CODE_OF_CONDUCT.md +0 -0
  77. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/CONTRIBUTING.md +0 -0
  78. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/DEPRECATIONS.md +0 -0
  79. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/Dockerfile +0 -0
  80. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/KNOWN_ISSUES.md +0 -0
  81. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/OPENAPI_SPEC_DISCREPANCIES.md +0 -0
  82. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/README.md +0 -0
  83. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/SECURITY.md +0 -0
  84. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/augment-mcp-config-remote.json +0 -0
  85. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/augment-mcp-config.json +0 -0
  86. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/augment-settings.json +0 -0
  87. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/benchmarks/README.md +0 -0
  88. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/benchmarks/bench_http_client.py +0 -0
  89. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/benchmarks/bench_models.py +0 -0
  90. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/benchmarks/bench_pagination.py +0 -0
  91. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/benchmarks/conftest.py +0 -0
  92. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/context7.json +0 -0
  93. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/README.md +0 -0
  94. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/audit-logging-setup.sh +0 -0
  95. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/cloudbuild.yaml +0 -0
  96. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/monitoring/README.md +0 -0
  97. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/monitoring/alert-policies.yaml +0 -0
  98. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/monitoring/dashboard.json +0 -0
  99. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/monitoring/validate-config.sh +0 -0
  100. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/deploy/service.yaml +0 -0
  101. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docker-compose.yml +0 -0
  102. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/brands.md +0 -0
  103. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/engagements.md +0 -0
  104. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/incidents.md +0 -0
  105. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/index.md +0 -0
  106. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/question-answers.md +0 -0
  107. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/recommendations.md +0 -0
  108. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/search.md +0 -0
  109. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta/uoms.md +0 -0
  110. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/beta-api-differences.md +0 -0
  111. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/client.md +0 -0
  112. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/config.md +0 -0
  113. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/exceptions.md +0 -0
  114. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/index.md +0 -0
  115. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/models/accounts.md +0 -0
  116. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/models/base.md +0 -0
  117. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/models/index.md +0 -0
  118. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/models/users.md +0 -0
  119. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/models/works.md +0 -0
  120. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/accounts.md +0 -0
  121. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/articles.md +0 -0
  122. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/code-changes.md +0 -0
  123. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/conversations.md +0 -0
  124. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/dev-users.md +0 -0
  125. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/groups.md +0 -0
  126. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/index.md +0 -0
  127. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/links.md +0 -0
  128. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/parts.md +0 -0
  129. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/rev-users.md +0 -0
  130. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/slas.md +0 -0
  131. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/tags.md +0 -0
  132. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/timeline-entries.md +0 -0
  133. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/webhooks.md +0 -0
  134. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/api/services/works.md +0 -0
  135. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/examples/advanced.md +0 -0
  136. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/examples/basic.md +0 -0
  137. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/examples/beta-features.md +0 -0
  138. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/examples/index.md +0 -0
  139. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/examples/integrations.md +0 -0
  140. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/getting-started/authentication.md +0 -0
  141. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/getting-started/index.md +0 -0
  142. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/getting-started/installation.md +0 -0
  143. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/getting-started/quickstart.md +0 -0
  144. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/beta-api.md +0 -0
  145. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/compatibility.md +0 -0
  146. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/configuration.md +0 -0
  147. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/error-handling.md +0 -0
  148. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/github-actions-setup.md +0 -0
  149. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/index.md +0 -0
  150. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/logging.md +0 -0
  151. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/pagination.md +0 -0
  152. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/sync-vs-async.md +0 -0
  153. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/testing.md +0 -0
  154. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/version-support.md +0 -0
  155. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/guides/write-integration-testing-strategy.md +0 -0
  156. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/hooks/copy_llms.py +0 -0
  157. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/index.md +0 -0
  158. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/mcp/deployment.md +0 -0
  159. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/mcp/index.md +0 -0
  160. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/mcp/quickstart.md +0 -0
  161. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/mcp/tools-reference.md +0 -0
  162. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/docs/stylesheets/extra.css +0 -0
  163. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/README.md +0 -0
  164. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/README.md +0 -0
  165. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/async_example.py +0 -0
  166. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/create_work.py +0 -0
  167. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/error_handling.py +0 -0
  168. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/list_accounts.py +0 -0
  169. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/pagination.py +0 -0
  170. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/basic/search_users.py +0 -0
  171. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/cloud_functions/README.md +0 -0
  172. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/cloud_functions/main.py +0 -0
  173. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/cloud_functions/requirements.txt +0 -0
  174. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/fastapi/README.md +0 -0
  175. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/fastapi/main.py +0 -0
  176. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/fastapi/requirements.txt +0 -0
  177. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/flask/README.md +0 -0
  178. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/flask/app.py +0 -0
  179. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/examples/integrations/flask/requirements.txt +0 -0
  180. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/llms-ctx-full.txt +0 -0
  181. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/llms-ctx.txt +0 -0
  182. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/llms-mcp.txt +0 -0
  183. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/llms.txt +0 -0
  184. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/mkdocs.yml +0 -0
  185. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/openapi-beta.yaml +0 -0
  186. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/openapi-public.yaml +0 -0
  187. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/openapi-spec-corrections.yaml +0 -0
  188. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/scripts/build_ai_docs.py +0 -0
  189. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/scripts/debug_articles.py +0 -0
  190. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/scripts/setup-github-secrets.sh +0 -0
  191. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/__init__.py +0 -0
  192. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/config.py +0 -0
  193. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/exceptions.py +0 -0
  194. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/accounts.py +0 -0
  195. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/articles.py +0 -0
  196. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/artifacts.py +0 -0
  197. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/base.py +0 -0
  198. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/brands.py +0 -0
  199. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/code_changes.py +0 -0
  200. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/conversations.py +0 -0
  201. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/dev_users.py +0 -0
  202. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/engagements.py +0 -0
  203. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/groups.py +0 -0
  204. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/incidents.py +0 -0
  205. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/links.py +0 -0
  206. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/notifications.py +0 -0
  207. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/parts.py +0 -0
  208. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/preferences.py +0 -0
  209. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/question_answers.py +0 -0
  210. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/recommendations.py +0 -0
  211. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/rev_users.py +0 -0
  212. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/search.py +0 -0
  213. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/slas.py +0 -0
  214. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/sync.py +0 -0
  215. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/tags.py +0 -0
  216. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/tasks.py +0 -0
  217. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/timeline_entries.py +0 -0
  218. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/timeline_events.py +0 -0
  219. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/track_events.py +0 -0
  220. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/uoms.py +0 -0
  221. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/webhooks.py +0 -0
  222. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/widgets.py +0 -0
  223. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/models/works.py +0 -0
  224. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/py.typed +0 -0
  225. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/accounts.py +0 -0
  226. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/artifacts.py +0 -0
  227. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/base.py +0 -0
  228. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/brands.py +0 -0
  229. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/code_changes.py +0 -0
  230. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/conversations.py +0 -0
  231. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/dev_users.py +0 -0
  232. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/engagements.py +0 -0
  233. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/groups.py +0 -0
  234. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/incidents.py +0 -0
  235. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/links.py +0 -0
  236. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/notifications.py +0 -0
  237. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/parts.py +0 -0
  238. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/preferences.py +0 -0
  239. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/question_answers.py +0 -0
  240. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/recommendations.py +0 -0
  241. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/rev_users.py +0 -0
  242. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/search.py +0 -0
  243. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/slas.py +0 -0
  244. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/tags.py +0 -0
  245. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/timeline_entries.py +0 -0
  246. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/track_events.py +0 -0
  247. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/uoms.py +0 -0
  248. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/webhooks.py +0 -0
  249. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/services/works.py +0 -0
  250. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/utils/deprecation.py +0 -0
  251. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/utils/http.py +0 -0
  252. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/utils/logging.py +0 -0
  253. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev/utils/pagination.py +0 -0
  254. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/__init__.py +0 -0
  255. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/__main__.py +0 -0
  256. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/config.py +0 -0
  257. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/middleware/__init__.py +0 -0
  258. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/middleware/audit.py +0 -0
  259. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/middleware/auth.py +0 -0
  260. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/middleware/health.py +0 -0
  261. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/middleware/rate_limit.py +0 -0
  262. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/prompts/__init__.py +0 -0
  263. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/prompts/escalation.py +0 -0
  264. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/prompts/investigate.py +0 -0
  265. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/prompts/response.py +0 -0
  266. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/prompts/summarize.py +0 -0
  267. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/prompts/triage.py +0 -0
  268. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/__init__.py +0 -0
  269. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/account.py +0 -0
  270. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/article.py +0 -0
  271. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/conversation.py +0 -0
  272. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/part.py +0 -0
  273. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/server_info.py +0 -0
  274. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/ticket.py +0 -0
  275. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/resources/user.py +0 -0
  276. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/__init__.py +0 -0
  277. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/recommendations.py +0 -0
  278. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/search.py +0 -0
  279. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/tools/server_info.py +0 -0
  280. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/utils/__init__.py +0 -0
  281. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/utils/errors.py +0 -0
  282. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/utils/formatting.py +0 -0
  283. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/src/devrev_mcp/utils/pagination.py +0 -0
  284. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/__init__.py +0 -0
  285. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/conftest.py +0 -0
  286. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/__init__.py +0 -0
  287. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/conftest.py +0 -0
  288. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_accounts_e2e.py +0 -0
  289. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_all_readonly_endpoints.py +0 -0
  290. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_articles_lifecycle.py +0 -0
  291. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_backwards_compatibility.py +0 -0
  292. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_contacts_e2e.py +0 -0
  293. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_core_services_phase1.py +0 -0
  294. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_extended_services_phase2.py +0 -0
  295. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_get_endpoints.py +0 -0
  296. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_issues_e2e.py +0 -0
  297. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_kb_articles_e2e.py +0 -0
  298. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_mcp_articles.py +0 -0
  299. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_ping.py +0 -0
  300. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_question_answers_e2e.py +0 -0
  301. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_readonly_endpoints.py +0 -0
  302. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_specialized_services_phase3.py +0 -0
  303. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_tickets_e2e.py +0 -0
  304. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/test_write_operations.py +0 -0
  305. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/utils/__init__.py +0 -0
  306. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/utils/cleanup.py +0 -0
  307. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/utils/constants.py +0 -0
  308. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/integration/utils/data_manager.py +0 -0
  309. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/performance/__init__.py +0 -0
  310. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/performance/test_articles_performance.py +0 -0
  311. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/__init__.py +0 -0
  312. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/__init__.py +0 -0
  313. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/conftest.py +0 -0
  314. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_audit.py +0 -0
  315. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_config.py +0 -0
  316. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_phase4_transport.py +0 -0
  317. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_prompts.py +0 -0
  318. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_resources.py +0 -0
  319. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_server_info.py +0 -0
  320. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_accounts.py +0 -0
  321. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_articles.py +0 -0
  322. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_conversations.py +0 -0
  323. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_engagements.py +0 -0
  324. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_groups.py +0 -0
  325. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_incidents.py +0 -0
  326. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_links.py +0 -0
  327. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_parts.py +0 -0
  328. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_question_answers.py +0 -0
  329. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_recommendations.py +0 -0
  330. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_search.py +0 -0
  331. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_slas.py +0 -0
  332. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_tags.py +0 -0
  333. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_timeline.py +0 -0
  334. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_users.py +0 -0
  335. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_tools_works.py +0 -0
  336. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/mcp/test_utils.py +0 -0
  337. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/models/__init__.py +0 -0
  338. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/models/test_user_state_regression.py +0 -0
  339. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/__init__.py +0 -0
  340. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/conftest.py +0 -0
  341. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_articles.py +0 -0
  342. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_async_services.py +0 -0
  343. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_brands.py +0 -0
  344. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_code_changes.py +0 -0
  345. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_conversations.py +0 -0
  346. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_engagements.py +0 -0
  347. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_groups.py +0 -0
  348. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_incidents.py +0 -0
  349. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_links.py +0 -0
  350. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_notifications.py +0 -0
  351. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_parts.py +0 -0
  352. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_preferences.py +0 -0
  353. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_question_answers.py +0 -0
  354. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_recommendations.py +0 -0
  355. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_search.py +0 -0
  356. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_slas.py +0 -0
  357. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_tags.py +0 -0
  358. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_timeline_entries.py +0 -0
  359. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_track_events.py +0 -0
  360. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_uoms.py +0 -0
  361. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_webhooks.py +0 -0
  362. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/services/test_works.py +0 -0
  363. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_articles_unified.py +0 -0
  364. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_artifacts.py +0 -0
  365. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_backward_compatibility.py +0 -0
  366. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_base_service.py +0 -0
  367. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_client.py +0 -0
  368. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_config.py +0 -0
  369. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_deprecation.py +0 -0
  370. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_error_handling.py +0 -0
  371. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_exceptions.py +0 -0
  372. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_http.py +0 -0
  373. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_logging.py +0 -0
  374. {devrev_python_sdk-2.12.2 → devrev_python_sdk-2.14.0}/tests/unit/test_pagination.py +0 -0
@@ -59,5 +59,5 @@ jobs:
59
59
  steps:
60
60
  - name: Deploy to GitHub Pages
61
61
  id: deployment
62
- uses: actions/deploy-pages@v4
62
+ uses: actions/deploy-pages@v5
63
63
 
@@ -102,7 +102,7 @@ jobs:
102
102
 
103
103
  - name: Create issue on failure
104
104
  if: failure()
105
- uses: actions/github-script@v8
105
+ uses: actions/github-script@v9
106
106
  with:
107
107
  script: |
108
108
  github.rest.issues.create({
@@ -155,7 +155,7 @@ jobs:
155
155
  EOF
156
156
 
157
157
  - name: Create Release
158
- uses: softprops/action-gh-release@v2
158
+ uses: softprops/action-gh-release@v3
159
159
  with:
160
160
  name: v${{ steps.version.outputs.version }}
161
161
  body_path: release_notes.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devrev-Python-SDK
3
- Version: 2.12.2
3
+ Version: 2.14.0
4
4
  Summary: A modern, type-safe Python SDK for the DevRev API
5
5
  Project-URL: Homepage, https://github.com/mgmonteleone/py-dev-rev
6
6
  Project-URL: Documentation, https://github.com/mgmonteleone/py-dev-rev
@@ -7,6 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.14.0] - 2026-04-14
11
+
12
+ ### Added
13
+
14
+ - **DON ID type validation with helpful error messages** (CUSS-396, PR #207)
15
+ - New `validate_don_id()` utility in `src/devrev_mcp/utils/don_id.py`
16
+ - `parse_don_type()` extracts object type segment from DON IDs
17
+ - `DON_TYPE_MAP` maps DON type segments to human-friendly names
18
+ - `TOOL_SUGGESTIONS` maps DON types to the correct MCP tool for actionable suggestions
19
+ - Integrated into all 14 MCP tool files (`_get`, `_update`, `_delete` operations)
20
+ - Example: *"This is a rev_org ID, try using devrev_rev_orgs_get instead"*
21
+ - Raises `RuntimeError` caught by existing MCP error handlers
22
+
23
+ - **Rev Orgs (revenue organizations) service** (CUSS-397, PR #207)
24
+ - Pydantic v2 models: `RevOrg`, `RevOrgSummary`, request/response models (`src/devrev/models/rev_orgs.py`)
25
+ - Sync `RevOrgsService` and async `AsyncRevOrgsService` (`src/devrev/services/rev_orgs.py`)
26
+ - MCP tools: `devrev_rev_orgs_list`, `devrev_rev_orgs_get`, `devrev_rev_orgs_create`, `devrev_rev_orgs_update`, `devrev_rev_orgs_delete`
27
+ - Destructive tools gated behind `enable_destructive_tools` config flag
28
+ - Registered in `DevRevClient` and `AsyncDevRevClient` as `rev_orgs` property
29
+
30
+ ### Security
31
+
32
+ - **Bump cryptography from 46.0.5 to 46.0.7** (PR #206) — Fixes CVE-2026-39892 (buffer overflow with non-contiguous buffers) and CVE-2026-34073 (name constraint bypass with wildcard DNS SAN)
33
+
34
+ ### Maintenance
35
+
36
+ - **CI dependency updates** — Folded 3 Dependabot PRs into PR #207:
37
+ - PR #208: Bump `softprops/action-gh-release` from v2 to v3 (Node 24)
38
+ - PR #209: Bump `actions/deploy-pages` from v4 to v5 (Node 24)
39
+ - PR #210: Bump `actions/github-script` from v8 to v9 (Node 24)
40
+
41
+ ### Testing
42
+
43
+ - 22 new unit tests for DON ID validation (`tests/unit/test_don_id_validation.py`)
44
+ - 19 new unit tests for Rev Orgs models and services (`tests/unit/test_rev_orgs.py`)
45
+ - All 1,091 tests passing
46
+
47
+ ## [2.13.0] - 2026-04-08
48
+
49
+ ### Added
50
+
51
+ - **Article content format detection and bidirectional conversion** (#160, PR #205)
52
+ - `detect_content_format()` — detects `devrev/rt`, `text/markdown`, `text/html`, or `text/plain`
53
+ - `devrev_rt_to_markdown()` — converts ProseMirror JSON to Markdown
54
+ - `devrev_rt_to_html()` — converts ProseMirror JSON to HTML with XSS-safe escaping
55
+ - `OutputFormat` type alias (`Literal["text/markdown", "text/html", "devrev/rt"]`)
56
+ - Four format constants: `CONTENT_FORMAT_DEVREV_RT`, `CONTENT_FORMAT_MARKDOWN`, `CONTENT_FORMAT_HTML`, `CONTENT_FORMAT_PLAIN`
57
+ - `get_with_content()` (sync + async) now accepts optional `output_format` parameter for automatic content conversion
58
+ - MCP tool `devrev_articles_get` accepts `output_format` when `include_content=True`
59
+ - `_convert_content()` validates output format and raises `ValueError` for invalid values
60
+ - All HTML output uses `html.escape()` for text and attributes; links include `rel="noopener noreferrer"`
61
+
10
62
  ## [2.12.2] - 2026-04-08
11
63
 
12
64
  ### Maintenance
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "devrev-Python-SDK"
7
- version = "2.12.2"
7
+ version = "2.14.0"
8
8
  description = "A modern, type-safe Python SDK for the DevRev API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -38,6 +38,7 @@ from devrev.services.recommendations import (
38
38
  AsyncRecommendationsService,
39
39
  RecommendationsService,
40
40
  )
41
+ from devrev.services.rev_orgs import AsyncRevOrgsService, RevOrgsService
41
42
  from devrev.services.rev_users import AsyncRevUsersService, RevUsersService
42
43
  from devrev.services.search import AsyncSearchService, SearchService
43
44
  from devrev.services.slas import AsyncSlasService, SlasService
@@ -160,6 +161,7 @@ class DevRevClient:
160
161
  self._groups = GroupsService(self._http)
161
162
  self._links = LinksService(self._http)
162
163
  self._parts = PartsService(self._http)
164
+ self._rev_orgs = RevOrgsService(self._http)
163
165
  self._rev_users = RevUsersService(self._http)
164
166
  self._slas = SlasService(self._http)
165
167
  self._tags = TagsService(self._http)
@@ -242,6 +244,11 @@ class DevRevClient:
242
244
  """Access the Parts service."""
243
245
  return self._parts
244
246
 
247
+ @property
248
+ def rev_orgs(self) -> RevOrgsService:
249
+ """Access the Rev Orgs service for managing revenue organizations."""
250
+ return self._rev_orgs
251
+
245
252
  @property
246
253
  def rev_users(self) -> RevUsersService:
247
254
  """Access the Rev Users service."""
@@ -482,6 +489,7 @@ class AsyncDevRevClient:
482
489
  self._groups = AsyncGroupsService(self._http)
483
490
  self._links = AsyncLinksService(self._http)
484
491
  self._parts = AsyncPartsService(self._http)
492
+ self._rev_orgs = AsyncRevOrgsService(self._http)
485
493
  self._rev_users = AsyncRevUsersService(self._http)
486
494
  self._slas = AsyncSlasService(self._http)
487
495
  self._tags = AsyncTagsService(self._http)
@@ -564,6 +572,11 @@ class AsyncDevRevClient:
564
572
  """Access the Parts service."""
565
573
  return self._parts
566
574
 
575
+ @property
576
+ def rev_orgs(self) -> AsyncRevOrgsService:
577
+ """Access the Rev Orgs service for managing revenue organizations."""
578
+ return self._rev_orgs
579
+
567
580
  @property
568
581
  def rev_users(self) -> AsyncRevUsersService:
569
582
  """Access the Rev Users service."""
@@ -260,6 +260,20 @@ from devrev.models.recommendations import (
260
260
  MessageRole,
261
261
  TokenUsage,
262
262
  )
263
+ from devrev.models.rev_orgs import (
264
+ RevOrg,
265
+ RevOrgsCreateRequest,
266
+ RevOrgsCreateResponse,
267
+ RevOrgsDeleteRequest,
268
+ RevOrgsDeleteResponse,
269
+ RevOrgsGetRequest,
270
+ RevOrgsGetResponse,
271
+ RevOrgsListRequest,
272
+ RevOrgsListResponse,
273
+ RevOrgSummary,
274
+ RevOrgsUpdateRequest,
275
+ RevOrgsUpdateResponse,
276
+ )
263
277
  from devrev.models.rev_users import (
264
278
  RevUser,
265
279
  RevUsersAssociationsAddRequest,
@@ -694,6 +708,19 @@ __all__ = [
694
708
  "ChatCompletionResponse",
695
709
  "GetReplyRequest",
696
710
  "GetReplyResponse",
711
+ # Rev Orgs
712
+ "RevOrg",
713
+ "RevOrgSummary",
714
+ "RevOrgsCreateRequest",
715
+ "RevOrgsCreateResponse",
716
+ "RevOrgsGetRequest",
717
+ "RevOrgsGetResponse",
718
+ "RevOrgsListRequest",
719
+ "RevOrgsListResponse",
720
+ "RevOrgsUpdateRequest",
721
+ "RevOrgsUpdateResponse",
722
+ "RevOrgsDeleteRequest",
723
+ "RevOrgsDeleteResponse",
697
724
  # Rev Users
698
725
  "RevUser",
699
726
  "RevUserSummary",
@@ -889,6 +916,12 @@ from devrev.models.accounts import (
889
916
  AccountsListResponse as _AccountsListResponse,
890
917
  )
891
918
  from devrev.models.base import TagWithValue as _TagWithValue # noqa: F811
919
+ from devrev.models.rev_orgs import ( # noqa: F811
920
+ RevOrg as _RevOrg,
921
+ )
922
+ from devrev.models.rev_orgs import (
923
+ RevOrgsListResponse as _RevOrgsListResponse,
924
+ )
892
925
  from devrev.models.works import ( # noqa: F811
893
926
  Work as _Work,
894
927
  )
@@ -904,6 +937,8 @@ _TagWithValue.model_rebuild()
904
937
  _Account.model_rebuild()
905
938
  _AccountsListResponse.model_rebuild()
906
939
  _AccountsExportResponse.model_rebuild()
940
+ _RevOrg.model_rebuild()
941
+ _RevOrgsListResponse.model_rebuild()
907
942
  _Work.model_rebuild()
908
943
  _WorksListResponse.model_rebuild()
909
944
  _WorksExportResponse.model_rebuild()
@@ -0,0 +1,159 @@
1
+ """Rev Org models for DevRev SDK.
2
+
3
+ This module contains Pydantic models for Rev Org (Revenue Organization)-related
4
+ API operations. Rev Orgs represent customer organizations in DevRev.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from datetime import datetime
10
+ from typing import Any
11
+
12
+ from pydantic import Field
13
+
14
+ from devrev.models.accounts import AccountSummary
15
+ from devrev.models.base import (
16
+ CustomSchemaSpec,
17
+ DateFilter,
18
+ DevRevBaseModel,
19
+ DevRevResponseModel,
20
+ PaginatedResponse,
21
+ TagWithValue,
22
+ UserSummary,
23
+ )
24
+
25
+
26
+ class RevOrg(DevRevResponseModel):
27
+ """DevRev Rev Org (Revenue Organization) model.
28
+
29
+ Represents a customer organization in DevRev, typically associated
30
+ with an Account.
31
+ """
32
+
33
+ id: str = Field(..., description="Rev org ID")
34
+ display_id: str | None = Field(default=None, description="Human-readable display ID")
35
+ display_name: str | None = Field(default=None, description="Rev org display name")
36
+ description: str | None = Field(default=None, description="Rev org description")
37
+ account: AccountSummary | None = Field(default=None, description="Associated account")
38
+ created_date: datetime | None = Field(default=None, description="Creation timestamp")
39
+ modified_date: datetime | None = Field(default=None, description="Last modification timestamp")
40
+ created_by: UserSummary | None = Field(
41
+ default=None, description="User who created this rev org"
42
+ )
43
+ modified_by: UserSummary | None = Field(
44
+ default=None, description="User who last modified this rev org"
45
+ )
46
+ domain: str | None = Field(default=None, description="Domain")
47
+ external_ref: str | None = Field(default=None, description="External reference identifier")
48
+ external_refs: list[str] | None = Field(default=None, description="External references")
49
+ custom_fields: dict[str, Any] | None = Field(default=None, description="Custom fields")
50
+ sub_type: str | None = Field(default=None, description="Rev org subtype")
51
+ tags: list[TagWithValue] | None = Field(default=None, description="Tags")
52
+ tier: str | None = Field(default=None, description="Rev org tier")
53
+ artifacts: list[str] | None = Field(default=None, description="Associated artifact IDs")
54
+
55
+
56
+ class RevOrgSummary(DevRevResponseModel):
57
+ """Summary of a Rev Org for list/reference operations."""
58
+
59
+ id: str = Field(..., description="Rev org ID")
60
+ display_id: str | None = Field(default=None, description="Human-readable display ID")
61
+ display_name: str | None = Field(default=None, description="Rev org display name")
62
+
63
+
64
+ # Request Models
65
+
66
+
67
+ class RevOrgsGetRequest(DevRevBaseModel):
68
+ """Request to get a rev org."""
69
+
70
+ id: str | None = Field(default=None, description="Rev org ID")
71
+ account: str | None = Field(
72
+ default=None, description="Account ID to get the default rev org for"
73
+ )
74
+
75
+
76
+ class RevOrgsListRequest(DevRevBaseModel):
77
+ """Request to list rev orgs."""
78
+
79
+ account: list[str] | None = Field(default=None, description="Filter by account IDs")
80
+ created_by: list[str] | None = Field(default=None, description="Filter by creator user IDs")
81
+ created_date: DateFilter | None = Field(default=None, description="Filter by creation date")
82
+ cursor: str | None = Field(default=None, description="Pagination cursor")
83
+ display_name: list[str] | None = Field(default=None, description="Filter by display names")
84
+ domains: list[str] | None = Field(default=None, description="Filter by domains")
85
+ external_refs: list[str] | None = Field(default=None, description="Filter by external refs")
86
+ limit: int | None = Field(default=None, ge=1, le=100, description="Max results to return")
87
+ modified_date: DateFilter | None = Field(
88
+ default=None, description="Filter by modification date"
89
+ )
90
+ owned_by: list[str] | None = Field(default=None, description="Filter by owner user IDs")
91
+ tags: list[str] | None = Field(default=None, description="Filter by tag IDs")
92
+
93
+
94
+ class RevOrgsCreateRequest(DevRevBaseModel):
95
+ """Request to create a rev org."""
96
+
97
+ display_name: str = Field(..., description="Rev org display name", min_length=1, max_length=256)
98
+ account: str = Field(..., description="Parent account ID")
99
+ description: str | None = Field(default=None, description="Rev org description")
100
+ external_ref: str | None = Field(default=None, description="External reference identifier")
101
+ tier: str | None = Field(default=None, description="Rev org tier")
102
+ custom_fields: dict[str, Any] | None = Field(default=None, description="Custom fields")
103
+ custom_schema_spec: CustomSchemaSpec | None = Field(
104
+ default=None, description="Custom schema spec"
105
+ )
106
+
107
+
108
+ class RevOrgsUpdateRequest(DevRevBaseModel):
109
+ """Request to update a rev org."""
110
+
111
+ id: str = Field(..., description="Rev org ID")
112
+ display_name: str | None = Field(default=None, description="New display name")
113
+ description: str | None = Field(default=None, description="New description")
114
+ tier: str | None = Field(default=None, description="New tier")
115
+ custom_fields: dict[str, Any] | None = Field(
116
+ default=None, description="Custom fields to update"
117
+ )
118
+ artifacts: dict[str, Any] | None = Field(
119
+ default=None, description="Artifact set/remove operations"
120
+ )
121
+
122
+
123
+ class RevOrgsDeleteRequest(DevRevBaseModel):
124
+ """Request to delete a rev org."""
125
+
126
+ id: str = Field(..., description="Rev org ID to delete")
127
+
128
+
129
+ # Response Models
130
+
131
+
132
+ class RevOrgsGetResponse(DevRevResponseModel):
133
+ """Response from getting a rev org."""
134
+
135
+ rev_org: RevOrg = Field(..., description="Retrieved rev org")
136
+
137
+
138
+ class RevOrgsListResponse(PaginatedResponse):
139
+ """Response from listing rev orgs."""
140
+
141
+ rev_orgs: list[RevOrg] = Field(..., description="List of rev orgs")
142
+
143
+
144
+ class RevOrgsCreateResponse(DevRevResponseModel):
145
+ """Response from creating a rev org."""
146
+
147
+ rev_org: RevOrg = Field(..., description="Created rev org")
148
+
149
+
150
+ class RevOrgsUpdateResponse(DevRevResponseModel):
151
+ """Response from updating a rev org."""
152
+
153
+ rev_org: RevOrg = Field(..., description="Updated rev org")
154
+
155
+
156
+ class RevOrgsDeleteResponse(DevRevResponseModel):
157
+ """Response from deleting a rev org."""
158
+
159
+ pass # Empty response body
@@ -34,6 +34,7 @@ from devrev.services.recommendations import (
34
34
  AsyncRecommendationsService,
35
35
  RecommendationsService,
36
36
  )
37
+ from devrev.services.rev_orgs import AsyncRevOrgsService, RevOrgsService
37
38
  from devrev.services.rev_users import AsyncRevUsersService, RevUsersService
38
39
  from devrev.services.search import AsyncSearchService, SearchService
39
40
  from devrev.services.slas import AsyncSlasService, SlasService
@@ -99,6 +100,9 @@ __all__ = [
99
100
  # Recommendations
100
101
  "RecommendationsService",
101
102
  "AsyncRecommendationsService",
103
+ # Rev Orgs
104
+ "RevOrgsService",
105
+ "AsyncRevOrgsService",
102
106
  # Rev Users
103
107
  "RevUsersService",
104
108
  "AsyncRevUsersService",
@@ -35,15 +35,16 @@ from devrev.models.artifacts import (
35
35
  )
36
36
  from devrev.models.base import SetTagWithValue
37
37
  from devrev.services.base import AsyncBaseService, BaseService
38
- from devrev.utils.content_converter import html_to_devrev_rt
39
-
40
- # Content format to file extension mapping
41
- _CONTENT_FORMAT_EXTENSIONS: dict[str, str] = {
42
- "text/html": ".html",
43
- "text/markdown": ".md",
44
- "text/plain": ".txt",
45
- "devrev/rt": "", # DevRev rich text uses no extension (file name "Article")
46
- }
38
+ from devrev.utils.content_converter import (
39
+ CONTENT_FORMAT_DEVREV_RT,
40
+ CONTENT_FORMAT_HTML,
41
+ CONTENT_FORMAT_MARKDOWN,
42
+ OutputFormat,
43
+ detect_content_format,
44
+ devrev_rt_to_html,
45
+ devrev_rt_to_markdown,
46
+ html_to_devrev_rt,
47
+ )
47
48
 
48
49
 
49
50
  def _extract_content_artifact_id(resource: dict[str, object]) -> str | None:
@@ -101,6 +102,69 @@ def _extract_content_format(resource: dict[str, object]) -> str:
101
102
  return "text/plain"
102
103
 
103
104
 
105
+ def _convert_content(
106
+ content: str,
107
+ source_format: str,
108
+ target_format: str,
109
+ ) -> tuple[str, str]:
110
+ """Convert article content between formats.
111
+
112
+ Args:
113
+ content: The raw content string.
114
+ source_format: The MIME type of *content* (e.g. ``"devrev/rt"``).
115
+ target_format: The desired output MIME type.
116
+
117
+ Returns:
118
+ A ``(converted_content, actual_format)`` tuple. If no conversion
119
+ is necessary (source == target, or conversion is not possible)
120
+ the original content and format are returned.
121
+ Raises:
122
+ ValueError: If *target_format* is not a recognised format.
123
+ """
124
+ _VALID_FORMATS = {
125
+ CONTENT_FORMAT_MARKDOWN,
126
+ CONTENT_FORMAT_HTML,
127
+ CONTENT_FORMAT_DEVREV_RT,
128
+ }
129
+ if target_format not in _VALID_FORMATS:
130
+ raise ValueError(
131
+ f"Invalid output_format {target_format!r}. Accepted values: {sorted(_VALID_FORMATS)}"
132
+ )
133
+
134
+ if source_format == target_format:
135
+ return content, source_format
136
+
137
+ # Auto-detect source format when unknown / generic
138
+ if source_format in ("text/plain", ""):
139
+ source_format = detect_content_format(content)
140
+
141
+ if target_format == CONTENT_FORMAT_MARKDOWN:
142
+ if source_format == CONTENT_FORMAT_DEVREV_RT:
143
+ return devrev_rt_to_markdown(content), CONTENT_FORMAT_MARKDOWN
144
+ # HTML or unknown → convert to devrev/rt first, then to markdown
145
+ if source_format == CONTENT_FORMAT_HTML:
146
+ rt = html_to_devrev_rt(content)
147
+ return devrev_rt_to_markdown(rt), CONTENT_FORMAT_MARKDOWN
148
+ # Already markdown or plain text
149
+ return content, source_format
150
+
151
+ if target_format == CONTENT_FORMAT_HTML:
152
+ if source_format == CONTENT_FORMAT_DEVREV_RT:
153
+ return devrev_rt_to_html(content), CONTENT_FORMAT_HTML
154
+ if source_format == CONTENT_FORMAT_MARKDOWN:
155
+ rt = html_to_devrev_rt(content)
156
+ return devrev_rt_to_html(rt), CONTENT_FORMAT_HTML
157
+ return content, source_format
158
+
159
+ if target_format == CONTENT_FORMAT_DEVREV_RT:
160
+ if source_format != CONTENT_FORMAT_DEVREV_RT:
161
+ return html_to_devrev_rt(content), CONTENT_FORMAT_DEVREV_RT
162
+ return content, source_format
163
+
164
+ # Unknown target format – return unchanged
165
+ return content, source_format
166
+
167
+
104
168
  class ArticlesService(BaseService):
105
169
  """Service for managing DevRev Articles."""
106
170
 
@@ -313,17 +377,27 @@ class ArticlesService(BaseService):
313
377
  # Re-raise the original error
314
378
  raise DevRevError(f"Failed to create article with content: {e}") from e
315
379
 
316
- def get_with_content(self, id: str) -> ArticleWithContent:
380
+ def get_with_content(
381
+ self,
382
+ id: str,
383
+ *,
384
+ output_format: OutputFormat | None = None,
385
+ ) -> ArticleWithContent:
317
386
  """Get an article with its content loaded.
318
387
 
319
388
  This is a high-level method that:
320
389
  1. Fetches article metadata
321
390
  2. Locates the content artifact
322
391
  3. Downloads artifact content
323
- 4. Returns combined model
392
+ 4. Optionally converts to the requested output format
393
+ 5. Returns combined model
324
394
 
325
395
  Args:
326
396
  id: Article ID
397
+ output_format: Desired output format for the content. Accepted
398
+ values: ``"text/markdown"``, ``"text/html"``, ``"devrev/rt"``.
399
+ When ``None`` (the default) the raw stored content is returned
400
+ as-is.
327
401
 
328
402
  Returns:
329
403
  ArticleWithContent with metadata and content
@@ -336,6 +410,9 @@ class ArticlesService(BaseService):
336
410
  >>> article_with_content = client.articles.get_with_content("ART-123")
337
411
  >>> print(article_with_content.article.title)
338
412
  >>> print(article_with_content.content)
413
+ >>> # Get content as Markdown
414
+ >>> md = client.articles.get_with_content("ART-123", output_format="text/markdown")
415
+ >>> print(md.content)
339
416
  """
340
417
  if not self._parent_client:
341
418
  raise DevRevError(
@@ -364,12 +441,18 @@ class ArticlesService(BaseService):
364
441
  # Get content format from resource metadata (more reliable than artifact.get)
365
442
  content_format = _extract_content_format(article.resource)
366
443
 
444
+ # Step 4: Convert to requested output format if specified
445
+ if output_format is not None:
446
+ content, content_format = _convert_content(content, content_format, output_format)
447
+
367
448
  return ArticleWithContent(
368
449
  article=article,
369
450
  content=content,
370
451
  content_format=content_format,
371
452
  content_version=None,
372
453
  )
454
+ except DevRevError:
455
+ raise
373
456
  except Exception as e:
374
457
  raise DevRevError(f"Failed to download content for article {id}: {e}") from e
375
458
 
@@ -772,17 +855,27 @@ class AsyncArticlesService(AsyncBaseService):
772
855
  # Re-raise the original error
773
856
  raise DevRevError(f"Failed to create article with content: {e}") from e
774
857
 
775
- async def get_with_content(self, id: str) -> ArticleWithContent:
858
+ async def get_with_content(
859
+ self,
860
+ id: str,
861
+ *,
862
+ output_format: OutputFormat | None = None,
863
+ ) -> ArticleWithContent:
776
864
  """Get an article with its content loaded (async).
777
865
 
778
866
  This is a high-level method that:
779
867
  1. Fetches article metadata
780
868
  2. Locates the content artifact
781
869
  3. Downloads artifact content
782
- 4. Returns combined model
870
+ 4. Optionally converts to the requested output format
871
+ 5. Returns combined model
783
872
 
784
873
  Args:
785
874
  id: Article ID
875
+ output_format: Desired output format for the content. Accepted
876
+ values: ``"text/markdown"``, ``"text/html"``, ``"devrev/rt"``.
877
+ When ``None`` (the default) the raw stored content is returned
878
+ as-is.
786
879
 
787
880
  Returns:
788
881
  ArticleWithContent with metadata and content
@@ -818,12 +911,18 @@ class AsyncArticlesService(AsyncBaseService):
818
911
  # Get content format from resource metadata (more reliable than artifact.get)
819
912
  content_format = _extract_content_format(article.resource)
820
913
 
914
+ # Step 4: Convert to requested output format if specified
915
+ if output_format is not None:
916
+ content, content_format = _convert_content(content, content_format, output_format)
917
+
821
918
  return ArticleWithContent(
822
919
  article=article,
823
920
  content=content,
824
921
  content_format=content_format,
825
922
  content_version=None,
826
923
  )
924
+ except DevRevError:
925
+ raise
827
926
  except Exception as e:
828
927
  raise DevRevError(f"Failed to download content for article {id}: {e}") from e
829
928