uipath-langchain 0.0.138__tar.gz → 0.0.140__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.

Potentially problematic release.


This version of uipath-langchain might be problematic. Click here for more details.

Files changed (283) hide show
  1. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/integration_tests.yml +20 -27
  2. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.gitignore +2 -2
  3. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/PKG-INFO +1 -1
  4. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/pyproject.toml +1 -1
  5. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_runtime/_context.py +0 -5
  6. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_runtime/_conversation.py +8 -0
  7. uipath_langchain-0.0.140/src/uipath_langchain/_cli/_runtime/_graph_resolver.py +143 -0
  8. uipath_langchain-0.0.140/src/uipath_langchain/_cli/_runtime/_runtime.py +255 -0
  9. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/cli_dev.py +8 -2
  10. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/cli_eval.py +7 -5
  11. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/cli_run.py +4 -5
  12. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_utils/_request_mixin.py +31 -14
  13. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/chat/models.py +137 -3
  14. uipath_langchain-0.0.138/testcases/common/print_output.sh → uipath_langchain-0.0.140/testcases/common/validate_output.sh +14 -2
  15. uipath_langchain-0.0.140/testcases/company-research-agent/run.sh +21 -0
  16. uipath_langchain-0.0.140/testcases/company-research-agent/src/assert.py +46 -0
  17. uipath_langchain-0.0.140/testcases/init-flow/input.json +3 -0
  18. uipath_langchain-0.0.140/testcases/init-flow/pyproject.toml +13 -0
  19. uipath_langchain-0.0.140/testcases/init-flow/run.sh +32 -0
  20. uipath_langchain-0.0.140/testcases/init-flow/src/assert.py +46 -0
  21. uipath_langchain-0.0.140/testcases/simple-local-mcp/run.sh +21 -0
  22. uipath_langchain-0.0.140/testcases/simple-local-mcp/src/assert.py +46 -0
  23. uipath_langchain-0.0.140/testcases/ticket-classification/run.sh +25 -0
  24. uipath_langchain-0.0.140/testcases/ticket-classification/src/assert.py +51 -0
  25. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/uv.lock +1 -1
  26. uipath_langchain-0.0.138/src/uipath_langchain/_cli/_runtime/_runtime.py +0 -379
  27. uipath_langchain-0.0.138/src/uipath_langchain/builder/agent_config.py +0 -191
  28. uipath_langchain-0.0.138/testcases/Dockerfile +0 -16
  29. uipath_langchain-0.0.138/testcases/README.md +0 -22
  30. uipath_langchain-0.0.138/testcases/company-research-agent/.env.example +0 -5
  31. uipath_langchain-0.0.138/testcases/company-research-agent/agent.mermaid +0 -23
  32. uipath_langchain-0.0.138/testcases/company-research-agent/run.sh +0 -28
  33. uipath_langchain-0.0.138/testcases/company-research-agent/src/assert.py +0 -61
  34. uipath_langchain-0.0.138/testcases/company-research-agent/uipath.json +0 -37
  35. uipath_langchain-0.0.138/testcases/simple-local-mcp/.env.example +0 -5
  36. uipath_langchain-0.0.138/testcases/simple-local-mcp/README.md +0 -95
  37. uipath_langchain-0.0.138/testcases/simple-local-mcp/agent.mermaid +0 -17
  38. uipath_langchain-0.0.138/testcases/simple-local-mcp/run.sh +0 -28
  39. uipath_langchain-0.0.138/testcases/simple-local-mcp/src/assert.py +0 -61
  40. uipath_langchain-0.0.138/testcases/simple-local-mcp/uipath.json +0 -145
  41. uipath_langchain-0.0.138/testcases/ticket-classification/.env.example +0 -7
  42. uipath_langchain-0.0.138/testcases/ticket-classification/README.md +0 -22
  43. uipath_langchain-0.0.138/testcases/ticket-classification/agent.mermaid +0 -21
  44. uipath_langchain-0.0.138/testcases/ticket-classification/run.sh +0 -34
  45. uipath_langchain-0.0.138/testcases/ticket-classification/src/assert.py +0 -71
  46. uipath_langchain-0.0.138/testcases/ticket-classification/uipath.json +0 -50
  47. uipath_langchain-0.0.138/tests/builder/test_config.py +0 -362
  48. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.cursorrules +0 -0
  49. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.editorconfig +0 -0
  50. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.gitattributes +0 -0
  51. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/cd.yml +0 -0
  52. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/ci.yml +0 -0
  53. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/commitlint.yml +0 -0
  54. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/lint-custom-version.yml +0 -0
  55. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/lint.yml +0 -0
  56. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/publish-dev.yml +0 -0
  57. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/publish-docs.yml +0 -0
  58. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/publish-prior-stable-version.yml +0 -0
  59. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/slack.yml +0 -0
  60. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/test-custom-version.yml +0 -0
  61. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.github/workflows/test.yml +0 -0
  62. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.pre-commit-config.yaml +0 -0
  63. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.python-version +0 -0
  64. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.vscode/extensions.json +0 -0
  65. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/.vscode/settings.json +0 -0
  66. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/CONTRIBUTING.md +0 -0
  67. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/LICENSE +0 -0
  68. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/README.md +0 -0
  69. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/chat_models.md +0 -0
  70. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/context_grounding.md +0 -0
  71. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/human_in_the_loop.md +0 -0
  72. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/quick_start.md +16 -16
  73. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/quick_start_images/cloud_env_var_dark.png +0 -0
  74. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/quick_start_images/cloud_env_var_light.png +0 -0
  75. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/quick_start_images/invoke_output_dark.png +0 -0
  76. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/quick_start_images/invoke_output_light.png +0 -0
  77. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/click-storage-bucket.png +0 -0
  78. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/create-index-1.png +0 -0
  79. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/create-index-2.png +0 -0
  80. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/create-process.png +0 -0
  81. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/create-quiz-generator.png +0 -0
  82. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/create-storage-bucket-1.png +0 -0
  83. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/create-storage-bucket-2.png +0 -0
  84. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/folder-path.png +0 -0
  85. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/job-info.png +0 -0
  86. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/output.png +0 -0
  87. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/process-page.png +0 -0
  88. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/researcher-1.png +0 -0
  89. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/researcher-2.png +0 -0
  90. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/run-process-1.png +0 -0
  91. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/run-process-2.png +0 -0
  92. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/RAG/storage-bucket-content.png +0 -0
  93. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/multi-agent-distributed/coder-agent-package-overview.png +0 -0
  94. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/multi-agent-distributed/coder-agent-process-configuration.png +0 -0
  95. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/multi-agent-distributed/planner-agent-package-overview.png +0 -0
  96. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/multi-agent-distributed/planner-agent-process-configuration.png +0 -0
  97. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/multi-agent-distributed/researcher-agent-package-overview.png +0 -0
  98. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/multi-agent-distributed/researcher-agent-process-configuration.png +0 -0
  99. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/activate-apps.png +0 -0
  100. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/activate-deployment.png +0 -0
  101. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/copy-folder-path.png +0 -0
  102. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/deploy-solution-package-wizard.png +0 -0
  103. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/deploy-solution-package.png +0 -0
  104. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/monitor-agent.png +0 -0
  105. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/navigate-to-solution-folder.png +0 -0
  106. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/resume-condition.png +0 -0
  107. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/run-agent.png +0 -0
  108. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/solution-destination-folder.png +0 -0
  109. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/start-job.png +0 -0
  110. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/docs/sample_images/ticket-classification/upload-solution-package.png +0 -0
  111. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/README.md +0 -0
  112. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/env.example +0 -0
  113. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/input.example/quiz-generator-debug-input.json +0 -0
  114. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/input.example/researcher-debug-input.json +0 -0
  115. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/langgraph.json +0 -0
  116. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/pyproject.toml +0 -0
  117. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/quiz-generator-RAG-agent.mermaid +0 -0
  118. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/researcher-RAG-agent.mermaid +0 -0
  119. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/src/agents/quiz-generator-RAG-agent.py +0 -0
  120. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/src/agents/researcher-RAG-agent.py +0 -0
  121. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/uipath.json +0 -0
  122. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/RAG-quiz-generator/uv.lock +0 -0
  123. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/README.md +0 -0
  124. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/calculator-agent/graph.py +0 -0
  125. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/calculator-agent/langgraph.json +0 -0
  126. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/calculator-agent/pyproject.toml +0 -0
  127. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/calculator-agent/uipath.json +0 -0
  128. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/calculator-agent/uv.lock +0 -0
  129. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/.env.example +0 -0
  130. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/agent.mermaid +0 -0
  131. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/graph.py +0 -0
  132. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/langgraph.json +0 -0
  133. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/pyproject.toml +0 -0
  134. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/uipath.json +0 -0
  135. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/chat-agent/uv.lock +0 -0
  136. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/.env.example +0 -0
  137. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/agent.mermaid +0 -0
  138. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/graph.py +0 -0
  139. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/langgraph.json +0 -0
  140. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/pyproject.toml +0 -0
  141. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/uipath.json +0 -0
  142. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/company-research-agent/uv.lock +0 -0
  143. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/.env.template +0 -0
  144. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/.python-version +0 -0
  145. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/.vscode/launch.json +0 -0
  146. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/README.md +0 -0
  147. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/agent.mermaid +0 -0
  148. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/input.json +0 -0
  149. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/langgraph.json +0 -0
  150. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/pyproject.toml +0 -0
  151. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/src/email_organizer/__init__.py +0 -0
  152. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/src/email_organizer/main.py +0 -0
  153. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/src/email_organizer/outlook_client.py +0 -0
  154. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/uipath.json +0 -0
  155. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/email-organizer-agent/uv.lock +0 -0
  156. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/database.py +0 -0
  157. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/main.py +0 -0
  158. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/models.py +0 -0
  159. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/pyproject.toml +0 -0
  160. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/schemas.py +0 -0
  161. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/templates/index.html +0 -0
  162. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/hitl-inbox-server/uv.lock +0 -0
  163. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/.env.example +0 -0
  164. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/README.md +0 -0
  165. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/coder.mermaid +0 -0
  166. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/langgraph.json +0 -0
  167. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/planner.mermaid +0 -0
  168. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/pyproject.toml +0 -0
  169. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/researcher.mermaid +0 -0
  170. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/src/multi-agent-distributed/coder.py +0 -0
  171. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/src/multi-agent-distributed/planner.py +0 -0
  172. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/src/multi-agent-distributed/researcher.py +0 -0
  173. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/uipath.json +0 -0
  174. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-planner-researcher-coder-distributed/uv.lock +0 -0
  175. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/.env.example +0 -0
  176. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/README.md +0 -0
  177. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/agent.mermaid +0 -0
  178. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/graph.py +0 -0
  179. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/langgraph.json +0 -0
  180. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/pyproject.toml +0 -0
  181. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/uipath.json +0 -0
  182. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/multi-agent-supervisor-researcher-coder/uv.lock +0 -0
  183. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/retrieval-chain/.env.example +0 -0
  184. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/retrieval-chain/README.md +0 -0
  185. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/retrieval-chain/main.py +0 -0
  186. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/retrieval-chain/pyproject.toml +0 -0
  187. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/retrieval-chain/uipath.json +0 -0
  188. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/retrieval-chain/uv.lock +0 -0
  189. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/.env.example +0 -0
  190. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/README.md +0 -0
  191. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/agent.mermaid +0 -0
  192. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/langgraph.json +0 -0
  193. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/pyproject.toml +0 -0
  194. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/src/simple-local-mcp/graph.py +0 -0
  195. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/src/simple-local-mcp/math_server.py +0 -0
  196. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/src/simple-local-mcp/weather_server.py +0 -0
  197. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/uipath.json +0 -0
  198. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-local-mcp/uv.lock +0 -0
  199. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/.env.example +0 -0
  200. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/README.md +0 -0
  201. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/agent.mermaid +0 -0
  202. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/langgraph.json +0 -0
  203. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/main.py +0 -0
  204. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/pyproject.toml +0 -0
  205. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/uipath.json +0 -0
  206. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/simple-remote-mcp/uv.lock +0 -0
  207. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/.env.example +0 -0
  208. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/README.md +0 -0
  209. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/agent.mermaid +0 -0
  210. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/escalation_app_solution/generic-escalation-app-solution-1.0.0.zip +0 -0
  211. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/langgraph.json +0 -0
  212. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/main.py +0 -0
  213. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/pyproject.toml +0 -0
  214. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/uipath.json +0 -0
  215. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/samples/ticket-classification/uv.lock +0 -0
  216. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/__init__.py +0 -0
  217. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/__init__.py +0 -0
  218. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_runtime/_exception.py +0 -0
  219. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_runtime/_input.py +0 -0
  220. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_runtime/_output.py +0 -0
  221. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_templates/langgraph.json.template +0 -0
  222. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_templates/main.py.template +0 -0
  223. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/_utils/_graph.py +0 -0
  224. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/cli_init.py +0 -0
  225. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_cli/cli_new.py +0 -0
  226. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_tracing/__init__.py +0 -0
  227. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_tracing/_instrument_traceable.py +0 -0
  228. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_tracing/_oteladapter.py +0 -0
  229. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_tracing/_utils.py +0 -0
  230. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_utils/__init__.py +0 -0
  231. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_utils/_settings.py +0 -0
  232. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/_utils/_sleep_policy.py +0 -0
  233. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/chat/__init__.py +0 -0
  234. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/embeddings/__init__.py +0 -0
  235. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/embeddings/embeddings.py +0 -0
  236. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/middlewares.py +0 -0
  237. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/retrievers/__init__.py +0 -0
  238. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/retrievers/context_grounding_retriever.py +0 -0
  239. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/tools/__init__.py +0 -0
  240. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/tools/preconfigured.py +0 -0
  241. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/vectorstores/__init__.py +0 -0
  242. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/src/uipath_langchain/vectorstores/context_grounding_vectorstore.py +0 -0
  243. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/company-research-agent/input.json +0 -0
  244. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/company-research-agent/langgraph.json +0 -0
  245. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/company-research-agent/pyproject.toml +0 -0
  246. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/company-research-agent/src/graph.py +0 -0
  247. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/company-research-agent/uv.lock +0 -0
  248. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/input.json +0 -0
  249. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/langgraph.json +0 -0
  250. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/pyproject.toml +0 -0
  251. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/src/simple-local-mcp/graph.py +0 -0
  252. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/src/simple-local-mcp/math_server.py +0 -0
  253. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/src/simple-local-mcp/weather_server.py +0 -0
  254. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/simple-local-mcp/uv.lock +0 -0
  255. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/ticket-classification/input.json +0 -0
  256. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/ticket-classification/langgraph.json +0 -0
  257. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/ticket-classification/pyproject.toml +0 -0
  258. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/ticket-classification/src/main.py +0 -0
  259. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/testcases/ticket-classification/uv.lock +0 -0
  260. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/__init__.py +0 -0
  261. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/cli/conftest.py +0 -0
  262. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/cli/mocks/langgraph.json +0 -0
  263. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/cli/mocks/simple_agent.py +0 -0
  264. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/cli/mocks/uipath.json +0 -0
  265. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/cli/test_run.py +0 -0
  266. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/__init__.py +0 -0
  267. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/conftest.py +0 -0
  268. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/mocks/action_trigger_hitl.py +0 -0
  269. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/mocks/api_trigger_hitl.py +0 -0
  270. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/mocks/job_trigger_hitl.py +0 -0
  271. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/mocks/langgraph.json +0 -0
  272. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/mocks/uipath-default-escalation.json +0 -0
  273. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/mocks/uipath.json +0 -0
  274. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/test_action_trigger.py +0 -0
  275. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/test_hitl_api_trigger.py +0 -0
  276. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/test_hitl_default_escalation.py +0 -0
  277. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/hitl/test_hitl_job_trigger.py +0 -0
  278. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/test_dummy.py +0 -0
  279. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/tools/__init__.py +0 -0
  280. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/tools/conftest.py +0 -0
  281. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/tools/mocks/agent_definition.json +0 -0
  282. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/tools/test_preconfigured.py +0 -0
  283. {uipath_langchain-0.0.138 → uipath_langchain-0.0.140}/tests/tracing/test_oteladapter.py +0 -0
