@langwatch/mcp-server 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/.release-please-shim +1 -0
  2. package/CHANGELOG.md +87 -0
  3. package/LICENSE +7 -0
  4. package/dist/archive-project-HZBRPR2S.js +19 -0
  5. package/dist/{archive-scenario-WJ2A7ETN.js → archive-scenario-P5RRITRM.js} +4 -4
  6. package/dist/{archive-suite-4JOM4SSL.js → archive-suite-NUUFD2EM.js} +4 -4
  7. package/dist/{assign-prompt-tag-GL7EAAF3.js → assign-prompt-tag-FKCCZPML.js} +3 -3
  8. package/dist/{chunk-2WPLXEKF.js → chunk-42ZHHHIJ.js} +20 -5
  9. package/dist/chunk-ADSJ2FDA.js +44 -0
  10. package/dist/{chunk-IE4M5OGE.js → chunk-BB7EOKHR.js} +2 -2
  11. package/dist/chunk-BBJ5WAJB.js +24 -0
  12. package/dist/{chunk-EGH5RPXM.js → chunk-BYWYM2RP.js} +2 -2
  13. package/dist/{chunk-2GT7IFWK.js → chunk-CCM4ZFGF.js} +2 -2
  14. package/dist/{chunk-LUMEZEHL.js → chunk-CHKCEZBP.js} +2 -2
  15. package/dist/{chunk-ZVS4UKN2.js → chunk-HKY3GW45.js} +2 -2
  16. package/dist/{chunk-EUQDVOSU.js → chunk-JHOSVOHT.js} +2 -2
  17. package/dist/{chunk-E5JYYU3J.js → chunk-JVLJKQJG.js} +669 -94
  18. package/dist/{chunk-BWWY5KEF.js → chunk-KOO5733S.js} +3 -2
  19. package/dist/{chunk-HYMIWO3U.js → chunk-R7C7OUVG.js} +2 -2
  20. package/dist/{chunk-WQG2DFHX.js → chunk-TROIWSEQ.js} +2 -2
  21. package/dist/{chunk-CCWCIJJ3.js → chunk-X2SEURT2.js} +2 -2
  22. package/dist/{chunk-4AUB2BIA.js → chunk-XC62KJIT.js} +3 -3
  23. package/dist/config.js +1 -1
  24. package/dist/{create-agent-MBOOT3XK.js → create-agent-K5Q7BFGZ.js} +4 -4
  25. package/dist/{create-annotation-XMV6A7ED.js → create-annotation-KN3GE3DK.js} +4 -4
  26. package/dist/create-api-key-OQI5PUNQ.js +26 -0
  27. package/dist/{create-dashboard-VRKLFVZJ.js → create-dashboard-G4QA5AXP.js} +4 -4
  28. package/dist/{create-dataset-7HQPZCRE.js → create-dataset-WQSC37N7.js} +4 -4
  29. package/dist/{create-dataset-records-2NIVFYTV.js → create-dataset-records-B4RL3FLC.js} +4 -4
  30. package/dist/{create-evaluator-WYFRFLRC.js → create-evaluator-YFFQIR7E.js} +4 -4
  31. package/dist/create-mcp-server.js +3 -2
  32. package/dist/create-project-CUVQ67VN.js +44 -0
  33. package/dist/{create-prompt-IEN7O6JT.js → create-prompt-NGXKSP4X.js} +3 -3
  34. package/dist/{create-prompt-tag-CAEZ45VO.js → create-prompt-tag-IUKYPVHH.js} +3 -3
  35. package/dist/{create-scenario-6YHSMGLP.js → create-scenario-FNBXALH3.js} +4 -4
  36. package/dist/{create-suite-H5XOFDE5.js → create-suite-DJEPD4ZB.js} +4 -4
  37. package/dist/{delete-agent-JKTNBWAA.js → delete-agent-TJI5XBBM.js} +4 -4
  38. package/dist/{delete-annotation-ACMDV6QO.js → delete-annotation-KRP53TUU.js} +4 -4
  39. package/dist/{delete-dashboard-VJSR7CRU.js → delete-dashboard-N5SZJIR3.js} +4 -4
  40. package/dist/{delete-dataset-RTTTWP4D.js → delete-dataset-KDUOHL2P.js} +4 -4
  41. package/dist/{delete-dataset-records-KNQTIPQK.js → delete-dataset-records-DM4W3PAW.js} +4 -4
  42. package/dist/{delete-evaluator-7FVC5WM4.js → delete-evaluator-7ZATLJOA.js} +4 -4
  43. package/dist/{delete-prompt-tag-ZMZUAGFW.js → delete-prompt-tag-I6HNMSVJ.js} +3 -3
  44. package/dist/{delete-workflow-EYQ3T4RQ.js → delete-workflow-QEO74JQR.js} +4 -4
  45. package/dist/{get-agent-E3QSTVKG.js → get-agent-3KDWCP5N.js} +4 -4
  46. package/dist/{get-analytics-2OHV763I.js → get-analytics-GPVJX7SF.js} +3 -3
  47. package/dist/{get-dashboard-PC7JDHH6.js → get-dashboard-YPTIE5YY.js} +4 -4
  48. package/dist/{get-dataset-H5IK5FVU.js → get-dataset-6DQFYITM.js} +4 -4
  49. package/dist/{get-evaluator-UWVUPYTM.js → get-evaluator-PCM6XQAU.js} +4 -4
  50. package/dist/get-project-JCMWXVLU.js +26 -0
  51. package/dist/{get-prompt-WZUOLLQC.js → get-prompt-5XAGWWBG.js} +3 -3
  52. package/dist/{get-scenario-Q6LCNUYN.js → get-scenario-7XBCDZWX.js} +4 -4
  53. package/dist/{get-simulation-run-Z2XKO256.js → get-simulation-run-AV24FJWI.js} +4 -4
  54. package/dist/{get-suite-BXK5TN7P.js → get-suite-4DBVHFEM.js} +4 -4
  55. package/dist/{get-trace-4EJAYVBG.js → get-trace-MRBDS3HJ.js} +3 -3
  56. package/dist/{get-workflow-O34QJLHD.js → get-workflow-UR4Y6UFX.js} +4 -4
  57. package/dist/{http-server-ISHF7NJX.js → http-server-DEGNV5EP.js} +4 -3
  58. package/dist/index.js +1453 -431
  59. package/dist/{langwatch-api-annotations-ERBG27RF.js → langwatch-api-annotations-ZJDRB4JH.js} +4 -4
  60. package/dist/{langwatch-api-dashboards-G6TR7VVO.js → langwatch-api-dashboards-WARLI6NF.js} +4 -4
  61. package/dist/{langwatch-api-monitors-WSXZLS2B.js → langwatch-api-monitors-4XKXHYCG.js} +3 -3
  62. package/dist/{langwatch-api-secrets-RR5DKG2X.js → langwatch-api-secrets-6SHK5G7Q.js} +3 -3
  63. package/dist/{langwatch-api-triggers-2RTNSWQY.js → langwatch-api-triggers-5SX6R2WU.js} +3 -3
  64. package/dist/langwatch-api-workflows-NLJENNXE.js +15 -0
  65. package/dist/{list-agents-AW3P6FJV.js → list-agents-NECO7MPI.js} +4 -4
  66. package/dist/{list-annotations-QNCGWPQ3.js → list-annotations-3OJEO774.js} +4 -4
  67. package/dist/list-api-keys-AWW7ROLB.js +37 -0
  68. package/dist/{list-dashboards-R7RK2IXL.js → list-dashboards-DVPVVVKW.js} +4 -4
  69. package/dist/{list-dataset-records-WVCSQP7P.js → list-dataset-records-I4BYORF5.js} +4 -4
  70. package/dist/{list-datasets-KEXRLDEU.js → list-datasets-WUAE5HGX.js} +4 -4
  71. package/dist/{list-evaluators-7R2LB4JH.js → list-evaluators-B6OSVAM2.js} +4 -4
  72. package/dist/{list-model-providers-OBYJCKBX.js → list-model-providers-NL6IP4UZ.js} +4 -4
  73. package/dist/list-projects-5FHMJ4PQ.js +42 -0
  74. package/dist/{list-prompt-tags-6LY3ZPYI.js → list-prompt-tags-Z2DD6FLQ.js} +3 -3
  75. package/dist/{list-prompts-VWEZ4CDE.js → list-prompts-VNXKHK7T.js} +3 -3
  76. package/dist/{list-scenarios-TXD4W2ZJ.js → list-scenarios-CFZHXL76.js} +4 -4
  77. package/dist/{list-simulation-runs-RHPOLMFI.js → list-simulation-runs-AM2BXLBW.js} +4 -4
  78. package/dist/{list-suites-FSGBX27Z.js → list-suites-ZDOHAAXF.js} +4 -4
  79. package/dist/{list-workflows-VRGEZ3EN.js → list-workflows-WBRBKLIT.js} +4 -4
  80. package/dist/{rename-prompt-tag-VOJJLX4M.js → rename-prompt-tag-A4RJUK7Z.js} +3 -3
  81. package/dist/revoke-api-key-ZSPSPF5G.js +15 -0
  82. package/dist/{run-agent-KTCC7TB7.js → run-agent-JFNDY7MR.js} +4 -4
  83. package/dist/{run-suite-BTMHGI2D.js → run-suite-TH7LO5TJ.js} +4 -4
  84. package/dist/{run-workflow-IGAYGKJL.js → run-workflow-CK3JP5U2.js} +4 -4
  85. package/dist/{search-traces-VYFUIMXH.js → search-traces-3BBVYPC3.js} +3 -3
  86. package/dist/{set-model-provider-W5IUI326.js → set-model-provider-WOC5FNMV.js} +4 -4
  87. package/dist/{update-agent-4BB7EYLR.js → update-agent-YMEV5MTL.js} +4 -4
  88. package/dist/{update-dataset-CXBKZ4W3.js → update-dataset-EYT5POFM.js} +4 -4
  89. package/dist/{update-dataset-record-HOHAMHXG.js → update-dataset-record-VFF5JTX4.js} +4 -4
  90. package/dist/{update-evaluator-IVOR6FTR.js → update-evaluator-6IJHFG2E.js} +4 -4
  91. package/dist/update-project-OIT4WPFI.js +24 -0
  92. package/dist/{update-prompt-OWQAKE7K.js → update-prompt-ZU2DD6KM.js} +3 -3
  93. package/dist/{update-scenario-GDFVILPN.js → update-scenario-3VUTPDRU.js} +4 -4
  94. package/dist/{update-suite-BXYUYSPT.js → update-suite-C6JFDQHL.js} +4 -4
  95. package/package.json +7 -7
  96. package/pnpm-workspace.yaml +2 -0
  97. package/pyproject.toml +3 -0
  98. package/src/__tests__/all-tools.integration.test.ts +9 -0
  99. package/src/__tests__/datasets.integration.test.ts +17 -0
  100. package/src/__tests__/datasets.unit.test.ts +4 -0
  101. package/src/__tests__/experiment-list-tools.unit.test.ts +157 -0
  102. package/src/__tests__/get-experiment-results.unit.test.ts +222 -0
  103. package/src/__tests__/project-api-key-tools.unit.test.ts +451 -0
  104. package/src/__tests__/scenario-tools.unit.test.ts +3 -0
  105. package/src/config.ts +2 -0
  106. package/src/create-mcp-server.ts +257 -13
  107. package/src/langwatch-api-api-keys.ts +54 -0
  108. package/src/langwatch-api-projects.ts +82 -0
  109. package/src/langwatch-api.ts +22 -4
  110. package/src/tools/archive-project.ts +14 -0
  111. package/src/tools/create-api-key.ts +29 -0
  112. package/src/tools/create-project.ts +45 -0
  113. package/src/tools/get-experiment-results.ts +273 -0
  114. package/src/tools/get-project.ts +20 -0
  115. package/src/tools/list-api-keys.ts +33 -0
  116. package/src/tools/list-experiment-runs.ts +142 -0
  117. package/src/tools/list-experiments.ts +95 -0
  118. package/src/tools/list-projects.ts +41 -0
  119. package/src/tools/revoke-api-key.ts +9 -0
  120. package/src/tools/{run-evaluation.ts → run-experiment.ts} +5 -5
  121. package/src/tools/update-project.ts +22 -0
  122. package/uv.lock +192 -530
  123. package/Dockerfile +0 -22
  124. package/build.js +0 -12
  125. package/dist/archive-scenario-WJ2A7ETN.js.map +0 -1
  126. package/dist/archive-suite-4JOM4SSL.js.map +0 -1
  127. package/dist/assign-prompt-tag-GL7EAAF3.js.map +0 -1
  128. package/dist/chunk-2GT7IFWK.js.map +0 -1
  129. package/dist/chunk-2WPLXEKF.js.map +0 -1
  130. package/dist/chunk-4AUB2BIA.js.map +0 -1
  131. package/dist/chunk-BWWY5KEF.js.map +0 -1
  132. package/dist/chunk-CCWCIJJ3.js.map +0 -1
  133. package/dist/chunk-E5JYYU3J.js.map +0 -1
  134. package/dist/chunk-EGH5RPXM.js.map +0 -1
  135. package/dist/chunk-EUQDVOSU.js.map +0 -1
  136. package/dist/chunk-HYMIWO3U.js.map +0 -1
  137. package/dist/chunk-IE4M5OGE.js.map +0 -1
  138. package/dist/chunk-LUMEZEHL.js.map +0 -1
  139. package/dist/chunk-NUFPTHKU.js.map +0 -1
  140. package/dist/chunk-WQG2DFHX.js.map +0 -1
  141. package/dist/chunk-WVI5CJ6S.js.map +0 -1
  142. package/dist/chunk-ZVS4UKN2.js.map +0 -1
  143. package/dist/chunk-ZXKLPC2E.js.map +0 -1
  144. package/dist/config.js.map +0 -1
  145. package/dist/create-agent-MBOOT3XK.js.map +0 -1
  146. package/dist/create-annotation-XMV6A7ED.js.map +0 -1
  147. package/dist/create-dashboard-VRKLFVZJ.js.map +0 -1
  148. package/dist/create-dataset-7HQPZCRE.js.map +0 -1
  149. package/dist/create-dataset-records-2NIVFYTV.js.map +0 -1
  150. package/dist/create-evaluator-WYFRFLRC.js.map +0 -1
  151. package/dist/create-mcp-server.js.map +0 -1
  152. package/dist/create-prompt-IEN7O6JT.js.map +0 -1
  153. package/dist/create-prompt-tag-CAEZ45VO.js.map +0 -1
  154. package/dist/create-scenario-6YHSMGLP.js.map +0 -1
  155. package/dist/create-suite-H5XOFDE5.js.map +0 -1
  156. package/dist/delete-agent-JKTNBWAA.js.map +0 -1
  157. package/dist/delete-annotation-ACMDV6QO.js.map +0 -1
  158. package/dist/delete-dashboard-VJSR7CRU.js.map +0 -1
  159. package/dist/delete-dataset-RTTTWP4D.js.map +0 -1
  160. package/dist/delete-dataset-records-KNQTIPQK.js.map +0 -1
  161. package/dist/delete-evaluator-7FVC5WM4.js.map +0 -1
  162. package/dist/delete-prompt-tag-ZMZUAGFW.js.map +0 -1
  163. package/dist/delete-workflow-EYQ3T4RQ.js.map +0 -1
  164. package/dist/discover-evaluator-schema-H23XCLNE.js.map +0 -1
  165. package/dist/discover-scenario-schema-MEEEVND7.js.map +0 -1
  166. package/dist/discover-schema-3T52ORPB.js.map +0 -1
  167. package/dist/get-agent-E3QSTVKG.js.map +0 -1
  168. package/dist/get-analytics-2OHV763I.js.map +0 -1
  169. package/dist/get-dashboard-PC7JDHH6.js.map +0 -1
  170. package/dist/get-dataset-H5IK5FVU.js.map +0 -1
  171. package/dist/get-evaluator-UWVUPYTM.js.map +0 -1
  172. package/dist/get-prompt-WZUOLLQC.js.map +0 -1
  173. package/dist/get-scenario-Q6LCNUYN.js.map +0 -1
  174. package/dist/get-simulation-run-Z2XKO256.js.map +0 -1
  175. package/dist/get-suite-BXK5TN7P.js.map +0 -1
  176. package/dist/get-trace-4EJAYVBG.js.map +0 -1
  177. package/dist/get-workflow-O34QJLHD.js.map +0 -1
  178. package/dist/http-server-ISHF7NJX.js.map +0 -1
  179. package/dist/index.js.map +0 -1
  180. package/dist/langwatch-api-annotations-ERBG27RF.js.map +0 -1
  181. package/dist/langwatch-api-dashboards-G6TR7VVO.js.map +0 -1
  182. package/dist/langwatch-api-monitors-WSXZLS2B.js.map +0 -1
  183. package/dist/langwatch-api-secrets-RR5DKG2X.js.map +0 -1
  184. package/dist/langwatch-api-triggers-2RTNSWQY.js.map +0 -1
  185. package/dist/langwatch-api-workflows-VJRIIDZ7.js +0 -15
  186. package/dist/langwatch-api-workflows-VJRIIDZ7.js.map +0 -1
  187. package/dist/list-agents-AW3P6FJV.js.map +0 -1
  188. package/dist/list-annotations-QNCGWPQ3.js.map +0 -1
  189. package/dist/list-dashboards-R7RK2IXL.js.map +0 -1
  190. package/dist/list-dataset-records-WVCSQP7P.js.map +0 -1
  191. package/dist/list-datasets-KEXRLDEU.js.map +0 -1
  192. package/dist/list-evaluators-7R2LB4JH.js.map +0 -1
  193. package/dist/list-model-providers-OBYJCKBX.js.map +0 -1
  194. package/dist/list-prompt-tags-6LY3ZPYI.js.map +0 -1
  195. package/dist/list-prompts-VWEZ4CDE.js.map +0 -1
  196. package/dist/list-scenarios-TXD4W2ZJ.js.map +0 -1
  197. package/dist/list-simulation-runs-RHPOLMFI.js.map +0 -1
  198. package/dist/list-suites-FSGBX27Z.js.map +0 -1
  199. package/dist/list-workflows-VRGEZ3EN.js.map +0 -1
  200. package/dist/rename-prompt-tag-VOJJLX4M.js.map +0 -1
  201. package/dist/run-agent-KTCC7TB7.js.map +0 -1
  202. package/dist/run-evaluation-2X3V3Q6L.js +0 -64
  203. package/dist/run-evaluation-2X3V3Q6L.js.map +0 -1
  204. package/dist/run-suite-BTMHGI2D.js.map +0 -1
  205. package/dist/run-workflow-IGAYGKJL.js.map +0 -1
  206. package/dist/search-traces-VYFUIMXH.js.map +0 -1
  207. package/dist/set-model-provider-W5IUI326.js.map +0 -1
  208. package/dist/update-agent-4BB7EYLR.js.map +0 -1
  209. package/dist/update-dataset-CXBKZ4W3.js.map +0 -1
  210. package/dist/update-dataset-record-HOHAMHXG.js.map +0 -1
  211. package/dist/update-evaluator-IVOR6FTR.js.map +0 -1
  212. package/dist/update-prompt-OWQAKE7K.js.map +0 -1
  213. package/dist/update-scenario-GDFVILPN.js.map +0 -1
  214. package/dist/update-suite-BXYUYSPT.js.map +0 -1
  215. package/tests/evaluations.ipynb +0 -649
  216. package/tests/fixtures/azure/azure_openai_stream_bot_expected.py +0 -102
  217. package/tests/fixtures/azure/azure_openai_stream_bot_input.py +0 -78
  218. package/tests/fixtures/dspy/dspy_bot_expected.py +0 -61
  219. package/tests/fixtures/dspy/dspy_bot_input.py +0 -53
  220. package/tests/fixtures/fastapi/fastapi_app_expected.py +0 -68
  221. package/tests/fixtures/fastapi/fastapi_app_input.py +0 -60
  222. package/tests/fixtures/fastapi/prompt_management_fastapi_expected.py +0 -114
  223. package/tests/fixtures/fastapi/prompt_management_fastapi_input.py +0 -88
  224. package/tests/fixtures/haystack/haystack_bot_expected.py +0 -141
  225. package/tests/fixtures/haystack/haystack_bot_input.py +0 -69
  226. package/tests/fixtures/langchain/langchain_bot_expected.py +0 -53
  227. package/tests/fixtures/langchain/langchain_bot_input.py +0 -45
  228. package/tests/fixtures/langchain/langchain_bot_with_memory_expected.py +0 -69
  229. package/tests/fixtures/langchain/langchain_bot_with_memory_input.py +0 -61
  230. package/tests/fixtures/langchain/langchain_rag_bot_expected.py +0 -97
  231. package/tests/fixtures/langchain/langchain_rag_bot_input.py +0 -77
  232. package/tests/fixtures/langchain/langchain_rag_bot_vertex_ai_expected.py +0 -116
  233. package/tests/fixtures/langchain/langchain_rag_bot_vertex_ai_input.py +0 -81
  234. package/tests/fixtures/langchain/langgraph_rag_bot_with_threads_expected.py +0 -331
  235. package/tests/fixtures/langchain/langgraph_rag_bot_with_threads_input.py +0 -106
  236. package/tests/fixtures/litellm/litellm_bot_expected.py +0 -40
  237. package/tests/fixtures/litellm/litellm_bot_input.py +0 -35
  238. package/tests/fixtures/openai/openai_bot_expected.py +0 -43
  239. package/tests/fixtures/openai/openai_bot_function_call_expected.py +0 -91
  240. package/tests/fixtures/openai/openai_bot_function_call_input.py +0 -82
  241. package/tests/fixtures/openai/openai_bot_input.py +0 -36
  242. package/tests/fixtures/openai/openai_bot_rag_expected.py +0 -73
  243. package/tests/fixtures/openai/openai_bot_rag_input.py +0 -51
  244. package/tests/fixtures/opentelemetry/openinference_dspy_bot_expected.py +0 -63
  245. package/tests/fixtures/opentelemetry/openinference_dspy_bot_input.py +0 -58
  246. package/tests/fixtures/opentelemetry/openinference_langchain_bot_expected.py +0 -53
  247. package/tests/fixtures/opentelemetry/openinference_langchain_bot_input.py +0 -52
  248. package/tests/fixtures/opentelemetry/openinference_openai_bot_expected.py +0 -49
  249. package/tests/fixtures/opentelemetry/openinference_openai_bot_input.py +0 -41
  250. package/tests/fixtures/opentelemetry/openllmetry_openai_bot_expected.py +0 -44
  251. package/tests/fixtures/opentelemetry/openllmetry_openai_bot_input.py +0 -40
  252. package/tests/fixtures/strands/strands_bot_expected.py +0 -84
  253. package/tests/fixtures/strands/strands_bot_input.py +0 -52
  254. package/tests/scenario-openai.test.ts +0 -160
  255. package/tsup.config.ts +0 -14
  256. package/vitest.config.js +0 -7
