uipath-langchain 0.0.101__tar.gz → 0.0.102__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 (156) hide show
  1. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/PKG-INFO +1 -1
  2. uipath_langchain-0.0.101/docs/context_grounding_retriever.md → uipath_langchain-0.0.102/docs/context_grounding.md +43 -7
  3. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/pyproject.toml +1 -1
  4. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_runtime/_runtime.py +0 -3
  5. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/tracers/AsyncUiPathTracer.py +14 -56
  6. uipath_langchain-0.0.102/tests/tracers/test_async_uipath_tracer.py +366 -0
  7. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/uv.lock +1423 -1423
  8. uipath_langchain-0.0.101/docs/context_grounding_vector_store.md +0 -35
  9. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.cursorrules +0 -0
  10. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.editorconfig +0 -0
  11. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.gitattributes +0 -0
  12. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/build.yml +0 -0
  13. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/cd.yml +0 -0
  14. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/ci.yml +0 -0
  15. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/commitlint.yml +0 -0
  16. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/lint.yml +0 -0
  17. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/publish-dev.yml +0 -0
  18. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.github/workflows/test.yml +0 -0
  19. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.gitignore +0 -0
  20. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.pre-commit-config.yaml +0 -0
  21. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.python-version +0 -0
  22. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.vscode/extensions.json +0 -0
  23. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/.vscode/settings.json +0 -0
  24. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/CONTRIBUTING.md +0 -0
  25. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/LICENSE +0 -0
  26. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/README.md +0 -0
  27. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/chat_models.md +0 -0
  28. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/human_in_the_loop.md +0 -0
  29. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/quick_start.md +0 -0
  30. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/quick_start_images/cloud_env_var.png +0 -0
  31. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/multi-agent-distributed/coder-agent-package-overview.png +0 -0
  32. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/multi-agent-distributed/coder-agent-process-configuration.png +0 -0
  33. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/multi-agent-distributed/planner-agent-package-overview.png +0 -0
  34. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/multi-agent-distributed/planner-agent-process-configuration.png +0 -0
  35. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/multi-agent-distributed/researcher-agent-package-overview.png +0 -0
  36. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/multi-agent-distributed/researcher-agent-process-configuration.png +0 -0
  37. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/activate-apps.png +0 -0
  38. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/activate-deployment.png +0 -0
  39. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/copy-folder-path.png +0 -0
  40. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/deploy-solution-package-wizard.png +0 -0
  41. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/deploy-solution-package.png +0 -0
  42. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/monitor-agent.png +0 -0
  43. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/navigate-to-solution-folder.png +0 -0
  44. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/resume-condition.png +0 -0
  45. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/run-agent.png +0 -0
  46. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/solution-destination-folder.png +0 -0
  47. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/start-job.png +0 -0
  48. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/docs/sample_images/ticket-classification/upload-solution-package.png +0 -0
  49. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/README.md +0 -0
  50. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/.env.example +0 -0
  51. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/agent.mermaid +0 -0
  52. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/graph.py +0 -0
  53. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/langgraph.json +0 -0
  54. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/pyproject.toml +0 -0
  55. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/uipath.json +0 -0
  56. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/company-research-agent/uv.lock +0 -0
  57. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/database.py +0 -0
  58. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/main.py +0 -0
  59. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/models.py +0 -0
  60. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/pyproject.toml +0 -0
  61. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/schemas.py +0 -0
  62. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/templates/index.html +0 -0
  63. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/hitl-inbox-server/uv.lock +0 -0
  64. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/.env.example +0 -0
  65. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/README.md +0 -0
  66. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/coder.mermaid +0 -0
  67. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/langgraph.json +0 -0
  68. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/planner.mermaid +0 -0
  69. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/pyproject.toml +0 -0
  70. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/researcher.mermaid +0 -0
  71. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/src/multi-agent-distributed/coder.py +0 -0
  72. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/src/multi-agent-distributed/planner.py +0 -0
  73. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/src/multi-agent-distributed/researcher.py +0 -0
  74. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/uipath.json +0 -0
  75. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-planner-researcher-coder-distributed/uv.lock +0 -0
  76. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/.env.example +0 -0
  77. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/README.md +0 -0
  78. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/agent.mermaid +0 -0
  79. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/graph.py +0 -0
  80. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/langgraph.json +0 -0
  81. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/pyproject.toml +0 -0
  82. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/uipath.json +0 -0
  83. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/multi-agent-supervisor-researcher-coder/uv.lock +0 -0
  84. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/retrieval-chain/.env.example +0 -0
  85. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/retrieval-chain/README.md +0 -0
  86. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/retrieval-chain/main.py +0 -0
  87. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/retrieval-chain/pyproject.toml +0 -0
  88. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/retrieval-chain/uv.lock +0 -0
  89. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/.env.example +0 -0
  90. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/README.md +0 -0
  91. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/agent.mermaid +0 -0
  92. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/langgraph.json +0 -0
  93. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/pyproject.toml +0 -0
  94. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/src/simple-local-mcp/graph.py +0 -0
  95. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/src/simple-local-mcp/math_server.py +0 -0
  96. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/src/simple-local-mcp/weather_server.py +0 -0
  97. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/uipath.json +0 -0
  98. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-local-mcp/uv.lock +0 -0
  99. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/.env.example +0 -0
  100. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/README.md +0 -0
  101. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/agent.mermaid +0 -0
  102. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/langgraph.json +0 -0
  103. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/main.py +0 -0
  104. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/pyproject.toml +0 -0
  105. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/uipath.json +0 -0
  106. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/simple-remote-mcp/uv.lock +0 -0
  107. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/.env.example +0 -0
  108. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/README.md +0 -0
  109. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/agent.mermaid +0 -0
  110. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/escalation_app_solution/generic-escalation-app-solution-1.0.0.zip +0 -0
  111. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/langgraph.json +0 -0
  112. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/main.py +0 -0
  113. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/pyproject.toml +0 -0
  114. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/uipath.json +0 -0
  115. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/samples/ticket-classification/uv.lock +0 -0
  116. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/__init__.py +0 -0
  117. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/__init__.py +0 -0
  118. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_runtime/_context.py +0 -0
  119. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_runtime/_escalation.py +0 -0
  120. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_runtime/_exception.py +0 -0
  121. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_runtime/_input.py +0 -0
  122. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_runtime/_output.py +0 -0
  123. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_templates/langgraph.json.template +0 -0
  124. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_templates/main.py.template +0 -0
  125. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/_utils/_graph.py +0 -0
  126. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/cli_init.py +0 -0
  127. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/cli_new.py +0 -0
  128. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_cli/cli_run.py +0 -0
  129. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_utils/__init__.py +0 -0
  130. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_utils/_request_mixin.py +0 -0
  131. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_utils/_settings.py +0 -0
  132. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/_utils/_sleep_policy.py +0 -0
  133. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/chat/__init__.py +0 -0
  134. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/chat/models.py +0 -0
  135. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/chat/utils/__init__.py +0 -0
  136. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/chat/utils/_chat_types.py +0 -0
  137. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/embeddings/__init__.py +0 -0
  138. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/embeddings/embeddings.py +0 -0
  139. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/middlewares.py +0 -0
  140. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/retrievers/__init__.py +0 -0
  141. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/retrievers/context_grounding_retriever.py +0 -0
  142. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/tracers/UiPathTracer.py +0 -0
  143. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/tracers/__init__.py +0 -0
  144. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/tracers/_events.py +0 -0
  145. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/tracers/_instrument_traceable.py +0 -0
  146. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/tracers/_utils.py +0 -0
  147. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/utils/__init__.py +0 -0
  148. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/utils/_request_mixin.py +0 -0
  149. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/utils/_settings.py +0 -0
  150. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/utils/_sleep_policy.py +0 -0
  151. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/src/uipath_langchain/vectorstores/context_grounding_vectorstore.py +0 -0
  152. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/tests/__init__.py +0 -0
  153. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/tests/test_dummy.py +0 -0
  154. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/tests/test_langchain_client.py +0 -0
  155. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/tests/tracers/__init__.py +0 -0
  156. {uipath_langchain-0.0.101 → uipath_langchain-0.0.102}/tests/tracers/test_instrument_traceable.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath-langchain
