@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.
- package/.release-please-shim +1 -0
- package/CHANGELOG.md +87 -0
- package/LICENSE +7 -0
- package/dist/archive-project-HZBRPR2S.js +19 -0
- package/dist/{archive-scenario-WJ2A7ETN.js → archive-scenario-P5RRITRM.js} +4 -4
- package/dist/{archive-suite-4JOM4SSL.js → archive-suite-NUUFD2EM.js} +4 -4
- package/dist/{assign-prompt-tag-GL7EAAF3.js → assign-prompt-tag-FKCCZPML.js} +3 -3
- package/dist/{chunk-2WPLXEKF.js → chunk-42ZHHHIJ.js} +20 -5
- package/dist/chunk-ADSJ2FDA.js +44 -0
- package/dist/{chunk-IE4M5OGE.js → chunk-BB7EOKHR.js} +2 -2
- package/dist/chunk-BBJ5WAJB.js +24 -0
- package/dist/{chunk-EGH5RPXM.js → chunk-BYWYM2RP.js} +2 -2
- package/dist/{chunk-2GT7IFWK.js → chunk-CCM4ZFGF.js} +2 -2
- package/dist/{chunk-LUMEZEHL.js → chunk-CHKCEZBP.js} +2 -2
- package/dist/{chunk-ZVS4UKN2.js → chunk-HKY3GW45.js} +2 -2
- package/dist/{chunk-EUQDVOSU.js → chunk-JHOSVOHT.js} +2 -2
- package/dist/{chunk-E5JYYU3J.js → chunk-JVLJKQJG.js} +669 -94
- package/dist/{chunk-BWWY5KEF.js → chunk-KOO5733S.js} +3 -2
- package/dist/{chunk-HYMIWO3U.js → chunk-R7C7OUVG.js} +2 -2
- package/dist/{chunk-WQG2DFHX.js → chunk-TROIWSEQ.js} +2 -2
- package/dist/{chunk-CCWCIJJ3.js → chunk-X2SEURT2.js} +2 -2
- package/dist/{chunk-4AUB2BIA.js → chunk-XC62KJIT.js} +3 -3
- package/dist/config.js +1 -1
- package/dist/{create-agent-MBOOT3XK.js → create-agent-K5Q7BFGZ.js} +4 -4
- package/dist/{create-annotation-XMV6A7ED.js → create-annotation-KN3GE3DK.js} +4 -4
- package/dist/create-api-key-OQI5PUNQ.js +26 -0
- package/dist/{create-dashboard-VRKLFVZJ.js → create-dashboard-G4QA5AXP.js} +4 -4
- package/dist/{create-dataset-7HQPZCRE.js → create-dataset-WQSC37N7.js} +4 -4
- package/dist/{create-dataset-records-2NIVFYTV.js → create-dataset-records-B4RL3FLC.js} +4 -4
- package/dist/{create-evaluator-WYFRFLRC.js → create-evaluator-YFFQIR7E.js} +4 -4
- package/dist/create-mcp-server.js +3 -2
- package/dist/create-project-CUVQ67VN.js +44 -0
- package/dist/{create-prompt-IEN7O6JT.js → create-prompt-NGXKSP4X.js} +3 -3
- package/dist/{create-prompt-tag-CAEZ45VO.js → create-prompt-tag-IUKYPVHH.js} +3 -3
- package/dist/{create-scenario-6YHSMGLP.js → create-scenario-FNBXALH3.js} +4 -4
- package/dist/{create-suite-H5XOFDE5.js → create-suite-DJEPD4ZB.js} +4 -4
- package/dist/{delete-agent-JKTNBWAA.js → delete-agent-TJI5XBBM.js} +4 -4
- package/dist/{delete-annotation-ACMDV6QO.js → delete-annotation-KRP53TUU.js} +4 -4
- package/dist/{delete-dashboard-VJSR7CRU.js → delete-dashboard-N5SZJIR3.js} +4 -4
- package/dist/{delete-dataset-RTTTWP4D.js → delete-dataset-KDUOHL2P.js} +4 -4
- package/dist/{delete-dataset-records-KNQTIPQK.js → delete-dataset-records-DM4W3PAW.js} +4 -4
- package/dist/{delete-evaluator-7FVC5WM4.js → delete-evaluator-7ZATLJOA.js} +4 -4
- package/dist/{delete-prompt-tag-ZMZUAGFW.js → delete-prompt-tag-I6HNMSVJ.js} +3 -3
- package/dist/{delete-workflow-EYQ3T4RQ.js → delete-workflow-QEO74JQR.js} +4 -4
- package/dist/{get-agent-E3QSTVKG.js → get-agent-3KDWCP5N.js} +4 -4
- package/dist/{get-analytics-2OHV763I.js → get-analytics-GPVJX7SF.js} +3 -3
- package/dist/{get-dashboard-PC7JDHH6.js → get-dashboard-YPTIE5YY.js} +4 -4
- package/dist/{get-dataset-H5IK5FVU.js → get-dataset-6DQFYITM.js} +4 -4
- package/dist/{get-evaluator-UWVUPYTM.js → get-evaluator-PCM6XQAU.js} +4 -4
- package/dist/get-project-JCMWXVLU.js +26 -0
- package/dist/{get-prompt-WZUOLLQC.js → get-prompt-5XAGWWBG.js} +3 -3
- package/dist/{get-scenario-Q6LCNUYN.js → get-scenario-7XBCDZWX.js} +4 -4
- package/dist/{get-simulation-run-Z2XKO256.js → get-simulation-run-AV24FJWI.js} +4 -4
- package/dist/{get-suite-BXK5TN7P.js → get-suite-4DBVHFEM.js} +4 -4
- package/dist/{get-trace-4EJAYVBG.js → get-trace-MRBDS3HJ.js} +3 -3
- package/dist/{get-workflow-O34QJLHD.js → get-workflow-UR4Y6UFX.js} +4 -4
- package/dist/{http-server-ISHF7NJX.js → http-server-DEGNV5EP.js} +4 -3
- package/dist/index.js +1453 -431
- package/dist/{langwatch-api-annotations-ERBG27RF.js → langwatch-api-annotations-ZJDRB4JH.js} +4 -4
- package/dist/{langwatch-api-dashboards-G6TR7VVO.js → langwatch-api-dashboards-WARLI6NF.js} +4 -4
- package/dist/{langwatch-api-monitors-WSXZLS2B.js → langwatch-api-monitors-4XKXHYCG.js} +3 -3
- package/dist/{langwatch-api-secrets-RR5DKG2X.js → langwatch-api-secrets-6SHK5G7Q.js} +3 -3
- package/dist/{langwatch-api-triggers-2RTNSWQY.js → langwatch-api-triggers-5SX6R2WU.js} +3 -3
- package/dist/langwatch-api-workflows-NLJENNXE.js +15 -0
- package/dist/{list-agents-AW3P6FJV.js → list-agents-NECO7MPI.js} +4 -4
- package/dist/{list-annotations-QNCGWPQ3.js → list-annotations-3OJEO774.js} +4 -4
- package/dist/list-api-keys-AWW7ROLB.js +37 -0
- package/dist/{list-dashboards-R7RK2IXL.js → list-dashboards-DVPVVVKW.js} +4 -4
- package/dist/{list-dataset-records-WVCSQP7P.js → list-dataset-records-I4BYORF5.js} +4 -4
- package/dist/{list-datasets-KEXRLDEU.js → list-datasets-WUAE5HGX.js} +4 -4
- package/dist/{list-evaluators-7R2LB4JH.js → list-evaluators-B6OSVAM2.js} +4 -4
- package/dist/{list-model-providers-OBYJCKBX.js → list-model-providers-NL6IP4UZ.js} +4 -4
- package/dist/list-projects-5FHMJ4PQ.js +42 -0
- package/dist/{list-prompt-tags-6LY3ZPYI.js → list-prompt-tags-Z2DD6FLQ.js} +3 -3
- package/dist/{list-prompts-VWEZ4CDE.js → list-prompts-VNXKHK7T.js} +3 -3
- package/dist/{list-scenarios-TXD4W2ZJ.js → list-scenarios-CFZHXL76.js} +4 -4
- package/dist/{list-simulation-runs-RHPOLMFI.js → list-simulation-runs-AM2BXLBW.js} +4 -4
- package/dist/{list-suites-FSGBX27Z.js → list-suites-ZDOHAAXF.js} +4 -4
- package/dist/{list-workflows-VRGEZ3EN.js → list-workflows-WBRBKLIT.js} +4 -4
- package/dist/{rename-prompt-tag-VOJJLX4M.js → rename-prompt-tag-A4RJUK7Z.js} +3 -3
- package/dist/revoke-api-key-ZSPSPF5G.js +15 -0
- package/dist/{run-agent-KTCC7TB7.js → run-agent-JFNDY7MR.js} +4 -4
- package/dist/{run-suite-BTMHGI2D.js → run-suite-TH7LO5TJ.js} +4 -4
- package/dist/{run-workflow-IGAYGKJL.js → run-workflow-CK3JP5U2.js} +4 -4
- package/dist/{search-traces-VYFUIMXH.js → search-traces-3BBVYPC3.js} +3 -3
- package/dist/{set-model-provider-W5IUI326.js → set-model-provider-WOC5FNMV.js} +4 -4
- package/dist/{update-agent-4BB7EYLR.js → update-agent-YMEV5MTL.js} +4 -4
- package/dist/{update-dataset-CXBKZ4W3.js → update-dataset-EYT5POFM.js} +4 -4
- package/dist/{update-dataset-record-HOHAMHXG.js → update-dataset-record-VFF5JTX4.js} +4 -4
- package/dist/{update-evaluator-IVOR6FTR.js → update-evaluator-6IJHFG2E.js} +4 -4
- package/dist/update-project-OIT4WPFI.js +24 -0
- package/dist/{update-prompt-OWQAKE7K.js → update-prompt-ZU2DD6KM.js} +3 -3
- package/dist/{update-scenario-GDFVILPN.js → update-scenario-3VUTPDRU.js} +4 -4
- package/dist/{update-suite-BXYUYSPT.js → update-suite-C6JFDQHL.js} +4 -4
- package/package.json +7 -7
- package/pnpm-workspace.yaml +2 -0
- package/pyproject.toml +3 -0
- package/src/__tests__/all-tools.integration.test.ts +9 -0
- package/src/__tests__/datasets.integration.test.ts +17 -0
- package/src/__tests__/datasets.unit.test.ts +4 -0
- package/src/__tests__/experiment-list-tools.unit.test.ts +157 -0
- package/src/__tests__/get-experiment-results.unit.test.ts +222 -0
- package/src/__tests__/project-api-key-tools.unit.test.ts +451 -0
- package/src/__tests__/scenario-tools.unit.test.ts +3 -0
- package/src/config.ts +2 -0
- package/src/create-mcp-server.ts +257 -13
- package/src/langwatch-api-api-keys.ts +54 -0
- package/src/langwatch-api-projects.ts +82 -0
- package/src/langwatch-api.ts +22 -4
- package/src/tools/archive-project.ts +14 -0
- package/src/tools/create-api-key.ts +29 -0
- package/src/tools/create-project.ts +45 -0
- package/src/tools/get-experiment-results.ts +273 -0
- package/src/tools/get-project.ts +20 -0
- package/src/tools/list-api-keys.ts +33 -0
- package/src/tools/list-experiment-runs.ts +142 -0
- package/src/tools/list-experiments.ts +95 -0
- package/src/tools/list-projects.ts +41 -0
- package/src/tools/revoke-api-key.ts +9 -0
- package/src/tools/{run-evaluation.ts → run-experiment.ts} +5 -5
- package/src/tools/update-project.ts +22 -0
- package/uv.lock +192 -530
- package/Dockerfile +0 -22
- package/build.js +0 -12
- package/dist/archive-scenario-WJ2A7ETN.js.map +0 -1
- package/dist/archive-suite-4JOM4SSL.js.map +0 -1
- package/dist/assign-prompt-tag-GL7EAAF3.js.map +0 -1
- package/dist/chunk-2GT7IFWK.js.map +0 -1
- package/dist/chunk-2WPLXEKF.js.map +0 -1
- package/dist/chunk-4AUB2BIA.js.map +0 -1
- package/dist/chunk-BWWY5KEF.js.map +0 -1
- package/dist/chunk-CCWCIJJ3.js.map +0 -1
- package/dist/chunk-E5JYYU3J.js.map +0 -1
- package/dist/chunk-EGH5RPXM.js.map +0 -1
- package/dist/chunk-EUQDVOSU.js.map +0 -1
- package/dist/chunk-HYMIWO3U.js.map +0 -1
- package/dist/chunk-IE4M5OGE.js.map +0 -1
- package/dist/chunk-LUMEZEHL.js.map +0 -1
- package/dist/chunk-NUFPTHKU.js.map +0 -1
- package/dist/chunk-WQG2DFHX.js.map +0 -1
- package/dist/chunk-WVI5CJ6S.js.map +0 -1
- package/dist/chunk-ZVS4UKN2.js.map +0 -1
- package/dist/chunk-ZXKLPC2E.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/create-agent-MBOOT3XK.js.map +0 -1
- package/dist/create-annotation-XMV6A7ED.js.map +0 -1
- package/dist/create-dashboard-VRKLFVZJ.js.map +0 -1
- package/dist/create-dataset-7HQPZCRE.js.map +0 -1
- package/dist/create-dataset-records-2NIVFYTV.js.map +0 -1
- package/dist/create-evaluator-WYFRFLRC.js.map +0 -1
- package/dist/create-mcp-server.js.map +0 -1
- package/dist/create-prompt-IEN7O6JT.js.map +0 -1
- package/dist/create-prompt-tag-CAEZ45VO.js.map +0 -1
- package/dist/create-scenario-6YHSMGLP.js.map +0 -1
- package/dist/create-suite-H5XOFDE5.js.map +0 -1
- package/dist/delete-agent-JKTNBWAA.js.map +0 -1
- package/dist/delete-annotation-ACMDV6QO.js.map +0 -1
- package/dist/delete-dashboard-VJSR7CRU.js.map +0 -1
- package/dist/delete-dataset-RTTTWP4D.js.map +0 -1
- package/dist/delete-dataset-records-KNQTIPQK.js.map +0 -1
- package/dist/delete-evaluator-7FVC5WM4.js.map +0 -1
- package/dist/delete-prompt-tag-ZMZUAGFW.js.map +0 -1
- package/dist/delete-workflow-EYQ3T4RQ.js.map +0 -1
- package/dist/discover-evaluator-schema-H23XCLNE.js.map +0 -1
- package/dist/discover-scenario-schema-MEEEVND7.js.map +0 -1
- package/dist/discover-schema-3T52ORPB.js.map +0 -1
- package/dist/get-agent-E3QSTVKG.js.map +0 -1
- package/dist/get-analytics-2OHV763I.js.map +0 -1
- package/dist/get-dashboard-PC7JDHH6.js.map +0 -1
- package/dist/get-dataset-H5IK5FVU.js.map +0 -1
- package/dist/get-evaluator-UWVUPYTM.js.map +0 -1
- package/dist/get-prompt-WZUOLLQC.js.map +0 -1
- package/dist/get-scenario-Q6LCNUYN.js.map +0 -1
- package/dist/get-simulation-run-Z2XKO256.js.map +0 -1
- package/dist/get-suite-BXK5TN7P.js.map +0 -1
- package/dist/get-trace-4EJAYVBG.js.map +0 -1
- package/dist/get-workflow-O34QJLHD.js.map +0 -1
- package/dist/http-server-ISHF7NJX.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/langwatch-api-annotations-ERBG27RF.js.map +0 -1
- package/dist/langwatch-api-dashboards-G6TR7VVO.js.map +0 -1
- package/dist/langwatch-api-monitors-WSXZLS2B.js.map +0 -1
- package/dist/langwatch-api-secrets-RR5DKG2X.js.map +0 -1
- package/dist/langwatch-api-triggers-2RTNSWQY.js.map +0 -1
- package/dist/langwatch-api-workflows-VJRIIDZ7.js +0 -15
- package/dist/langwatch-api-workflows-VJRIIDZ7.js.map +0 -1
- package/dist/list-agents-AW3P6FJV.js.map +0 -1
- package/dist/list-annotations-QNCGWPQ3.js.map +0 -1
- package/dist/list-dashboards-R7RK2IXL.js.map +0 -1
- package/dist/list-dataset-records-WVCSQP7P.js.map +0 -1
- package/dist/list-datasets-KEXRLDEU.js.map +0 -1
- package/dist/list-evaluators-7R2LB4JH.js.map +0 -1
- package/dist/list-model-providers-OBYJCKBX.js.map +0 -1
- package/dist/list-prompt-tags-6LY3ZPYI.js.map +0 -1
- package/dist/list-prompts-VWEZ4CDE.js.map +0 -1
- package/dist/list-scenarios-TXD4W2ZJ.js.map +0 -1
- package/dist/list-simulation-runs-RHPOLMFI.js.map +0 -1
- package/dist/list-suites-FSGBX27Z.js.map +0 -1
- package/dist/list-workflows-VRGEZ3EN.js.map +0 -1
- package/dist/rename-prompt-tag-VOJJLX4M.js.map +0 -1
- package/dist/run-agent-KTCC7TB7.js.map +0 -1
- package/dist/run-evaluation-2X3V3Q6L.js +0 -64
- package/dist/run-evaluation-2X3V3Q6L.js.map +0 -1
- package/dist/run-suite-BTMHGI2D.js.map +0 -1
- package/dist/run-workflow-IGAYGKJL.js.map +0 -1
- package/dist/search-traces-VYFUIMXH.js.map +0 -1
- package/dist/set-model-provider-W5IUI326.js.map +0 -1
- package/dist/update-agent-4BB7EYLR.js.map +0 -1
- package/dist/update-dataset-CXBKZ4W3.js.map +0 -1
- package/dist/update-dataset-record-HOHAMHXG.js.map +0 -1
- package/dist/update-evaluator-IVOR6FTR.js.map +0 -1
- package/dist/update-prompt-OWQAKE7K.js.map +0 -1
- package/dist/update-scenario-GDFVILPN.js.map +0 -1
- package/dist/update-suite-BXYUYSPT.js.map +0 -1
- package/tests/evaluations.ipynb +0 -649
- package/tests/fixtures/azure/azure_openai_stream_bot_expected.py +0 -102
- package/tests/fixtures/azure/azure_openai_stream_bot_input.py +0 -78
- package/tests/fixtures/dspy/dspy_bot_expected.py +0 -61
- package/tests/fixtures/dspy/dspy_bot_input.py +0 -53
- package/tests/fixtures/fastapi/fastapi_app_expected.py +0 -68
- package/tests/fixtures/fastapi/fastapi_app_input.py +0 -60
- package/tests/fixtures/fastapi/prompt_management_fastapi_expected.py +0 -114
- package/tests/fixtures/fastapi/prompt_management_fastapi_input.py +0 -88
- package/tests/fixtures/haystack/haystack_bot_expected.py +0 -141
- package/tests/fixtures/haystack/haystack_bot_input.py +0 -69
- package/tests/fixtures/langchain/langchain_bot_expected.py +0 -53
- package/tests/fixtures/langchain/langchain_bot_input.py +0 -45
- package/tests/fixtures/langchain/langchain_bot_with_memory_expected.py +0 -69
- package/tests/fixtures/langchain/langchain_bot_with_memory_input.py +0 -61
- package/tests/fixtures/langchain/langchain_rag_bot_expected.py +0 -97
- package/tests/fixtures/langchain/langchain_rag_bot_input.py +0 -77
- package/tests/fixtures/langchain/langchain_rag_bot_vertex_ai_expected.py +0 -116
- package/tests/fixtures/langchain/langchain_rag_bot_vertex_ai_input.py +0 -81
- package/tests/fixtures/langchain/langgraph_rag_bot_with_threads_expected.py +0 -331
- package/tests/fixtures/langchain/langgraph_rag_bot_with_threads_input.py +0 -106
- package/tests/fixtures/litellm/litellm_bot_expected.py +0 -40
- package/tests/fixtures/litellm/litellm_bot_input.py +0 -35
- package/tests/fixtures/openai/openai_bot_expected.py +0 -43
- package/tests/fixtures/openai/openai_bot_function_call_expected.py +0 -91
- package/tests/fixtures/openai/openai_bot_function_call_input.py +0 -82
- package/tests/fixtures/openai/openai_bot_input.py +0 -36
- package/tests/fixtures/openai/openai_bot_rag_expected.py +0 -73
- package/tests/fixtures/openai/openai_bot_rag_input.py +0 -51
- package/tests/fixtures/opentelemetry/openinference_dspy_bot_expected.py +0 -63
- package/tests/fixtures/opentelemetry/openinference_dspy_bot_input.py +0 -58
- package/tests/fixtures/opentelemetry/openinference_langchain_bot_expected.py +0 -53
- package/tests/fixtures/opentelemetry/openinference_langchain_bot_input.py +0 -52
- package/tests/fixtures/opentelemetry/openinference_openai_bot_expected.py +0 -49
- package/tests/fixtures/opentelemetry/openinference_openai_bot_input.py +0 -41
- package/tests/fixtures/opentelemetry/openllmetry_openai_bot_expected.py +0 -44
- package/tests/fixtures/opentelemetry/openllmetry_openai_bot_input.py +0 -40
- package/tests/fixtures/strands/strands_bot_expected.py +0 -84
- package/tests/fixtures/strands/strands_bot_input.py +0 -52
- package/tests/scenario-openai.test.ts +0 -160
- package/tsup.config.ts +0 -14
- package/vitest.config.js +0 -7
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from dotenv import load_dotenv
|
|
3
|
-
|
|
4
|
-
from langwatch.types import RAGChunk
|
|
5
|
-
|
|
6
|
-
load_dotenv()
|
|
7
|
-
|
|
8
|
-
import chainlit as cl
|
|
9
|
-
|
|
10
|
-
from haystack import Pipeline, Document, component
|
|
11
|
-
from haystack.utils import Secret
|
|
12
|
-
from haystack.document_stores.in_memory import InMemoryDocumentStore
|
|
13
|
-
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
|
|
14
|
-
from haystack.components.generators import OpenAIGenerator
|
|
15
|
-
from haystack.components.builders.prompt_builder import PromptBuilder
|
|
16
|
-
|
|
17
|
-
import os
|
|
18
|
-
import langwatch
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# Haystack pipeline
|
|
22
|
-
|
|
23
|
-
# Write documents to InMemoryDocumentStore
|
|
24
|
-
document_store = InMemoryDocumentStore()
|
|
25
|
-
document_store.write_documents(
|
|
26
|
-
[
|
|
27
|
-
Document(content="My name is Jean and I live in Paris."),
|
|
28
|
-
Document(content="My name is Mark and I live in Berlin."),
|
|
29
|
-
Document(content="My name is Giorgio and I live in Rome."),
|
|
30
|
-
]
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
# Build a RAG pipeline
|
|
34
|
-
prompt_template = """
|
|
35
|
-
Given these documents, answer the question.
|
|
36
|
-
Documents:
|
|
37
|
-
{% for doc in documents %}
|
|
38
|
-
{{ doc.content }}
|
|
39
|
-
{% endfor %}
|
|
40
|
-
Question: {{question}}
|
|
41
|
-
Answer:
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class TrackedInMemoryBM25Retriever(InMemoryBM25Retriever):
|
|
46
|
-
@langwatch.span(type="rag")
|
|
47
|
-
@component.output_types(documents=List[Document])
|
|
48
|
-
def run(self, query: str, **kwargs):
|
|
49
|
-
results = super().run(query, **kwargs)
|
|
50
|
-
langwatch.get_current_span().update(
|
|
51
|
-
contexts=[
|
|
52
|
-
RAGChunk(
|
|
53
|
-
document_id=document.id,
|
|
54
|
-
content=document.content or "",
|
|
55
|
-
)
|
|
56
|
-
for document in results["documents"]
|
|
57
|
-
]
|
|
58
|
-
)
|
|
59
|
-
return results
|
|
60
|
-
|
|
61
|
-
@component.output_types(documents=List[Document])
|
|
62
|
-
async def run_async(self, query: str, **kwargs):
|
|
63
|
-
return self.run(query, **kwargs)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
retriever = TrackedInMemoryBM25Retriever(document_store=document_store)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class TrackedPromptBuilder(PromptBuilder):
|
|
70
|
-
@langwatch.span()
|
|
71
|
-
@component.output_types(prompt=str)
|
|
72
|
-
def run(self, template=None, template_variables=None, **kwargs):
|
|
73
|
-
return super().run(template, template_variables, **kwargs)
|
|
74
|
-
|
|
75
|
-
@component.output_types(prompt=str)
|
|
76
|
-
async def run_async(self, template=None, template_variables=None, **kwargs):
|
|
77
|
-
return self.run(template, template_variables, **kwargs)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
prompt_builder = TrackedPromptBuilder(template=prompt_template)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
class TrackedOpenAIGenerator(OpenAIGenerator):
|
|
84
|
-
@langwatch.span(type="llm")
|
|
85
|
-
def run(self, prompt: str, **kwargs):
|
|
86
|
-
result = super().run(prompt, **kwargs)
|
|
87
|
-
langwatch.get_current_span().update(
|
|
88
|
-
model=self.model,
|
|
89
|
-
output=result["replies"][0],
|
|
90
|
-
metrics={
|
|
91
|
-
"prompt_tokens": result["meta"][0]["usage"]["prompt_tokens"],
|
|
92
|
-
"completion_tokens": result["meta"][0]["usage"]["completion_tokens"],
|
|
93
|
-
},
|
|
94
|
-
)
|
|
95
|
-
return result
|
|
96
|
-
|
|
97
|
-
async def run_async(self, prompt: str, **kwargs):
|
|
98
|
-
return self.run(prompt, **kwargs)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
llm = TrackedOpenAIGenerator(
|
|
102
|
-
api_key=Secret.from_token(os.environ["OPENAI_API_KEY"]), model="gpt-5"
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
rag_pipeline = Pipeline()
|
|
106
|
-
rag_pipeline.add_component("retriever", retriever)
|
|
107
|
-
rag_pipeline.add_component("prompt_builder", prompt_builder)
|
|
108
|
-
rag_pipeline.add_component("llm", llm)
|
|
109
|
-
rag_pipeline.connect("retriever", "prompt_builder.documents")
|
|
110
|
-
rag_pipeline.connect("prompt_builder", "llm")
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
@cl.on_message
|
|
114
|
-
@langwatch.trace()
|
|
115
|
-
async def main(message: cl.Message):
|
|
116
|
-
langwatch.get_current_trace().update(
|
|
117
|
-
metadata={"labels": ["haystack", "rag"]},
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
msg = cl.Message(
|
|
121
|
-
content="",
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
langwatch.get_current_trace().update(
|
|
125
|
-
metadata={
|
|
126
|
-
"thread_id": message.thread_id,
|
|
127
|
-
"user_id": "my-test-user",
|
|
128
|
-
"tags": ["User relevant question", "Second tag example"],
|
|
129
|
-
"metadata": {"foo": "bar"},
|
|
130
|
-
}
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
results = rag_pipeline.run(
|
|
134
|
-
{
|
|
135
|
-
"retriever": {"query": message.content},
|
|
136
|
-
"prompt_builder": {"question": message.content},
|
|
137
|
-
}
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
msg.content = results["llm"]["replies"][0]
|
|
141
|
-
await msg.send()
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
from dotenv import load_dotenv
|
|
3
|
-
|
|
4
|
-
load_dotenv()
|
|
5
|
-
|
|
6
|
-
import chainlit as cl
|
|
7
|
-
|
|
8
|
-
from haystack import Pipeline, Document, component
|
|
9
|
-
from haystack.utils import Secret
|
|
10
|
-
from haystack.document_stores.in_memory import InMemoryDocumentStore
|
|
11
|
-
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
|
|
12
|
-
from haystack.components.generators import OpenAIGenerator
|
|
13
|
-
from haystack.components.builders.prompt_builder import PromptBuilder
|
|
14
|
-
|
|
15
|
-
import os
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# Haystack pipeline
|
|
19
|
-
|
|
20
|
-
# Write documents to InMemoryDocumentStore
|
|
21
|
-
document_store = InMemoryDocumentStore()
|
|
22
|
-
document_store.write_documents(
|
|
23
|
-
[
|
|
24
|
-
Document(content="My name is Jean and I live in Paris."),
|
|
25
|
-
Document(content="My name is Mark and I live in Berlin."),
|
|
26
|
-
Document(content="My name is Giorgio and I live in Rome."),
|
|
27
|
-
]
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
# Build a RAG pipeline
|
|
31
|
-
prompt_template = """
|
|
32
|
-
Given these documents, answer the question.
|
|
33
|
-
Documents:
|
|
34
|
-
{% for doc in documents %}
|
|
35
|
-
{{ doc.content }}
|
|
36
|
-
{% endfor %}
|
|
37
|
-
Question: {{question}}
|
|
38
|
-
Answer:
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
retriever = InMemoryBM25Retriever(document_store=document_store)
|
|
42
|
-
prompt_builder = PromptBuilder(template=prompt_template)
|
|
43
|
-
llm = OpenAIGenerator(
|
|
44
|
-
api_key=Secret.from_token(os.environ["OPENAI_API_KEY"]), model="gpt-5"
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
rag_pipeline = Pipeline()
|
|
48
|
-
rag_pipeline.add_component("retriever", retriever)
|
|
49
|
-
rag_pipeline.add_component("prompt_builder", prompt_builder)
|
|
50
|
-
rag_pipeline.add_component("llm", llm)
|
|
51
|
-
rag_pipeline.connect("retriever", "prompt_builder.documents")
|
|
52
|
-
rag_pipeline.connect("prompt_builder", "llm")
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@cl.on_message
|
|
56
|
-
async def main(message: cl.Message):
|
|
57
|
-
msg = cl.Message(
|
|
58
|
-
content="",
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
results = rag_pipeline.run(
|
|
62
|
-
{
|
|
63
|
-
"retriever": {"query": message.content},
|
|
64
|
-
"prompt_builder": {"question": message.content},
|
|
65
|
-
}
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
msg.content = results["llm"]["replies"][0]
|
|
69
|
-
await msg.send()
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
from dotenv import load_dotenv
|
|
2
|
-
from langchain_openai import ChatOpenAI
|
|
3
|
-
|
|
4
|
-
load_dotenv()
|
|
5
|
-
|
|
6
|
-
import chainlit as cl
|
|
7
|
-
from langchain.prompts import ChatPromptTemplate
|
|
8
|
-
from langchain.schema import StrOutputParser
|
|
9
|
-
from langchain.schema.runnable import Runnable
|
|
10
|
-
from langchain.schema.runnable.config import RunnableConfig
|
|
11
|
-
|
|
12
|
-
import langwatch
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@cl.on_chat_start
|
|
16
|
-
async def on_chat_start():
|
|
17
|
-
model = ChatOpenAI(streaming=True)
|
|
18
|
-
prompt = ChatPromptTemplate.from_messages(
|
|
19
|
-
[
|
|
20
|
-
(
|
|
21
|
-
"system",
|
|
22
|
-
"You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
|
|
23
|
-
),
|
|
24
|
-
("human", "{question}"),
|
|
25
|
-
]
|
|
26
|
-
)
|
|
27
|
-
runnable = prompt | model | StrOutputParser()
|
|
28
|
-
cl.user_session.set("runnable", runnable)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@cl.on_message
|
|
32
|
-
@langwatch.trace()
|
|
33
|
-
async def main(message: cl.Message):
|
|
34
|
-
runnable: Runnable = cl.user_session.get("runnable") # type: ignore
|
|
35
|
-
|
|
36
|
-
msg = cl.Message(content="")
|
|
37
|
-
|
|
38
|
-
langwatch.get_current_trace().update(
|
|
39
|
-
metadata={"customer_id": "customer_example", "labels": ["langchain"]}
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
async for chunk in runnable.astream(
|
|
43
|
-
{"question": message.content},
|
|
44
|
-
config=RunnableConfig(
|
|
45
|
-
callbacks=[
|
|
46
|
-
cl.LangchainCallbackHandler(),
|
|
47
|
-
langwatch.get_current_trace().get_langchain_callback(),
|
|
48
|
-
]
|
|
49
|
-
),
|
|
50
|
-
):
|
|
51
|
-
await msg.stream_token(chunk)
|
|
52
|
-
|
|
53
|
-
await msg.send()
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
from dotenv import load_dotenv
|
|
2
|
-
from langchain_openai import ChatOpenAI
|
|
3
|
-
|
|
4
|
-
load_dotenv()
|
|
5
|
-
|
|
6
|
-
import chainlit as cl
|
|
7
|
-
from langchain.prompts import ChatPromptTemplate
|
|
8
|
-
from langchain.schema import StrOutputParser
|
|
9
|
-
from langchain.schema.runnable import Runnable
|
|
10
|
-
from langchain.schema.runnable.config import RunnableConfig
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@cl.on_chat_start
|
|
14
|
-
async def on_chat_start():
|
|
15
|
-
model = ChatOpenAI(streaming=True)
|
|
16
|
-
prompt = ChatPromptTemplate.from_messages(
|
|
17
|
-
[
|
|
18
|
-
(
|
|
19
|
-
"system",
|
|
20
|
-
"You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis.",
|
|
21
|
-
),
|
|
22
|
-
("human", "{question}"),
|
|
23
|
-
]
|
|
24
|
-
)
|
|
25
|
-
runnable = prompt | model | StrOutputParser()
|
|
26
|
-
cl.user_session.set("runnable", runnable)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@cl.on_message
|
|
30
|
-
async def main(message: cl.Message):
|
|
31
|
-
runnable: Runnable = cl.user_session.get("runnable") # type: ignore
|
|
32
|
-
|
|
33
|
-
msg = cl.Message(content="")
|
|
34
|
-
|
|
35
|
-
async for chunk in runnable.astream(
|
|
36
|
-
{"question": message.content},
|
|
37
|
-
config=RunnableConfig(
|
|
38
|
-
callbacks=[
|
|
39
|
-
cl.LangchainCallbackHandler(),
|
|
40
|
-
]
|
|
41
|
-
),
|
|
42
|
-
):
|
|
43
|
-
await msg.stream_token(chunk)
|
|
44
|
-
|
|
45
|
-
await msg.send()
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
from dotenv import load_dotenv
|
|
2
|
-
from langchain_openai import ChatOpenAI
|
|
3
|
-
|
|
4
|
-
load_dotenv()
|
|
5
|
-
|
|
6
|
-
import chainlit as cl
|
|
7
|
-
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
8
|
-
from langchain.schema.runnable import Runnable, RunnableMap
|
|
9
|
-
from langchain.schema.runnable.config import RunnableConfig
|
|
10
|
-
from langchain.memory import ConversationBufferMemory
|
|
11
|
-
|
|
12
|
-
import langwatch
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
session_memories: dict = {}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@cl.on_chat_start
|
|
19
|
-
async def on_chat_start():
|
|
20
|
-
memory = session_memories.setdefault(
|
|
21
|
-
cl.user_session.get("session_id"),
|
|
22
|
-
ConversationBufferMemory(return_messages=True, memory_key="chat_history"),
|
|
23
|
-
)
|
|
24
|
-
ingress = RunnableMap(
|
|
25
|
-
{
|
|
26
|
-
"input": lambda x: x["input"],
|
|
27
|
-
"chat_history": lambda x: memory.load_memory_variables(x)["chat_history"],
|
|
28
|
-
}
|
|
29
|
-
)
|
|
30
|
-
prompt = ChatPromptTemplate.from_messages(
|
|
31
|
-
[
|
|
32
|
-
("system", "You are a helpful assistant."),
|
|
33
|
-
MessagesPlaceholder(variable_name="chat_history"),
|
|
34
|
-
("human", "{input}"),
|
|
35
|
-
]
|
|
36
|
-
)
|
|
37
|
-
llm = ChatOpenAI(temperature=0.3, model="gpt-5", max_tokens=4096)
|
|
38
|
-
runnable = ingress | prompt | llm
|
|
39
|
-
|
|
40
|
-
cl.user_session.set("runnable", runnable)
|
|
41
|
-
cl.user_session.set("memory", memory)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@cl.on_message
|
|
45
|
-
@langwatch.trace()
|
|
46
|
-
async def main(message: cl.Message):
|
|
47
|
-
runnable: Runnable = cl.user_session.get("runnable") # type: ignore
|
|
48
|
-
memory = cl.user_session.get("memory") # type: ignore
|
|
49
|
-
|
|
50
|
-
msg = cl.Message(content="")
|
|
51
|
-
|
|
52
|
-
langwatch.get_current_trace().update(
|
|
53
|
-
metadata={"customer_id": "customer_example", "labels": ["langchain", "memory"]}
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
async for chunk in runnable.astream(
|
|
57
|
-
{"input": message.content},
|
|
58
|
-
config=RunnableConfig(
|
|
59
|
-
callbacks=[
|
|
60
|
-
cl.LangchainCallbackHandler(),
|
|
61
|
-
langwatch.get_current_trace().get_langchain_callback(),
|
|
62
|
-
]
|
|
63
|
-
),
|
|
64
|
-
):
|
|
65
|
-
await msg.stream_token(chunk.content)
|
|
66
|
-
|
|
67
|
-
memory.save_context({"input": message.content}, {"output": msg.content}) # type: ignore
|
|
68
|
-
|
|
69
|
-
await msg.send()
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
from dotenv import load_dotenv
|
|
2
|
-
from langchain_openai import ChatOpenAI
|
|
3
|
-
|
|
4
|
-
load_dotenv()
|
|
5
|
-
|
|
6
|
-
import chainlit as cl
|
|
7
|
-
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
|
|
8
|
-
from langchain.schema.runnable import Runnable, RunnableMap
|
|
9
|
-
from langchain.schema.runnable.config import RunnableConfig
|
|
10
|
-
from langchain.memory import ConversationBufferMemory
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
session_memories: dict = {}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@cl.on_chat_start
|
|
17
|
-
async def on_chat_start():
|
|
18
|
-
memory = session_memories.setdefault(
|
|
19
|
-
cl.user_session.get("session_id"),
|
|
20
|
-
ConversationBufferMemory(return_messages=True, memory_key="chat_history"),
|
|
21
|
-
)
|
|
22
|
-
ingress = RunnableMap(
|
|
23
|
-
{
|
|
24
|
-
"input": lambda x: x["input"],
|
|
25
|
-
"chat_history": lambda x: memory.load_memory_variables(x)["chat_history"],
|
|
26
|
-
}
|
|
27
|
-
)
|
|
28
|
-
prompt = ChatPromptTemplate.from_messages(
|
|
29
|
-
[
|
|
30
|
-
("system", "You are a helpful assistant."),
|
|
31
|
-
MessagesPlaceholder(variable_name="chat_history"),
|
|
32
|
-
("human", "{input}"),
|
|
33
|
-
]
|
|
34
|
-
)
|
|
35
|
-
llm = ChatOpenAI(temperature=0.3, model="gpt-5", max_tokens=4096)
|
|
36
|
-
runnable = ingress | prompt | llm
|
|
37
|
-
|
|
38
|
-
cl.user_session.set("runnable", runnable)
|
|
39
|
-
cl.user_session.set("memory", memory)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@cl.on_message
|
|
43
|
-
async def main(message: cl.Message):
|
|
44
|
-
runnable: Runnable = cl.user_session.get("runnable") # type: ignore
|
|
45
|
-
memory = cl.user_session.get("memory") # type: ignore
|
|
46
|
-
|
|
47
|
-
msg = cl.Message(content="")
|
|
48
|
-
|
|
49
|
-
async for chunk in runnable.astream(
|
|
50
|
-
{"input": message.content},
|
|
51
|
-
config=RunnableConfig(
|
|
52
|
-
callbacks=[
|
|
53
|
-
cl.LangchainCallbackHandler(),
|
|
54
|
-
]
|
|
55
|
-
),
|
|
56
|
-
):
|
|
57
|
-
await msg.stream_token(chunk.content)
|
|
58
|
-
|
|
59
|
-
memory.save_context({"input": message.content}, {"output": msg.content}) # type: ignore
|
|
60
|
-
|
|
61
|
-
await msg.send()
|
|
@@ -1,97 +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 langchain.prompts import ChatPromptTemplate
|
|
9
|
-
from langchain.schema import HumanMessage
|
|
10
|
-
from langchain.schema.runnable.config import RunnableConfig
|
|
11
|
-
|
|
12
|
-
import langwatch
|
|
13
|
-
|
|
14
|
-
from langchain_community.document_loaders import WebBaseLoader
|
|
15
|
-
from langchain_community.vectorstores.faiss import FAISS
|
|
16
|
-
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
|
17
|
-
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
18
|
-
from langchain.tools.retriever import create_retriever_tool
|
|
19
|
-
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
20
|
-
from langchain.tools import BaseTool, StructuredTool, tool
|
|
21
|
-
|
|
22
|
-
loader = WebBaseLoader("https://docs.langwatch.ai")
|
|
23
|
-
docs = loader.load()
|
|
24
|
-
documents = RecursiveCharacterTextSplitter(
|
|
25
|
-
chunk_size=1000, chunk_overlap=200
|
|
26
|
-
).split_documents(docs)
|
|
27
|
-
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
|
|
28
|
-
retriever = vector.as_retriever()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@cl.on_chat_start
|
|
32
|
-
async def on_chat_start():
|
|
33
|
-
retriever_tool = create_retriever_tool(
|
|
34
|
-
langwatch.langchain.capture_rag_from_retriever(
|
|
35
|
-
retriever,
|
|
36
|
-
lambda document: RAGChunk(
|
|
37
|
-
document_id=document.metadata["source"], content=document.page_content
|
|
38
|
-
),
|
|
39
|
-
),
|
|
40
|
-
"langwatch_search",
|
|
41
|
-
"Search for information about LangWatch. For any questions about LangWatch, use this tool if you didn't already",
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# Alternative approach to retrievers
|
|
45
|
-
# wrapped_tool = langwatch.langchain.capture_rag_from_tool(
|
|
46
|
-
# retriever_tool, lambda response: [RAGChunk(content=response)]
|
|
47
|
-
# )
|
|
48
|
-
|
|
49
|
-
tools = [retriever_tool]
|
|
50
|
-
model = ChatOpenAI(model="gpt-5", streaming=True)
|
|
51
|
-
prompt = ChatPromptTemplate.from_messages(
|
|
52
|
-
[
|
|
53
|
-
(
|
|
54
|
-
"system",
|
|
55
|
-
"You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis and use tools only once.\n\n{agent_scratchpad}",
|
|
56
|
-
),
|
|
57
|
-
("human", "{question}"),
|
|
58
|
-
]
|
|
59
|
-
)
|
|
60
|
-
agent = create_tool_calling_agent(model, tools, prompt)
|
|
61
|
-
executor = AgentExecutor(agent=agent, tools=tools, verbose=True) # type: ignore
|
|
62
|
-
cl.user_session.set("agent", executor)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
@cl.on_message
|
|
66
|
-
@langwatch.trace()
|
|
67
|
-
async def main(message: cl.Message):
|
|
68
|
-
agent: AgentExecutor = cl.user_session.get("agent") # type: ignore
|
|
69
|
-
|
|
70
|
-
msg = cl.Message(content="")
|
|
71
|
-
|
|
72
|
-
langwatch.get_current_trace().update(
|
|
73
|
-
metadata={"user_id": "user_example", "labels": ["langchain", "rag"]}
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
async for chunk in agent.astream(
|
|
77
|
-
{
|
|
78
|
-
"question": message.content,
|
|
79
|
-
"messages": [HumanMessage(content="Hoi, dit is een test")],
|
|
80
|
-
},
|
|
81
|
-
config=RunnableConfig(
|
|
82
|
-
callbacks=[
|
|
83
|
-
cl.LangchainCallbackHandler(),
|
|
84
|
-
langwatch.get_current_trace().get_langchain_callback(),
|
|
85
|
-
]
|
|
86
|
-
),
|
|
87
|
-
):
|
|
88
|
-
if "output" in chunk:
|
|
89
|
-
await msg.stream_token(chunk["output"])
|
|
90
|
-
elif "actions" in chunk:
|
|
91
|
-
await msg.stream_token(chunk["actions"][0].log)
|
|
92
|
-
elif "steps" in chunk:
|
|
93
|
-
await msg.stream_token(chunk["steps"][0].observation + "\n\n")
|
|
94
|
-
else:
|
|
95
|
-
await msg.stream_token("<unammaped chunk>")
|
|
96
|
-
|
|
97
|
-
await msg.send()
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
from dotenv import load_dotenv
|
|
2
|
-
|
|
3
|
-
load_dotenv()
|
|
4
|
-
|
|
5
|
-
import chainlit as cl
|
|
6
|
-
from langchain.prompts import ChatPromptTemplate
|
|
7
|
-
from langchain.schema import HumanMessage
|
|
8
|
-
from langchain.schema.runnable.config import RunnableConfig
|
|
9
|
-
|
|
10
|
-
from langchain_community.document_loaders import WebBaseLoader
|
|
11
|
-
from langchain_community.vectorstores.faiss import FAISS
|
|
12
|
-
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
|
13
|
-
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
|
14
|
-
from langchain.tools.retriever import create_retriever_tool
|
|
15
|
-
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
|
16
|
-
from langchain.tools import BaseTool, StructuredTool, tool
|
|
17
|
-
|
|
18
|
-
loader = WebBaseLoader("https://docs.langwatch.ai")
|
|
19
|
-
docs = loader.load()
|
|
20
|
-
documents = RecursiveCharacterTextSplitter(
|
|
21
|
-
chunk_size=1000, chunk_overlap=200
|
|
22
|
-
).split_documents(docs)
|
|
23
|
-
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
|
|
24
|
-
retriever = vector.as_retriever()
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@cl.on_chat_start
|
|
28
|
-
async def on_chat_start():
|
|
29
|
-
retriever_tool = create_retriever_tool(
|
|
30
|
-
retriever,
|
|
31
|
-
"langwatch_search",
|
|
32
|
-
"Search for information about LangWatch. For any questions about LangWatch, use this tool if you didn't already",
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
tools = [retriever_tool]
|
|
36
|
-
model = ChatOpenAI(model="gpt-5", streaming=True)
|
|
37
|
-
prompt = ChatPromptTemplate.from_messages(
|
|
38
|
-
[
|
|
39
|
-
(
|
|
40
|
-
"system",
|
|
41
|
-
"You are a helpful assistant that only reply in short tweet-like responses, using lots of emojis and use tools only once.\n\n{agent_scratchpad}",
|
|
42
|
-
),
|
|
43
|
-
("human", "{question}"),
|
|
44
|
-
]
|
|
45
|
-
)
|
|
46
|
-
agent = create_tool_calling_agent(model, tools, prompt)
|
|
47
|
-
executor = AgentExecutor(agent=agent, tools=tools, verbose=True) # type: ignore
|
|
48
|
-
cl.user_session.set("agent", executor)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@cl.on_message
|
|
52
|
-
async def main(message: cl.Message):
|
|
53
|
-
agent: AgentExecutor = cl.user_session.get("agent") # type: ignore
|
|
54
|
-
|
|
55
|
-
msg = cl.Message(content="")
|
|
56
|
-
|
|
57
|
-
async for chunk in agent.astream(
|
|
58
|
-
{
|
|
59
|
-
"question": message.content,
|
|
60
|
-
"messages": [HumanMessage(content="Hoi, dit is een test")],
|
|
61
|
-
},
|
|
62
|
-
config=RunnableConfig(
|
|
63
|
-
callbacks=[
|
|
64
|
-
cl.LangchainCallbackHandler(),
|
|
65
|
-
]
|
|
66
|
-
),
|
|
67
|
-
):
|
|
68
|
-
if "output" in chunk:
|
|
69
|
-
await msg.stream_token(chunk["output"])
|
|
70
|
-
elif "actions" in chunk:
|
|
71
|
-
await msg.stream_token(chunk["actions"][0].log)
|
|
72
|
-
elif "steps" in chunk:
|
|
73
|
-
await msg.stream_token(chunk["steps"][0].observation + "\n\n")
|
|
74
|
-
else:
|
|
75
|
-
await msg.stream_token("<unammaped chunk>")
|
|
76
|
-
|
|
77
|
-
await msg.send()
|