@@ -19,16 +19,16 @@ jobs:
19
19
  steps:
20
20
  - name: Checkout code
21
21
  uses: actions/checkout@v4
22
-
22
+
23
23
  - name: Discover testcases
24
24
  id: discover
25
25
  run: |
26
26
  # Find all testcase folders (excluding common folders like README, etc.)
27
27
  testcase_dirs=$(find testcases -maxdepth 1 -type d -name "*-*" | sed 's|testcases/||' | sort)
28
-
28
+
29
29
  echo "Found testcase directories:"
30
30
  echo "$testcase_dirs"
31
-
31
+
32
32
  # Convert to JSON array for matrix
33
33
  testcases_json=$(echo "$testcase_dirs" | jq -R -s -c 'split("\n")[:-1]')
34
34
  echo "testcases=$testcases_json" >> $GITHUB_OUTPUT
@@ -36,46 +36,39 @@ jobs:
36
36
  integration-tests:
37
37
  needs: [discover-testcases]
38
38
  runs-on: ubuntu-latest
39
+ container:
40
+ image: ghcr.io/astral-sh/uv:python3.12-bookworm
41
+ env:
42
+ UIPATH_JOB_KEY: "3a03d5cb-fa21-4021-894d-a8e2eda0afe0"
39
43
  strategy:
40
44
  fail-fast: false
41
45
  matrix:
42
46
  testcase: ${{ fromJson(needs.discover-testcases.outputs.testcases) }}
43
- environment: [alpha, cloud]
47
+ environment: [alpha, staging] # temporary disable [cloud]
44
48
  use_azure_chat: [true, false]
45
-
49
+
46
50
  name: "${{ matrix.testcase }} / ${{ matrix.environment }} / ${{ matrix.use_azure_chat && 'UiPathAzureChatOpenAI' || 'UiPathChat' }}"
47
-
51
+
48
52
  steps:
49
53
  - name: Checkout code
50
54
  uses: actions/checkout@v4
51
55
 
52
- - name: Set up Docker Buildx
53
- uses: docker/setup-buildx-action@v3
54
-
55
- - name: Build Docker image
56
- run: |
57
- echo "Building Docker image for ${{ matrix.testcase }} at $(date)"
58
- docker build -f testcases/Dockerfile \
59
- -t uipath-langchain-testbase:latest \
60
- .
61
- echo "Docker image built at $(date)"
56
+ - name: Install Dependencies
57
+ run: uv sync
62
58
 
63
59
  - name: Run testcase
64
60
  env:
65
- CLIENT_ID: ${{ matrix.environment == 'alpha' && secrets.ALPHA_TEST_CLIENT_ID || secrets.CLOUD_TEST_CLIENT_ID }}
66
- CLIENT_SECRET: ${{ matrix.environment == 'alpha' && secrets.ALPHA_TEST_CLIENT_SECRET || secrets.CLOUD_TEST_CLIENT_SECRET }}
67
- BASE_URL: ${{ matrix.environment == 'alpha' && secrets.ALPHA_BASE_URL || secrets.CLOUD_BASE_URL }}
61
+ CLIENT_ID: ${{ matrix.environment == 'alpha' && secrets.ALPHA_TEST_CLIENT_ID || matrix.environment == 'staging' && secrets.STAGING_TEST_CLIENT_ID || matrix.environment == 'cloud' && secrets.CLOUD_TEST_CLIENT_ID }}
62
+ CLIENT_SECRET: ${{ matrix.environment == 'alpha' && secrets.ALPHA_TEST_CLIENT_SECRET || matrix.environment == 'staging' && secrets.STAGING_TEST_CLIENT_SECRET || matrix.environment == 'cloud' && secrets.CLOUD_TEST_CLIENT_SECRET }}
63
+ BASE_URL: ${{ matrix.environment == 'alpha' && secrets.ALPHA_BASE_URL || matrix.environment == 'staging' && secrets.STAGING_BASE_URL || matrix.environment == 'cloud' && secrets.CLOUD_BASE_URL }}
68
64
  USE_AZURE_CHAT: ${{ matrix.use_azure_chat }}