3
- Version: 0.0.101
3
+ Version: 0.0.102
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,10 +1,6 @@
1
- # ContextGroundingRetriever
2
-
3
- The `ContextGroundingRetriever` is a document retrieval system that uses vector search to efficiently find and retrieve relevant information from your document store.
4
-
5
- ## Overview
1
+ # Context Grounding
6
2
 
7
- `ContextGroundingRetriever` allows you to:
3
+ Context Grounding Service allows you to:
8
4
  - Search through indexed documents using natural language queries
9
5
  - Ground LLM responses in your organization's specific information
10
6
  - Retrieve context-relevant documents for various applications
@@ -12,6 +8,11 @@ The `ContextGroundingRetriever` is a document retrieval system that uses vector
12
8
 
13
9
  You will need to create an index in `Context Grounding` to use this feature. To create an index go to organization `Admin` -> `AI Trust Layer` -> `Context Grounding`. There you can create a new index and add documents to it. See the full documentation [here](https://docs.uipath.com/automation-cloud/automation-cloud/latest/admin-guide/about-context-grounding) for more details.
14
10
 
11
+
12
+ # ContextGroundingRetriever
13
+
14
+ The `ContextGroundingRetriever` is a document retrieval system that uses vector search to efficiently find and retrieve relevant information from your document store.
15
+
15
16
  ## Basic Usage
16
17
 
17
18
  Create a simple retriever by specifying an index name:
@@ -51,4 +52,39 @@ agent = create_react_agent(model, tools, prompt="Answer user questions as best a
51
52
 
52
53
  ## Advanced Usage
53
54
 
54
- For complex applications, the retriever can be combined with other LangChain components to create robust document QA systems, agents, or knowledge bases.
55
+ For complex applications, the retriever can be combined with other LangChain components to create robust document QA systems, agents, or knowledge bases.
56
+
57
+
58
+
59
+ # ContextGroundingVectorStore
60
+
61
+ `ContextGroundingVectorStore` is a vector store implementation designed for context-aware document retrieval. It allows you to perform semantic searches and create retrieval chains with language models.
62
+
63
+ ## Searching Documents
64
+
65
+ The vector store supports various search methods:
66
+
67
+ ```python
68
+ from uipath_langchain.vectorstores.context_grounding_vectorstore import ContextGroundingVectorStore
69
+
70
+ vectorstore = ContextGroundingVectorStore(index_name="Company policy")
71
+
72
+ # Perform semantic searches with distance scores
73
+ docs_with_scores = vectorstore.asimilarity_search_with_score(query="What is the company policy on data storage?", k=5)
74
+
75
+ # Perform a similarity search with relevance scores
76
+ docs_with_relevance_scores = await vectorstore.asimilarity_search_with_relevance_scores(query=query, k=5)
77
+ ```
78
+
79
+ ## Creating a Retrieval Chain
80
+
81
+ You can integrate the vector store into a retrieval chain with a language model:
82
+
83
+ ```python
84
+ # Run a retrieval chain
85
+ model = UiPathAzureChatOpenAI(model="gpt-4o-2024-08-06", max_retries=3)
86
+ retrieval_chain = create_retrieval_chain(vectorstore=vectorstore, model=model)
87
+
88
+ query = "What is the ECCN for a laptop?"
89
+ result = retrieval_chain(query)
90
+ ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "uipath-langchain"
3
- version = "0.0.101"
3
+ version = "0.0.102"
4
4
  description = "UiPath Langchain"
5
5
  readme = { file = "README.md", content-type = "text/markdown" }
6
6
  requires-python = ">=3.10"
@@ -80,9 +80,6 @@ class LangGraphRuntime(UiPathBaseRuntime):
80
80
 
81
81
  if self.context.job_id and self.context.tracing_enabled:
82
82
  tracer = AsyncUiPathTracer(context=self.context.trace_context)
83
- await tracer.init_trace(
84
- self.context.entrypoint, self.context.job_id
85
- )
86
83
  callbacks = [tracer]
87
84
 
88
85
  graph_config: RunnableConfig = {
@@ -2,7 +2,6 @@ import asyncio
2
2
  import json
3
3
  import logging
4
4
  import queue
5
- import re
6
5
  import uuid
7
6
  import warnings
8
7
  from os import environ as env
@@ -43,9 +42,7 @@ class AsyncUiPathTracer(AsyncBaseTracer):
43
42
 
44
43
  self.context = context or UiPathTraceContext()
45
44
 
46
- llm_ops_pattern = self._get_base_url() + "{orgId}/llmops_"
47
-
48
- self.url = llm_ops_pattern.format(orgId=self.context.org_id).rstrip("/")
45
+ self.base_url = self._get_base_url()
49
46
 
50
47
  auth_token = env.get("UNATTENDED_USER_ACCESS_TOKEN") or env.get(
51
48
  "UIPATH_ACCESS_TOKEN"
@@ -103,44 +100,6 @@ class AsyncUiPathTracer(AsyncBaseTracer):
103
100
  )
104
101
  self._send_span(previous_run)
105
102
 
106
- async def init_trace(self, run_name, trace_id=None) -> None:
107
- if self.context.trace_id:
108
- # trace id already set no need to do anything
109
- return
110
-
111
- # no trace id, start a new trace
112
- await self.start_trace(run_name, trace_id)
113
-
114
- async def start_trace(self, run_name, trace_id=None) -> None:
115
- self.context.trace_id = str(uuid.uuid4())
116
-
117
- run_name = run_name or f"Job Run: {self.context.trace_id}"
118
- trace_data = {
119
- "id": self.context.trace_id,
120
- "name": re.sub(
121
- r"[!@#$<>\.]", "", run_name
122
- ), # if we use these characters the Agents UI throws some error (but llmops backend seems fine)
123
- "referenceId": self.context.reference_id,
124
- "attributes": "{}",
125
- "organizationId": self.context.org_id,
126
- "tenantId": self.context.tenant_id,
127
- }
128
-
129
- for attempt in range(self.retries):
130
- response = await self.client.post(
131
- f"{self.url}/api/Agent/trace/", headers=self.headers, json=trace_data
132
- )
133
-
134
- if response.is_success:
135
- break
136
-
137
- await asyncio.sleep(0.5 * (2**attempt)) # Exponential backoff
138
-
139
- if 400 <= response.status_code < 600:
140
- logger.warning(
141
- f"Error when sending trace: {response}. Body is: {response.text}"
142
- )
143
-
144
103
  async def wait_for_all_tracers(self) -> None:
145
104
  """
146
105
  Wait for all pending log requests to complete
@@ -159,11 +118,13 @@ class AsyncUiPathTracer(AsyncBaseTracer):
159
118
 
160
119
  span_data = self.log_queue.get_nowait()
161
120
 
121
+ url = self._build_url(self.context.trace_id)
122
+
162
123
  for attempt in range(self.retries):
163
124
  response = await self.client.post(
164
- f"{self.url}/api/Agent/span/",
125
+ url,
165
126
  headers=self.headers,
166
- json=span_data,
127
+ json=[span_data], # api expects a list of spans
167
128
  timeout=10,
168
129
  )
169
130
 
@@ -189,11 +150,12 @@ class AsyncUiPathTracer(AsyncBaseTracer):
189
150
  break
190
151
 
191
152
  span_data = self.log_queue.get_nowait()
153
+ url = self._build_url(self.context.trace_id)
192
154
 
193
155
  response = await self.client.post(
194
- f"{self.url}/api/Agent/span/",
156
+ url,
195
157
  headers=self.headers,
196
- json=span_data,
158
+ json=[span_data], # api expects a list of spans
197
159
  timeout=10,
198
160
  )
199
161
  except Exception as e:
@@ -239,6 +201,7 @@ class AsyncUiPathTracer(AsyncBaseTracer):
239
201
  "jobKey": self.context.job_id,
240
202
  "folderKey": self.context.folder_key,
241
203
  "processKey": self.context.folder_key,
204
+ "expiryTimeUtc": None,
242
205
  }
243
206
 
244
207
  self.log_queue.put(span_data)
@@ -293,16 +256,11 @@ class AsyncUiPathTracer(AsyncBaseTracer):
293
256
  uipath_url = (
294
257
  env.get("UIPATH_URL") or "https://cloud.uipath.com/dummyOrg/dummyTennant/"
295
258
  )
296
- uipath_url = uipath_url.rstrip("/")
297
259
 
298
- # split by "//" to get ['', 'https:', 'alpha.uipath.com/ada/byoa']
299
- parts = uipath_url.split("//")
300
-
301
- # after splitting by //, the base URL will be at index 1 along with the rest,
302
- # hence split it again using "/" to get ['https:', 'alpha.uipath.com', 'ada', 'byoa']
303
- base_url_parts = parts[1].split("/")
260
+ uipath_url = uipath_url.rstrip("/")
304
261
 
305
- # combine scheme and netloc to get the base URL
306
- base_url = parts[0] + "//" + base_url_parts[0] + "/"
262
+ return uipath_url
307
263
 
308
- return base_url
264
+ def _build_url(self, trace_id: Optional[str]) -> str:
265
+ """Construct the URL for the API request."""
266
+ return f"{self.base_url}/llmopstenant_/api/Traces/spans?traceId={trace_id}&source=Robots"
@@ -0,0 +1,366 @@
1
+ import uuid
2
+ from datetime import datetime
3
+ from unittest.mock import AsyncMock, MagicMock, patch
4
+
5
+ import pytest
6
+ from langchain_core.tracers.schemas import Run
7
+ from uipath._cli._runtime._contracts import UiPathTraceContext
8
+
9
+ from uipath_langchain.tracers._events import CustomTraceEvents, FunctionCallEventData
10
+ from uipath_langchain.tracers.AsyncUiPathTracer import AsyncUiPathTracer, Status
11
+
12
+
13
+ class TestAsyncUiPathTracer:
14
+ @pytest.fixture
15
+ def mock_response(self):
16
+ response = AsyncMock()
17
+ response.is_success = True
18
+ response.status_code = 200
19
+ response.text = "Success"
20
+ return response
21
+
22
+ @pytest.fixture
23
+ def mock_client(self, mock_response):
24
+ client = AsyncMock()
25
+ client.post.return_value = mock_response
26
+ return client
27
+
28
+ @pytest.fixture
29
+ def mock_context(self):
30
+ context = UiPathTraceContext()
31
+ context.trace_id = "test-trace-id"
32
+ context.parent_span_id = "test-parent-span-id"
33
+ context.org_id = "test-org-id"
34
+ context.tenant_id = "test-tenant-id"
35
+ context.job_id = "test-job-id"
36
+ context.folder_key = "test-folder-key"
37
+ context.reference_id = "test-reference-id"
38
+ return context
39
+
40
+ @pytest.fixture
41
+ def tracer(self, mock_client, mock_context):
42
+ # Don't create any real asyncio tasks in fixtures
43
+ with patch("asyncio.create_task"):
44
+ with patch.dict("os.environ", {"UIPATH_ACCESS_TOKEN": "test-token"}):
45
+ # Instantiate the tracer but don't start the worker
46
+ tracer = AsyncUiPathTracer(context=mock_context, client=mock_client)
47
+
48
+ # Set worker_task to a mock that can be awaited
49
+ mock_task = AsyncMock()
50
+ tracer.worker_task = mock_task
51
+
52
+ # Set running to False to avoid worker logic
53
+ tracer.running = False
54
+
55
+ yield tracer
56
+
57
+ @pytest.mark.asyncio
58
+ async def test_init(self, tracer, mock_client, mock_context):
59
+ # We only verify non-task related initialization
60
+ assert tracer.client == mock_client
61
+ assert tracer.context == mock_context
62
+ assert tracer.headers == {"Authorization": "Bearer test-token"}
63
+ assert tracer.running is False
64
+
65
+ @pytest.mark.asyncio
66
+ async def test_persist_run(self, tracer):
67
+ # Mock the _send_span method
68
+ tracer._send_span = MagicMock()
69
+
70
+ # Create a run with datetime for start_time
71
+ run = Run(
72
+ id=uuid.uuid4(),
73
+ name="test_run",
74
+ start_time=datetime(2023, 1, 1, 0, 0, 0),
75
+ run_type="llm",
76
+ inputs={"prompt": "test"},
77
+ )
78
+
79
+ # Call _persist_run
80
+ await tracer._persist_run(run)
81
+
82
+ # Verify _send_span was called with the run
83
+ tracer._send_span.assert_called_once_with(run)
84
+
85
+ @pytest.mark.asyncio
86
+ async def test_send_span(self, tracer):
87
+ # Create a run
88
+ run_id = uuid.uuid4()
89
+ run = Run(
90
+ id=run_id,
91
+ name="test_run",
92
+ start_time=datetime(2023, 1, 1, 0, 0, 0),
93
+ end_time=datetime(2023, 1, 1, 0, 1, 0),
94
+ run_type="llm",
95
+ inputs={"prompt": "test"},
96
+ outputs={"result": "output"},
97
+ error=None, # Make it explicit that there's no error
98
+ )
99
+
100
+ # Call _send_span without mocking its internal methods
101
+ tracer._send_span(run)
102
+
103
+ # Get the item from the queue
104
+ span_data = tracer.log_queue.get_nowait()
105
+
106
+ # Verify expected data was put in the queue
107
+ assert span_data["id"] == str(run_id)
108
+ assert span_data["name"] == "test_run"
109
+ assert span_data["traceId"] == tracer.context.trace_id
110
+ assert span_data["parentId"] == tracer.context.parent_span_id
111
+ assert (
112
+ span_data["startTime"] == "2023-01-01T00:00:00"
113
+ ) # Serialized to ISO format
114
+ assert span_data["endTime"] == "2023-01-01T00:01:00" # Serialized to ISO format
115
+ assert span_data["status"] == Status.SUCCESS # Since error is None
116
+ assert (
117
+ "attributes" in span_data
118
+ ) # Just verify it exists, don't check exact content
119
+ assert span_data["spanType"] == "LangGraphRun"
120
+
121
+ @pytest.mark.asyncio
122
+ async def test_on_custom_event_function_call(self, tracer):
123
+ # Instead of modifying the Run object, we'll patch the entire Run.create_child method
124
+ # at the module level
125
+ child_run = Run(
126
+ id=uuid.uuid4(),
127
+ name="function_call",
128
+ run_type="tool",
129
+ inputs={"arg": "value"},
130
+ start_time=datetime(2023, 1, 1, 0, 0, 0),
131
+ )
132
+
133
+ # Create a run
134
+ run_id = uuid.uuid4()
135
+ parent_run = Run(
136
+ id=run_id,
137
+ name="parent_run",
138
+ run_type="chain",
139
+ inputs={},
140
+ start_time=datetime(2023, 1, 1, 0, 0, 0),
141
+ )
142
+
143
+ # Add the run to the run_map
144
+ tracer.run_map[str(run_id)] = parent_run
145
+
146
+ # Mock _send_span method
147
+ tracer._send_span = MagicMock()
148
+
149
+ # Patch the RunTree create_child in langsmith
150
+ with patch(
151
+ "langchain_core.tracers.schemas.Run.create_child", return_value=child_run
152
+ ) as mock_create_child:
153
+ # Create function call event data
154
+ call_uuid = "test-call-uuid"
155
+ event_data = FunctionCallEventData(
156
+ call_uuid=call_uuid,
157
+ event_type="call",
158
+ function_name="test_function",
159
+ run_type="tool",
160
+ inputs={"arg": "value"},
161
+ tags=["test-tag"],
162
+ metadata={"meta": "data"},
163
+ output=None,
164
+ error=None,
165
+ )
166
+
167
+ # Call on_custom_event
168
+ await tracer.on_custom_event(
169
+ name=CustomTraceEvents.UIPATH_TRACE_FUNCTION_CALL,
170
+ data=event_data,
171
+ run_id=run_id,
172
+ )
173
+
174
+ # Verify the patched create_child was called with correct arguments
175
+ mock_create_child.assert_called_once_with(
176
+ name="test_function",
177
+ run_type="tool",
178
+ tags=["test-tag"],
179
+ inputs={"arg": "value"},
180
+ )
181
+
182
+ # Verify _send_span was called
183
+ tracer._send_span.assert_called_once()
184
+
185
+ # Verify function_call_run_map was updated
186
+ assert call_uuid in tracer.function_call_run_map
187
+ assert tracer.function_call_run_map[call_uuid] == child_run
188
+
189
+ @pytest.mark.asyncio
190
+ async def test_on_custom_event_function_completion(self, tracer):
191
+ # Create a function call run
192
+ call_uuid = "test-call-uuid"
193
+ child_run = Run(
194
+ id=uuid.uuid4(),
195
+ name="function_call",
196
+ run_type="function",
197
+ inputs={"arg": "value"},
198
+ start_time=datetime(2023, 1, 1, 0, 0, 0),
199
+ )
200
+
201
+ # Add the run to the function_call_run_map
202
+ tracer.function_call_run_map[call_uuid] = child_run
203
+
204
+ # Mock _send_span method and _safe_dict_dump
205
+ tracer._send_span = MagicMock()
206
+ tracer._safe_dict_dump = MagicMock(return_value={"result": "output"})
207
+
208
+ # Create function completion event data
209
+ event_data = FunctionCallEventData(
210
+ call_uuid=call_uuid,
211
+ event_type="completion",
212
+ function_name="test_function",
213
+ output={"result": "output"},
214
+ error=None,
215
+ inputs={},
216
+ )
217
+
218
+ # Patch Run.end method since we can't modify the Run object directly
219
+ with patch("langchain_core.tracers.schemas.Run.end") as mock_end:
220
+ # Call on_custom_event
221
+ await tracer.on_custom_event(
222
+ name=CustomTraceEvents.UIPATH_TRACE_FUNCTION_CALL,
223
+ data=event_data,
224
+ run_id=uuid.uuid4(),
225
+ )
226
+
227
+ # Verify Run.end was called with the right arguments
228
+ mock_end.assert_called_once_with(outputs={"result": "output"}, error=None)
229
+
230
+ # Verify _send_span was called
231
+ tracer._send_span.assert_called_once_with(child_run)
232
+
233
+ # Verify run was removed from function_call_run_map
234
+ assert call_uuid not in tracer.function_call_run_map
235
+
236
+ @pytest.mark.asyncio
237
+ async def test_determine_status(self, tracer):
238
+ # Test success status
239
+ assert tracer._determine_status(None) == Status.SUCCESS
240
+
241
+ # Test error status
242
+ assert tracer._determine_status("Error message") == Status.ERROR
243
+
244
+ # Test interrupted status
245
+ assert tracer._determine_status("GraphInterrupt(reason)") == Status.INTERRUPTED
246
+
247
+ @pytest.mark.asyncio
248
+ async def test_build_url(self, tracer):
249
+ # Mock the _get_base_url method
250
+ tracer.base_url = "https://cloud.uipath.com/org/tenant"
251
+
252
+ # Call _build_url
253
+ url = tracer._build_url("test-trace-id")
254
+
255
+ # Verify the URL
256
+ assert (
257
+ url
258
+ == "https://cloud.uipath.com/org/tenant/llmopstenant_/api/Traces/spans?traceId=test-trace-id&source=Robots"
259
+ )
260
+
261
+ @pytest.mark.asyncio
262
+ async def test_wait_for_all_tracers(self, tracer):
263
+ # Instead of trying to await the mock directly, let's patch the wait_for_all_tracers method
264
+ # to avoid awaiting the worker_task
265
+
266
+ # Save the original method
267
+ original_method = tracer.wait_for_all_tracers
268
+
269
+ # Replace with our test version that doesn't await the task
270
+ async def test_wait_for_all_tracers():
271
+ tracer.running = False
272
+ # Just return, don't await the worker_task
273
+
274
+ # Patch the method
275
+ tracer.wait_for_all_tracers = test_wait_for_all_tracers
276
+
277
+ # Call our test method
278
+ await tracer.wait_for_all_tracers()
279
+
280
+ # Verify running is set to False
281
+ assert tracer.running is False
282
+
283
+ # Restore the original method
284
+ tracer.wait_for_all_tracers = original_method
285
+
286
+ @pytest.mark.asyncio
287
+ async def test_worker_functionality(self, mock_client, mock_response, mock_context):
288
+ # For testing the worker functionality, we'll manually set up the tracer
289
+ with patch("asyncio.create_task"):
290
+ with patch.dict("os.environ", {"UIPATH_ACCESS_TOKEN": "test-token"}):
291
+ with patch.dict(
292
+ "os.environ", {"UIPATH_URL": "https://cloud.uipath.com/org/tenant"}
293
+ ):
294
+ # Mock the client.post method
295
+ mock_client.post = AsyncMock(return_value=mock_response)
296
+ # Create a tracer without starting the worker
297
+ tracer = AsyncUiPathTracer(context=mock_context, client=mock_client)
298
+ tracer.running = (
299
+ False # Set running to False to ensure worker exits
300
+ )
301
+
302
+ # Configure test data
303
+ expected_url = "https://cloud.uipath.com/org/tenant/llmopstenant_/api/Traces/spans?traceId=test-trace-id&source=Robots"
304
+
305
+ # Add a test span to the queue
306
+ span_data = {
307
+ "id": "test-id",
308
+ "name": "test-span",
309
+ "traceId": "test-trace-id",
310
+ }
311
+ tracer.log_queue.put(span_data)
312
+
313
+ # Call the worker method directly
314
+ await tracer._worker()
315
+
316
+ # Verify client.post was called correctly
317
+ mock_client.post.assert_called_with(
318
+ expected_url,
319
+ headers=tracer.headers,
320
+ json=[span_data],
321
+ timeout=10,
322
+ )
323
+
324
+ @pytest.mark.asyncio
325
+ async def test_httpx_post_with_correct_data(self, mock_client, mock_response):
326
+ # Create a context
327
+ context = UiPathTraceContext()
328
+ context.trace_id = "test-trace-id"
329
+ context.parent_span_id = "test-parent-span-id"
330
+
331
+ # Create a tracer with patch.dict to set the environment variables
332
+ with patch("asyncio.create_task"):
333
+ with patch.dict("os.environ", {"UIPATH_ACCESS_TOKEN": "test-token"}):
334
+ # Fix the patch path - we want to patch the method, not the import
335
+ with patch.object(
336
+ AsyncUiPathTracer,
337
+ "_get_base_url",
338
+ return_value="https://test.uipath.com/org/tenant",
339
+ ):
340
+ tracer = AsyncUiPathTracer(context=context, client=mock_client)
341
+ tracer.running = (
342
+ False # Set running to False to ensure worker exits
343
+ )
344
+
345
+ # Create a span that will go in the queue
346
+ span_data = {
347
+ "id": "test-id",
348
+ "name": "test-span",
349
+ "traceId": "test-trace-id",
350
+ "attributes": '{"key": "value"}',
351
+ }
352
+
353
+ # Add span to the queue
354
+ tracer.log_queue.put(span_data)
355
+
356
+ # Execute the worker directly
357
+ await tracer._worker()
358
+
359
+ # Verify the post was called with the right URL and data
360
+ expected_url = "https://test.uipath.com/org/tenant/llmopstenant_/api/Traces/spans?traceId=test-trace-id&source=Robots"
361
+ mock_client.post.assert_called_with(
362
+ expected_url,
363
+ headers={"Authorization": "Bearer test-token"},
364
+ json=[span_data],
365
+ timeout=10,
366
+ )