@@ -1,35 +0,0 @@
1
- from typing import cast
2
- from dotenv import load_dotenv
3
-
4
- load_dotenv()
5
-
6
- import chainlit as cl
7
- import litellm
8
- from litellm import CustomStreamWrapper
9
- from litellm.types.utils import StreamingChoices
10
-
11
-
12
- @cl.on_message
13
- async def main(message: cl.Message):
14
- msg = cl.Message(
15
- content="",
16
- )
17
-
18
- response = litellm.completion(
19
- model="cerebras/gpt-oss-120b",
20
- messages=[
21
- {
22
- "role": "system",
23
- "content": "You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
24
- },
25
- {"role": "user", "content": message.content},
26
- ],
27
- stream=True,
28
- stream_options={"include_usage": True},
29
- )
30
-
31
- for part in cast(CustomStreamWrapper, response):
32
- if token := cast(StreamingChoices, part.choices[0]).delta.content or "":
33
- await msg.stream_token(token)
34
-
35
- await msg.update()
@@ -1,43 +0,0 @@
1
- from dotenv import load_dotenv
2
-
3
- load_dotenv()
4
-
5
- import chainlit as cl
6
- from openai import OpenAI
7
- import langwatch
8
-
9
- client = OpenAI()
10
-
11
-
12
- @cl.on_message
13
- @langwatch.trace()
14
- async def main(message: cl.Message):
15
- langwatch.get_current_trace().autotrack_openai_calls(client)
16
- langwatch.get_current_trace().update(
17
- metadata={"labels": ["openai"]},
18
- )
19
-
20
- msg = cl.Message(
21
- content="",
22
- )
23
-
24
- completion = client.chat.completions.create(
25
- model="gpt-5",
26
- messages=[
27
- {
28
- "role": "system",
29
- "content": "You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
30
- },
31
- {"role": "user", "content": message.content},
32
- ],
33
- stream=True,
34
- stream_options={"include_usage": True},
35
- )
36
-
37
- for part in completion:
38
- if len(part.choices) == 0:
39
- continue
40
- if token := part.choices[0].delta.content or "":
41
- await msg.stream_token(token)
42
-
43
- await msg.update()
@@ -1,91 +0,0 @@
1
- from dotenv import load_dotenv
2
-
3
- load_dotenv()
4
-
5
- import chainlit as cl
6
- from openai import OpenAI
7
-
8
- client = OpenAI()
9
-
10
- import langwatch
11
-
12
- import json
13
-
14
-
15
- @langwatch.span(type="tool")
16
- def get_weather(city: str):
17
- return "27°C and sunny"
18
-
19
-
20
- @cl.on_message
21
- @langwatch.trace()
22
- async def main(message: cl.Message):
23
- langwatch.get_current_trace().autotrack_openai_calls(client)
24
- langwatch.get_current_trace().update(
25
- metadata={"labels": ["openai", "tools"]},
26
- )
27
-
28
- msg = cl.Message(
29
- content="",
30
- )
31
-
32
- completion = client.chat.completions.create(
33
- model="gpt-5",
34
- messages=[
35
- {
36
- "role": "system",
37
- "content": "You are a helpful assistant that calls tools that gives weather predictions.",
38
- },
39
- {"role": "user", "content": message.content},
40
- ],
41
- tools=[
42
- {
43
- "type": "function",
44
- "function": {
45
- "name": "get_weather",
46
- "description": "Get the weather for a city.",
47
- "parameters": {
48
- "type": "object",
49
- "properties": {
50
- "city": {
51
- "type": "string",
52
- "description": "The city to get the weather for.",
53
- },
54
- },
55
- "required": ["city"],
56
- },
57
- },
58
- }
59
- ],
60
- tool_choice={
61
- "type": "function",
62
- "function": {
63
- "name": "get_weather",
64
- },
65
- },
66
- )
67
-
68
- tool_message = completion.choices[0].message.tool_calls[0] # type: ignore
69
- weather_call = json.loads(tool_message.function.arguments) # type: ignore
70
-
71
- weather = get_weather(weather_call["city"])
72
-
73
- completion = client.chat.completions.create(
74
- model="gpt-5",
75
- messages=[
76
- {
77
- "role": "system",
78
- "content": "You are a helpful assistant that gives weather predictions based on the tool results.",
79
- },
80
- {"role": "user", "content": message.content},
81
- completion.choices[0].message,
82
- {"tool_call_id": tool_message.id, "role": "tool", "name": tool_message.function.name, "content": weather}, # type: ignore
83
- ],
84
- stream=True,
85
- )
86
-
87
- for part in completion:
88
- if token := part.choices[0].delta.content or "":
89
- await msg.stream_token(token)
90
-
91
- await msg.update()
@@ -1,82 +0,0 @@
1
- from dotenv import load_dotenv
2
-
3
- load_dotenv()
4
-
5
- import chainlit as cl
6
- from openai import OpenAI
7
-
8
- client = OpenAI()
9
-
10
- import json
11
-
12
-
13
- def get_weather(city: str):
14
- return "27°C and sunny"
15
-
16
-
17
- @cl.on_message
18
- async def main(message: cl.Message):
19
- msg = cl.Message(
20
- content="",
21
- )
22
-
23
- completion = client.chat.completions.create(
24
- model="gpt-5",
25
- messages=[
26
- {
27
- "role": "system",
28
- "content": "You are a helpful assistant that calls tools that gives weather predictions.",
29
- },
30
- {"role": "user", "content": message.content},
31
- ],
32
- tools=[
33
- {
34
- "type": "function",
35
- "function": {
36
- "name": "get_weather",
37
- "description": "Get the weather for a city.",
38
- "parameters": {
39
- "type": "object",
40
- "properties": {
41
- "city": {
42
- "type": "string",
43
- "description": "The city to get the weather for.",
44
- },
45
- },
46
- "required": ["city"],
47
- },
48
- },
49
- }
50
- ],
51
- tool_choice={
52
- "type": "function",
53
- "function": {
54
- "name": "get_weather",
55
- },
56
- },
57
- )
58
-
59
- tool_message = completion.choices[0].message.tool_calls[0] # type: ignore
60
- weather_call = json.loads(tool_message.function.arguments) # type: ignore
61
-
62
- weather = get_weather(weather_call["city"])
63
-
64
- completion = client.chat.completions.create(
65
- model="gpt-5",
66
- messages=[
67
- {
68
- "role": "system",
69
- "content": "You are a helpful assistant that gives weather predictions based on the tool results.",
70
- },
71
- {"role": "user", "content": message.content},
72
- completion.choices[0].message,
73
- {"tool_call_id": tool_message.id, "role": "tool", "name": tool_message.function.name, "content": weather}, # type: ignore
74
- ],
75
- stream=True,
76
- )
77
-
78
- for part in completion:
79
- if token := part.choices[0].delta.content or "":
80
- await msg.stream_token(token)
81
-
82
- await msg.update()
@@ -1,36 +0,0 @@
1
- from dotenv import load_dotenv
2
-
3
- load_dotenv()
4
-
5
- import chainlit as cl
6
- from openai import OpenAI
7
-
8
- client = OpenAI()
9
-
10
-
11
- @cl.on_message
12
- async def main(message: cl.Message):
13
- msg = cl.Message(
14
- content="",
15
- )
16
-
17
- completion = client.chat.completions.create(
18
- model="gpt-5",
19
- messages=[
20
- {
21
- "role": "system",
22
- "content": "You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
23
- },
24
- {"role": "user", "content": message.content},
25
- ],
26
- stream=True,
27
- stream_options={"include_usage": True},
28
- )
29
-
30
- for part in completion:
31
- if len(part.choices) == 0:
32
- continue
33
- if token := part.choices[0].delta.content or "":
34
- await msg.stream_token(token)
35
-
36
- await msg.update()
@@ -1,73 +0,0 @@
1
- from dotenv import load_dotenv
2
-
3
- from langwatch.types import RAGChunk
4
-
5
- load_dotenv()
6
-
7
- import chainlit as cl
8
- from openai import OpenAI
9
-
10
- client = OpenAI()
11
-
12
- import langwatch.openai
13
-
14
-
15
- @langwatch.span(type="rag")
16
- def rag_retrieval(query: str):
17
- # the documents you retrieved from your vector database
18
- search_results = [
19
- {
20
- "id": "doc-1",
21
- "content": "France is a country in Europe.",
22
- },
23
- {
24
- "id": "doc-2",
25
- "content": "Paris is the capital of France.",
26
- },
27
- ]
28
-
29
- # capture then on the span contexts with RAGChunk before returning
30
- langwatch.get_current_span().update(
31
- contexts=[
32
- RAGChunk(
33
- document_id=document["id"],
34
- content=document["content"],
35
- )
36
- for document in search_results
37
- ]
38
- )
39
-
40
- return search_results
41
-
42
-
43
- @cl.on_message
44
- @langwatch.trace()
45
- async def main(message: cl.Message):
46
- langwatch.get_current_trace().autotrack_openai_calls(client)
47
- langwatch.get_current_trace().update(
48
- metadata={"labels": ["openai", "rag"]},
49
- )
50
-
51
- msg = cl.Message(
52
- content="",
53
- )
54
-
55
- contexts = rag_retrieval(message.content)
56
-
57
- completion = client.chat.completions.create(
58
- model="gpt-5",
59
- messages=[
60
- {
61
- "role": "system",
62
- "content": f"You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis. {contexts}",
63
- },
64
- {"role": "user", "content": message.content},
65
- ],
66
- stream=True,
67
- )
68
-
69
- for part in completion:
70
- if token := part.choices[0].delta.content or "":
71
- await msg.stream_token(token)
72
-
73
- await msg.update()
@@ -1,51 +0,0 @@
1
- from dotenv import load_dotenv
2
-
3
- load_dotenv()
4
-
5
- import chainlit as cl
6
- from openai import OpenAI
7
-
8
- client = OpenAI()
9
-
10
-
11
- def rag_retrieval(query: str):
12
- # the documents you retrieved from your vector database
13
- search_results = [
14
- {
15
- "id": "doc-1",
16
- "content": "France is a country in Europe.",
17
- },
18
- {
19
- "id": "doc-2",
20
- "content": "Paris is the capital of France.",
21
- },
22
- ]
23
-
24
- return search_results
25
-
26
-
27
- @cl.on_message
28
- async def main(message: cl.Message):
29
- msg = cl.Message(
30
- content="",
31
- )
32
-
33
- contexts = rag_retrieval(message.content)
34
-
35
- completion = client.chat.completions.create(
36
- model="gpt-5",
37
- messages=[
38
- {
39
- "role": "system",
40
- "content": f"You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis. {contexts}",
41
- },
42
- {"role": "user", "content": message.content},
43
- ],
44
- stream=True,
45
- )
46
-
47
- for part in completion:
48
- if token := part.choices[0].delta.content or "":
49
- await msg.stream_token(token)
50
-
51
- await msg.update()
@@ -1,63 +0,0 @@
1
- import os
2
- import dspy
3
- from dotenv import load_dotenv
4
-
5
- import langwatch
6
-
7
- load_dotenv()
8
-
9
- import chainlit as cl
10
-
11
- from openinference.instrumentation.dspy import DSPyInstrumentor
12
-
13
- langwatch.setup(
14
- instrumentors=[DSPyInstrumentor()],
15
- )
16
-
17
- llm = dspy.OpenAI(
18
- model="gpt-5",
19
- max_tokens=2048,
20
- temperature=0,
21
- api_key=os.environ["OPENAI_API_KEY"],
22
- )
23
-
24
- colbertv2_wiki17_abstracts = dspy.ColBERTv2(
25
- url="http://20.102.90.50:2017/wiki17_abstracts"
26
- )
27
-
28
- dspy.settings.configure(lm=llm, rm=colbertv2_wiki17_abstracts)
29
-
30
-
31
- class GenerateAnswer(dspy.Signature):
32
- """Answer questions with short factoid answers."""
33
-
34
- context = dspy.InputField(desc="may contain relevant facts")
35
- question = dspy.InputField()
36
- answer = dspy.OutputField(desc="often between 1 and 5 words")
37
-
38
-
39
- class RAG(dspy.Module):
40
- def __init__(self, num_passages=3):
41
- super().__init__()
42
-
43
- self.retrieve = dspy.Retrieve(k=num_passages)
44
- self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
45
-
46
- def forward(self, question):
47
- context = self.retrieve(question).passages # type: ignore
48
- prediction = self.generate_answer(question=question, context=context)
49
- return dspy.Prediction(answer=prediction.answer)
50
-
51
-
52
- @cl.on_message
53
- async def main(message: cl.Message):
54
- msg = cl.Message(
55
- content="",
56
- )
57
-
58
- program = RAG()
59
- program = program.reset_copy()
60
- prediction = program(question=message.content)
61
-
62
- await msg.stream_token(prediction.answer)
63
- await msg.update()
@@ -1,58 +0,0 @@
1
- # This example uses the OpenTelemetry instrumentation for DSPy from OpenInference
2
-
3
- import os
4
- from dotenv import load_dotenv
5
-
6
- load_dotenv()
7
-
8
- import chainlit as cl
9
-
10
- import dspy
11
- from openinference.instrumentation.dspy import DSPyInstrumentor
12
-
13
- # Manual instrumentation setup would go here
14
- DSPyInstrumentor().instrument()
15
-
16
- lm = dspy.LM("openai/gpt-5", api_key=os.environ["OPENAI_API_KEY"], temperature=1)
17
-
18
- colbertv2_wiki17_abstracts = dspy.ColBERTv2(
19
- url="http://20.102.90.50:2017/wiki17_abstracts"
20
- )
21
-
22
- dspy.settings.configure(lm=lm, rm=colbertv2_wiki17_abstracts)
23
-
24
-
25
- class GenerateAnswer(dspy.Signature):
26
- """Answer questions with careful explanations to the user."""
27
-
28
- context = dspy.InputField(desc="may contain relevant facts")
29
- question = dspy.InputField()
30
- answer = dspy.OutputField(desc="markdown formatted answer, use some emojis")
31
-
32
-
33
- class RAG(dspy.Module):
34
- def __init__(self, num_passages=3):
35
- super().__init__()
36
-
37
- self.retrieve = dspy.Retrieve(k=num_passages)
38
- self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
39
-
40
- def forward(self, question):
41
- context = self.retrieve(question).passages # type: ignore
42
- prediction = self.generate_answer(question=question, context=context)
43
- return dspy.Prediction(answer=prediction.answer)
44
-
45
-
46
- @cl.on_message
47
- async def main(message: cl.Message):
48
- msg = cl.Message(
49
- content="",
50
- )
51
-
52
- program = RAG()
53
- prediction = program(question=message.content)
54
-
55
- await msg.stream_token(prediction.answer)
56
- await msg.update()
57
-
58
- return prediction.answer
@@ -1,53 +0,0 @@
1
- from dotenv import load_dotenv
2
- from langchain_openai import ChatOpenAI
3
-
4
- import langwatch
5
-
6
- load_dotenv()
7
-
8
- import chainlit as cl
9
- from langchain.prompts import ChatPromptTemplate
10
- from langchain.schema import StrOutputParser
11
- from langchain.schema.runnable import Runnable
12
- from langchain.schema.runnable.config import RunnableConfig
13
-
14
- from openinference.instrumentation.langchain import LangChainInstrumentor
15
-
16
- langwatch.setup(
17
- instrumentors=[LangChainInstrumentor()],
18
- )
19
-
20
-
21
- @cl.on_chat_start
22
- async def on_chat_start():
23
- model = ChatOpenAI(streaming=True)
24
- prompt = ChatPromptTemplate.from_messages(
25
- [
26
- (
27
- "system",
28
- "You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
29
- ),
30
- ("human", "{question}"),
31
- ]
32
- )
33
- runnable = prompt | model | StrOutputParser()
34
- cl.user_session.set("runnable", runnable)
35
-
36
-
37
- @cl.on_message
38
- async def main(message: cl.Message):
39
- runnable: Runnable = cl.user_session.get("runnable") # type: ignore
40
-
41
- msg = cl.Message(content="")
42
-
43
- async for chunk in runnable.astream(
44
- {"question": message.content},
45
- config=RunnableConfig(
46
- callbacks=[
47
- cl.LangchainCallbackHandler(),
48
- ]
49
- ),
50
- ):
51
- await msg.stream_token(chunk)
52
-
53
- await msg.send()
@@ -1,52 +0,0 @@
1
- # This example uses the OpenTelemetry instrumentation for LangChain from OpenInference
2
-
3
- from dotenv import load_dotenv
4
- from langchain_openai import ChatOpenAI
5
-
6
- load_dotenv()
7
-
8
- import chainlit as cl
9
- from langchain.prompts import ChatPromptTemplate
10
- from langchain.schema import StrOutputParser
11
- from langchain.schema.runnable import Runnable
12
- from langchain.schema.runnable.config import RunnableConfig
13
-
14
- from openinference.instrumentation.langchain import LangChainInstrumentor
15
-
16
- # Manual instrumentation setup would go here
17
- LangChainInstrumentor().instrument()
18
-
19
-
20
- @cl.on_chat_start
21
- async def on_chat_start():
22
- model = ChatOpenAI(streaming=True)
23
- prompt = ChatPromptTemplate.from_messages(
24
- [
25
- (
26
- "system",
27
- "You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
28
- ),
29
- ("human", "{question}"),
30
- ]
31
- )
32
- runnable = prompt | model | StrOutputParser()
33
- cl.user_session.set("runnable", runnable)
34
-
35
-
36
- @cl.on_message
37
- async def main(message: cl.Message):
38
- runnable: Runnable = cl.user_session.get("runnable") # type: ignore
39
-
40
- msg = cl.Message(content="")
41
-
42
- async for chunk in runnable.astream(
43
- {"question": message.content},
44
- config=RunnableConfig(
45
- callbacks=[
46
- cl.LangchainCallbackHandler(),
47
- ]
48
- ),
49
- ):
50
- await msg.stream_token(chunk)
51
-
52
- await msg.send()
@@ -1,49 +0,0 @@
1
- # This example uses the OpenTelemetry instrumentation for OpenAI from OpenInference: https://pypi.org/project/openinference-instrumentation-openai/
2
-
3
- from dotenv import load_dotenv
4
-
5
- import langwatch
6
-
7
- load_dotenv()
8
-
9
- import chainlit as cl
10
-
11
- from openinference.instrumentation.openai import OpenAIInstrumentor
12
- from openinference.instrumentation import using_attributes
13
- from openai import OpenAI
14
-
15
- client = OpenAI()
16
- langwatch.setup(
17
- instrumentors=[OpenAIInstrumentor()],
18
- )
19
-
20
-
21
- @cl.on_message
22
- async def main(message: cl.Message):
23
- msg = cl.Message(
24
- content="",
25
- )
26
-
27
- with using_attributes(
28
- session_id="my-test-session",
29
- user_id="my-test-user",
30
- tags=["tag-1", "tag-2"],
31
- metadata={"foo": "bar"},
32
- ):
33
- completion = client.chat.completions.create(
34
- model="gpt-5",
35
- messages=[
36
- {
37
- "role": "system",
38
- "content": "You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
39
- },
40
- {"role": "user", "content": message.content},
41
- ],
42
- stream=True,
43
- )
44
-
45
- for part in completion:
46
- if token := part.choices[0].delta.content or "":
47
- await msg.stream_token(token)
48
-
49
- await msg.update()