65
+ working-directory: testcases/${{ matrix.testcase }}
69
66
  run: |
70
67
  echo "Running testcase: ${{ matrix.testcase }}"
71
68
  echo "Environment: ${{ matrix.environment }}"
72
69
  echo "LLM: ${{ matrix.use_azure_chat && 'UiPathAzureChatOpenAI' || 'UiPathChat' }}"
73
70
  echo "USE_AZURE_CHAT: ${{ matrix.use_azure_chat }}"
74
-
75
- docker run --rm \
76
- -e CLIENT_ID="$CLIENT_ID" \
77
- -e CLIENT_SECRET="$CLIENT_SECRET" \
78
- -e BASE_URL="$BASE_URL" \
79
- -e USE_AZURE_CHAT="$USE_AZURE_CHAT" \
80
- uipath-langchain-testbase:latest \
81
- bash /app/testcases/${{ matrix.testcase }}/run.sh
71
+
72
+ # Execute the testcase run script directly
73
+ bash run.sh
74
+ bash ../common/validate_output.sh
@@ -165,7 +165,7 @@ cython_debug/
165
165
  # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
166
  # and can be added to the global gitignore or merged into this file. For a more nuclear
167
167
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
- #.idea/
168
+ .idea/
169
169
 
170
170
  # Ruff stuff:
171
171
  .ruff_cache/
@@ -178,4 +178,4 @@ cython_debug/
178
178
  **/.uipath
179
179
  **/**.nupkg
180
180
  **/__uipath/
181
- **/.langgraph_api
181
+ **/.langgraph_api
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath-langchain
3
- Version: 0.0.138
3
+ Version: 0.0.140
4
4
  Summary: UiPath Langchain
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-langchain-python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "uipath-langchain"
3
- version = "0.0.138"
3
+ version = "0.0.140"
4
4
  description = "UiPath Langchain"
5
5
  readme = { file = "README.md", content-type = "text/markdown" }
6
6
  requires-python = ">=3.10"
@@ -1,17 +1,12 @@
1
1
  from typing import Any, Optional, Union
2
2
 
3
3
  from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
4
- from langgraph.graph import StateGraph
5
4
  from uipath._cli._runtime._contracts import UiPathRuntimeContext
6
5
 
7
- from .._utils._graph import LangGraphConfig
8
-
9
6
 
10
7
  class LangGraphRuntimeContext(UiPathRuntimeContext):
11
8
  """Context information passed throughout the runtime execution."""
12
9
 
13
- langgraph_config: Optional[LangGraphConfig] = None
14
- state_graph: Optional[StateGraph[Any, Any]] = None
15
10
  output: Optional[Any] = None
16
11
  state: Optional[Any] = (
17
12
  None # TypedDict issue, the actual type is: Optional[langgraph.types.StateSnapshot]
@@ -173,6 +173,14 @@ def map_message(
173
173
  content_part_sequence=idx,
174
174
  ),
175
175
  )
176
+ elif isinstance(message.content, str) and message.content:
177
+ msg_event.content_part = UiPathConversationContentPartEvent(
178
+ content_part_id=f"content-{message.id}",
179
+ chunk=UiPathConversationContentPartChunkEvent(
180
+ data=message.content,
181
+ content_part_sequence=0,
182
+ ),
183
+ )
176
184
 
177
185
  stop_reason = message.response_metadata.get("stop_reason")
178
186
  if not message.content and stop_reason in ("tool_use", "end_turn"):
@@ -0,0 +1,143 @@
1
+ import asyncio
2
+ from typing import Any, Awaitable, Callable, Optional
3
+
4
+ from langgraph.graph.state import CompiledStateGraph, StateGraph
5
+ from uipath._cli._runtime._contracts import (
6
+ UiPathErrorCategory,
7
+ )
8
+
9
+ from .._utils._graph import GraphConfig, LangGraphConfig
10
+ from ._exception import LangGraphRuntimeError
11
+
12
+
13
+ class LangGraphJsonResolver:
14
+ def __init__(self, entrypoint: Optional[str] = None) -> None:
15
+ self.entrypoint = entrypoint
16
+ self.graph_config: Optional[GraphConfig] = None
17
+ self._lock = asyncio.Lock()
18
+ self._graph_cache: Optional[StateGraph[Any, Any, Any]] = None
19
+ self._resolving: bool = False
20
+
21
+ async def __call__(self) -> StateGraph[Any, Any, Any]:
22
+ # Fast path: if already resolved, return immediately without locking
23
+ if self._graph_cache is not None:
24
+ return self._graph_cache
25
+
26
+ # Slow path: acquire lock and resolve
27
+ async with self._lock:
28
+ # Double-check after acquiring lock (another coroutine may have resolved it)
29
+ if self._graph_cache is not None:
30
+ return self._graph_cache
31
+
32
+ self._graph_cache = await self._resolve(self.entrypoint)
33
+ return self._graph_cache
34
+
35
+ async def _resolve(self, entrypoint: Optional[str]) -> StateGraph[Any, Any, Any]:
36
+ config = LangGraphConfig()
37
+ if not config.exists:
38
+ raise LangGraphRuntimeError(
39
+ "CONFIG_MISSING",
40
+ "Invalid configuration",
41
+ "Failed to load configuration",
42
+ UiPathErrorCategory.DEPLOYMENT,
43
+ )
44
+
45
+ try:
46
+ config.load_config()
47
+ except Exception as e:
48
+ raise LangGraphRuntimeError(
49
+ "CONFIG_INVALID",
50
+ "Invalid configuration",
51
+ f"Failed to load configuration: {str(e)}",
52
+ UiPathErrorCategory.DEPLOYMENT,
53
+ ) from e
54
+
55
+ # Determine entrypoint if not provided
56
+ graphs = config.graphs
57
+ if not entrypoint and len(graphs) == 1:
58
+ entrypoint = graphs[0].name
59
+ elif not entrypoint:
60
+ graph_names = ", ".join(g.name for g in graphs)
61
+ raise LangGraphRuntimeError(
62
+ "ENTRYPOINT_MISSING",
63
+ "Entrypoint required",
64
+ f"Multiple graphs available. Please specify one of: {graph_names}.",
65
+ UiPathErrorCategory.DEPLOYMENT,
66
+ )
67
+
68
+ # Get the specified graph
69
+ self.graph_config = config.get_graph(entrypoint)
70
+ if not self.graph_config:
71
+ raise LangGraphRuntimeError(
72
+ "GRAPH_NOT_FOUND",
73
+ "Graph not found",
74
+ f"Graph '{entrypoint}' not found.",
75
+ UiPathErrorCategory.DEPLOYMENT,
76
+ )
77
+ try:
78
+ loaded_graph = await self.graph_config.load_graph()
79
+ return (
80
+ loaded_graph.builder
81
+ if isinstance(loaded_graph, CompiledStateGraph)
82
+ else loaded_graph
83
+ )
84
+ except ImportError as e:
85
+ raise LangGraphRuntimeError(
86
+ "GRAPH_IMPORT_ERROR",
87
+ "Graph import failed",
88
+ f"Failed to import graph '{entrypoint}': {str(e)}",
89
+ UiPathErrorCategory.USER,
90
+ ) from e
91
+ except TypeError as e:
92
+ raise LangGraphRuntimeError(
93
+ "GRAPH_TYPE_ERROR",
94
+ "Invalid graph type",
95
+ f"Graph '{entrypoint}' is not a valid StateGraph or CompiledStateGraph: {str(e)}",
96
+ UiPathErrorCategory.USER,
97
+ ) from e
98
+ except ValueError as e:
99
+ raise LangGraphRuntimeError(
100
+ "GRAPH_VALUE_ERROR",
101
+ "Invalid graph value",
102
+ f"Invalid value in graph '{entrypoint}': {str(e)}",
103
+ UiPathErrorCategory.USER,
104
+ ) from e
105
+ except Exception as e:
106
+ raise LangGraphRuntimeError(
107
+ "GRAPH_LOAD_ERROR",
108
+ "Failed to load graph",
109
+ f"Unexpected error loading graph '{entrypoint}': {str(e)}",
110
+ UiPathErrorCategory.USER,
111
+ ) from e
112
+
113
+ async def cleanup(self):
114
+ """Clean up resources"""
115
+ async with self._lock:
116
+ if self.graph_config:
117
+ await self.graph_config.cleanup()
118
+ self.graph_config = None
119
+ self._graph_cache = None
120
+
121
+
122
+ AsyncResolver = Callable[[], Awaitable[StateGraph[Any, Any, Any]]]
123
+
124
+
125
+ class LangGraphJsonResolverContext:
126
+ """
127
+ Async context manager wrapping LangGraphJsonResolver.
128
+ Returns a callable that can be passed directly as AsyncResolver to LangGraphRuntime.
129
+ Thread-safe and reuses the same resolved graph across concurrent executions.
130
+ """
131
+
132
+ def __init__(self, entrypoint: Optional[str] = None) -> None:
133
+ self._resolver = LangGraphJsonResolver(entrypoint)
134
+
135
+ async def __aenter__(self) -> AsyncResolver:
136
+ # Return a callable that safely reuses the cached graph
137
+ async def resolver_callable() -> StateGraph[Any, Any, Any]:
138
+ return await self._resolver()
139
+
140
+ return resolver_callable
141
+
142
+ async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
143
+ await self._resolver.cleanup()
@@ -0,0 +1,255 @@
1
+ import logging
2
+ import os
3
+ from typing import Any, List, Optional, Sequence
4
+
5
+ from langchain_core.callbacks.base import BaseCallbackHandler
6
+ from langchain_core.messages import BaseMessage
7
+ from langchain_core.runnables.config import RunnableConfig
8
+ from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
9
+ from langgraph.errors import EmptyInputError, GraphRecursionError, InvalidUpdateError
10
+ from uipath._cli._runtime._contracts import (
11
+ UiPathBaseRuntime,
12
+ UiPathErrorCategory,
13
+ UiPathRuntimeResult,
14
+ )
15
+
16
+ from ._context import LangGraphRuntimeContext
17
+ from ._conversation import map_message
18
+ from ._exception import LangGraphRuntimeError
19
+ from ._graph_resolver import AsyncResolver, LangGraphJsonResolver
20
+ from ._input import LangGraphInputProcessor
21
+ from ._output import LangGraphOutputProcessor
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ class LangGraphRuntime(UiPathBaseRuntime):
27
+ """
28
+ A runtime class implementing the async context manager protocol.
29
+ This allows using the class with 'async with' statements.
30
+ """
31
+
32
+ def __init__(self, context: LangGraphRuntimeContext, graph_resolver: AsyncResolver):
33
+ super().__init__(context)
34
+ self.context: LangGraphRuntimeContext = context
35
+ self.graph_resolver: AsyncResolver = graph_resolver
36
+
37
+ async def execute(self) -> Optional[UiPathRuntimeResult]:
38
+ """
39
+ Execute the graph with the provided input and configuration.
40
+
41
+ Returns:
42
+ Dictionary with execution results
43
+
44
+ Raises:
45
+ LangGraphRuntimeError: If execution fails
46
+ """
47
+
48
+ graph = await self.graph_resolver()
49
+ if not graph:
50
+ return None
51
+
52
+ try:
53
+ async with AsyncSqliteSaver.from_conn_string(
54
+ self.state_file_path
55
+ ) as memory:
56
+ self.context.memory = memory
57
+
58
+ # Compile the graph with the checkpointer
59
+ compiled_graph = graph.compile(checkpointer=self.context.memory)
60
+
61
+ # Process input, handling resume if needed
62
+ input_processor = LangGraphInputProcessor(context=self.context)
63
+
64
+ processed_input = await input_processor.process()
65
+
66
+ callbacks: List[BaseCallbackHandler] = []
67
+
68
+ graph_config: RunnableConfig = {
69
+ "configurable": {
70
+ "thread_id": (
71
+ self.context.execution_id
72
+ or self.context.job_id
73
+ or "default"
74
+ )
75
+ },
76
+ "callbacks": callbacks,
77
+ }
78
+
79
+ recursion_limit = os.environ.get("LANGCHAIN_RECURSION_LIMIT", None)
80
+ max_concurrency = os.environ.get("LANGCHAIN_MAX_CONCURRENCY", None)
81
+
82
+ if recursion_limit is not None:
83
+ graph_config["recursion_limit"] = int(recursion_limit)
84
+ if max_concurrency is not None:
85
+ graph_config["max_concurrency"] = int(max_concurrency)
86
+
87
+ if self.context.chat_handler or self.is_debug_run():
88
+ final_chunk: Optional[dict[Any, Any]] = None
89
+ async for stream_chunk in compiled_graph.astream(
90
+ processed_input,
91
+ graph_config,
92
+ stream_mode=["messages", "updates"],
93
+ subgraphs=True,
94
+ ):
95
+ _, chunk_type, data = stream_chunk
96
+ if chunk_type == "messages":
97
+ if self.context.chat_handler:
98
+ if isinstance(data, tuple):
99
+ message, _ = data
100
+ event = map_message(
101
+ message=message,
102
+ conversation_id=self.context.execution_id,
103
+ exchange_id=self.context.execution_id,
104
+ )
105
+ if event:
106
+ self.context.chat_handler.on_event(event)
107
+ elif chunk_type == "updates":
108
+ if isinstance(data, dict):
109
+ # data is a dict, e.g. {'agent': {'messages': [...]}}
110
+ for agent_data in data.values():
111
+ if isinstance(agent_data, dict):
112
+ messages = agent_data.get("messages", [])
113
+ if isinstance(messages, list):
114
+ for message in messages:
115
+ if isinstance(message, BaseMessage):
116
+ message.pretty_print()
117
+ final_chunk = data
118
+
119
+ self.context.output = self._extract_graph_result(
120
+ final_chunk, compiled_graph.output_channels
121
+ )
122
+ else:
123
+ # Execute the graph normally at runtime or eval
124
+ self.context.output = await compiled_graph.ainvoke(
125
+ processed_input, graph_config
126
+ )
127
+
128
+ # Get the state if available
129
+ try:
130
+ self.context.state = await compiled_graph.aget_state(graph_config)
131
+ except Exception:
132
+ pass
133
+
134
+ output_processor = await LangGraphOutputProcessor.create(self.context)
135
+
136
+ self.context.result = await output_processor.process()
137
+
138
+ return self.context.result
139
+
140
+ except Exception as e:
141
+ if isinstance(e, LangGraphRuntimeError):
142
+ raise
143
+
144
+ detail = f"Error: {str(e)}"
145
+
146
+ if isinstance(e, GraphRecursionError):
147
+ raise LangGraphRuntimeError(
148
+ "GRAPH_RECURSION_ERROR",
149
+ "Graph recursion limit exceeded",
150
+ detail,
151
+ UiPathErrorCategory.USER,
152
+ ) from e
153
+
154
+ if isinstance(e, InvalidUpdateError):
155
+ raise LangGraphRuntimeError(
156
+ "GRAPH_INVALID_UPDATE",
157
+ str(e),
158
+ detail,
159
+ UiPathErrorCategory.USER,
160
+ ) from e
161
+
162
+ if isinstance(e, EmptyInputError):
163
+ raise LangGraphRuntimeError(
164
+ "GRAPH_EMPTY_INPUT",
165
+ "The input data is empty",
166
+ detail,
167
+ UiPathErrorCategory.USER,
168
+ ) from e
169
+
170
+ raise LangGraphRuntimeError(
171
+ "EXECUTION_ERROR",
172
+ "Graph execution failed",
173
+ detail,
174
+ UiPathErrorCategory.USER,
175
+ ) from e
176
+ finally:
177
+ pass
178
+
179
+ async def validate(self) -> None:
180
+ pass
181
+
182
+ async def cleanup(self):
183
+ pass
184
+
185
+ def _extract_graph_result(self, final_chunk, output_channels: str | Sequence[str]):
186
+ """
187
+ Extract the result from a LangGraph output chunk according to the graph's output channels.
188
+
189
+ Args:
190
+ final_chunk: The final chunk from graph.astream()
191
+ graph: The LangGraph instance
192
+
193
+ Returns:
194
+ The extracted result according to the graph's output_channels configuration
195
+ """
196
+ # Unwrap from subgraph tuple format if needed
197
+ if isinstance(final_chunk, tuple) and len(final_chunk) == 2:
198
+ final_chunk = final_chunk[
199
+ 1
200
+ ] # Extract data part from (namespace, data) tuple
201
+
202
+ # If the result isn't a dict or graph doesn't define output channels, return as is
203
+ if not isinstance(final_chunk, dict):
204
+ return final_chunk
205
+
206
+ # Case 1: Single output channel as string
207
+ if isinstance(output_channels, str):
208
+ if output_channels in final_chunk:
209
+ return final_chunk[output_channels]
210
+ else:
211
+ return final_chunk
212
+
213
+ # Case 2: Multiple output channels as sequence
214
+ elif hasattr(output_channels, "__iter__") and not isinstance(
215
+ output_channels, str
216
+ ):
217
+ # Check which channels are present
218
+ available_channels = [ch for ch in output_channels if ch in final_chunk]
219
+
220
+ # if no available channels, output may contain the last_node name as key
221
+ unwrapped_final_chunk = {}
222
+ if not available_channels:
223
+ if len(final_chunk) == 1 and isinstance(
224
+ unwrapped_final_chunk := next(iter(final_chunk.values())), dict
225
+ ):
226
+ available_channels = [
227
+ ch for ch in output_channels if ch in unwrapped_final_chunk
228
+ ]
229
+
230
+ if available_channels:
231
+ # Create a dict with the available channels
232
+ return {
233
+ channel: final_chunk.get(channel, None)
234
+ or unwrapped_final_chunk[channel]
235
+ for channel in available_channels
236
+ }
237
+
238
+ # Fallback for any other case
239
+ return final_chunk
240
+
241
+
242
+ class LangGraphScriptRuntime(LangGraphRuntime):
243
+ """
244
+ Resolves the graph from langgraph.json config file and passes it to the base runtime.
245
+ """
246
+
247
+ def __init__(
248
+ self, context: LangGraphRuntimeContext, entrypoint: Optional[str] = None
249
+ ):
250
+ self.resolver = LangGraphJsonResolver(entrypoint=entrypoint)
251
+ super().__init__(context, self.resolver)
252
+
253
+ async def cleanup(self):
254
+ await super().cleanup()
255
+ await self.resolver.cleanup()
@@ -12,7 +12,7 @@ from uipath._cli.middlewares import MiddlewareResult
12
12
 
13
13
  from .._tracing import _instrument_traceable_attributes
14
14
  from ._runtime._context import LangGraphRuntimeContext
15
- from ._runtime._runtime import LangGraphRuntime
15
+ from ._runtime._runtime import LangGraphScriptRuntime
16
16
 
17
17
  console = ConsoleLogger()
18
18
 
@@ -22,8 +22,14 @@ def langgraph_dev_middleware(interface: Optional[str]) -> MiddlewareResult:
22
22
 
23
23
  try:
24
24
  if interface == "terminal":
25
+
26
+ def generate_runtime(
27
+ ctx: LangGraphRuntimeContext,
28
+ ) -> LangGraphScriptRuntime:
29
+ return LangGraphScriptRuntime(ctx, ctx.entrypoint)
30
+
25
31
  runtime_factory = UiPathRuntimeFactory(
26
- LangGraphRuntime, LangGraphRuntimeContext
32
+ LangGraphScriptRuntime, LangGraphRuntimeContext, generate_runtime
27
33
  )
28
34
 
29
35
  _instrument_traceable_attributes()
@@ -17,7 +17,7 @@ from uipath._events._event_bus import EventBus
17
17
  from uipath.eval._helpers import auto_discover_entrypoint
18
18
 
19
19
  from uipath_langchain._cli._runtime._context import LangGraphRuntimeContext
20
- from uipath_langchain._cli._runtime._runtime import LangGraphRuntime
20
+ from uipath_langchain._cli._runtime._runtime import LangGraphScriptRuntime
21
21
  from uipath_langchain._cli._utils._graph import LangGraphConfig
22
22
  from uipath_langchain._tracing import (
23
23
  LangChainExporter,
@@ -48,10 +48,9 @@ def langgraph_eval_middleware(
48
48
  asyncio.run(console_reporter.subscribe_to_eval_runtime_events(event_bus))
49
49
 
50
50
  def generate_runtime_context(
51
- context_entrypoint: str, langgraph_config: LangGraphConfig, **context_kwargs
51
+ context_entrypoint: str, **context_kwargs
52
52
  ) -> LangGraphRuntimeContext:
53
53
  context = LangGraphRuntimeContext.with_defaults(**context_kwargs)
54
- context.langgraph_config = langgraph_config
55
54
  context.entrypoint = context_entrypoint
56
55
  return context
57
56
 
@@ -63,14 +62,17 @@ def langgraph_eval_middleware(
63
62
  eval_context.eval_set = eval_set or EvalHelpers.auto_discover_eval_set()
64
63
  eval_context.eval_ids = eval_ids
65
64
 
65
+ def generate_runtime(ctx: LangGraphRuntimeContext) -> LangGraphScriptRuntime:
66
+ return LangGraphScriptRuntime(ctx, ctx.entrypoint)
67
+
66
68
  runtime_factory = UiPathRuntimeFactory(
67
- LangGraphRuntime,
69
+ LangGraphScriptRuntime,
68
70
  LangGraphRuntimeContext,
69
71
  context_generator=lambda **context_kwargs: generate_runtime_context(
70
72
  context_entrypoint=runtime_entrypoint,
71
- langgraph_config=config,
72
73
  **context_kwargs,
73
74
  ),
75
+ runtime_generator=generate_runtime,
74
76
  )
75
77
 
76
78
  if eval_context.job_id:
@@ -14,8 +14,8 @@ from uipath._cli.middlewares import MiddlewareResult
14
14
  from .._tracing import LangChainExporter, _instrument_traceable_attributes
15
15
  from ._runtime._exception import LangGraphRuntimeError
16
16
  from ._runtime._runtime import ( # type: ignore[attr-defined]
17
- LangGraphRuntime,
18
17
  LangGraphRuntimeContext,
18
+ LangGraphScriptRuntime,
19
19
  )
20
20
  from ._utils._graph import LangGraphConfig
21
21
 
@@ -32,15 +32,14 @@ def langgraph_run_middleware(
32
32
 
33
33
  try:
34
34
  context = LangGraphRuntimeContext.with_defaults(**kwargs)
35
- context.langgraph_config = config
36
35
  context.entrypoint = entrypoint
37
36
  context.input = input
38
37
  context.resume = resume
39
38
 
40
39
  _instrument_traceable_attributes()
41
40
 
42
- def generate_runtime(ctx: LangGraphRuntimeContext) -> LangGraphRuntime:
43
- runtime = LangGraphRuntime(ctx)
41
+ def generate_runtime(ctx: LangGraphRuntimeContext) -> LangGraphScriptRuntime:
42
+ runtime = LangGraphScriptRuntime(ctx, ctx.entrypoint)
44
43
  # If not resuming and no job id, delete the previous state file
45
44
  if not ctx.resume and ctx.job_id is None:
46
45
  if os.path.exists(runtime.state_file_path):
@@ -49,7 +48,7 @@ def langgraph_run_middleware(
49
48
 
50
49
  async def execute():
51
50
  runtime_factory = UiPathRuntimeFactory(
52
- LangGraphRuntime,
51
+ LangGraphScriptRuntime,
53
52
  LangGraphRuntimeContext,
54
53
  runtime_generator=generate_runtime,
55
54
  )