@langwatch/mcp-server 0.6.1 → 0.8.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 +89 -0
- package/README.md +51 -8
- package/dist/{archive-scenario-YFD5THOR.js → archive-scenario-YKGLJ4MZ.js} +4 -4
- package/dist/archive-suite-QFNDO3Y3.js +15 -0
- package/dist/assign-prompt-tag-Y2B4CBBT.js +19 -0
- package/dist/chunk-B57MZ4WI.js +1573 -0
- package/dist/{chunk-IX6QJKAD.js → chunk-CPUPGDNA.js} +2 -2
- package/dist/chunk-FBRKHHJV.js +48 -0
- package/dist/{chunk-5UOPNRXW.js → chunk-HDJDFKZR.js} +10 -3
- package/dist/chunk-KOO5733S.js +72 -0
- package/dist/chunk-KZNBCKWG.js +39 -0
- package/dist/chunk-L6QENXYA.js +42 -0
- package/dist/{chunk-6U4TCGFC.js → chunk-NACSR6B7.js} +2 -2
- package/dist/chunk-NUFPTHKU.js +9 -0
- package/dist/chunk-OVQF3D5R.js +86 -0
- package/dist/chunk-PO7FM7IX.js +35 -0
- package/dist/chunk-PZUWCWOS.js +25 -0
- package/dist/chunk-WVI5CJ6S.js +21 -0
- package/dist/{chunk-LLRQIF52.js → chunk-YH2IBTEL.js} +54 -6
- package/dist/chunk-YI3OG4PI.js +71 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +13 -0
- package/dist/create-agent-YRSDH7P7.js +23 -0
- package/dist/create-annotation-FYQNKMVJ.js +24 -0
- package/dist/create-dashboard-CORBR4YQ.js +18 -0
- package/dist/create-dataset-ZC63T6BB.js +22 -0
- package/dist/create-dataset-records-ILVNVKVR.js +22 -0
- package/dist/{create-evaluator-E5X5ZP3B.js → create-evaluator-2AU3PXFB.js} +4 -4
- package/dist/create-mcp-server.d.ts +8 -0
- package/dist/create-mcp-server.js +8 -0
- package/dist/{create-prompt-7Z35MIL6.js → create-prompt-NKRJ47YY.js} +7 -4
- package/dist/create-prompt-tag-S4JX3ULL.js +17 -0
- package/dist/{create-scenario-DIMPJRPY.js → create-scenario-BPRF75KF.js} +4 -4
- package/dist/create-suite-4YN7D6K2.js +38 -0
- package/dist/delete-agent-Y72R2YQA.js +18 -0
- package/dist/delete-annotation-UHWDMHSH.js +17 -0
- package/dist/delete-dashboard-LPWT36KN.js +18 -0
- package/dist/delete-dataset-GGPQRHKX.js +20 -0
- package/dist/delete-dataset-records-LTG5LT26.js +21 -0
- package/dist/delete-evaluator-F7QLXDHU.js +15 -0
- package/dist/delete-prompt-tag-B5UKZL45.js +17 -0
- package/dist/delete-workflow-4DGUDIDE.js +17 -0
- package/dist/get-agent-YEVICUX4.js +28 -0
- package/dist/{get-analytics-4YJW4S5L.js → get-analytics-3W5CMU3F.js} +22 -5
- package/dist/get-dashboard-NCQHN6MW.js +29 -0
- package/dist/get-dataset-KBK6PH36.js +48 -0
- package/dist/{get-evaluator-WDEH2F7M.js → get-evaluator-QDUL5LXR.js} +4 -4
- package/dist/{get-prompt-F6PDVC76.js → get-prompt-XCSSNRKR.js} +4 -4
- package/dist/{get-scenario-H24ZYNT5.js → get-scenario-FNRKOY7E.js} +4 -4
- package/dist/get-simulation-run-WOEKUF7K.js +56 -0
- package/dist/get-suite-U5AOD5TC.js +44 -0
- package/dist/{get-trace-27USKGO7.js → get-trace-MUWEJM2Z.js} +3 -3
- package/dist/get-workflow-SOA7MT7L.js +25 -0
- package/dist/http-server-7DMOCB75.js +224 -0
- package/dist/index.js +61640 -31868
- package/dist/langwatch-api-annotations-Q57NDUVR.js +17 -0
- package/dist/langwatch-api-dashboards-VBWWXV3Y.js +17 -0
- package/dist/langwatch-api-monitors-L3IY7FDT.js +52 -0
- package/dist/langwatch-api-secrets-S5HHF3XR.js +40 -0
- package/dist/langwatch-api-triggers-ME33QE26.js +30 -0
- package/dist/langwatch-api-workflows-4CJQAYP2.js +15 -0
- package/dist/list-agents-3HGIBJFM.js +32 -0
- package/dist/list-annotations-KWXYVEPI.js +33 -0
- package/dist/list-dashboards-VQ2LH666.js +32 -0
- package/dist/list-dataset-records-RNRGROJP.js +39 -0
- package/dist/list-datasets-I4A2LT2S.js +60 -0
- package/dist/{list-evaluators-KRGI72EH.js → list-evaluators-AKKRJ5MX.js} +4 -4
- package/dist/{list-model-providers-A5YCFTPI.js → list-model-providers-DVFEHFHZ.js} +4 -4
- package/dist/list-prompt-tags-PL5OISUA.js +23 -0
- package/dist/{list-prompts-LKJSE7XN.js → list-prompts-7VTFWE2Z.js} +3 -3
- package/dist/{list-scenarios-ZK5CMGC4.js → list-scenarios-5BZWZ6ZN.js} +4 -4
- package/dist/list-simulation-runs-WCZ6RLPE.js +43 -0
- package/dist/list-suites-RRQ2JX5Y.js +42 -0
- package/dist/list-workflows-UQB5FCX5.js +35 -0
- package/dist/rename-prompt-tag-TURD6KYU.js +18 -0
- package/dist/run-agent-BEJ4K4CM.js +36 -0
- package/dist/run-evaluation-AJ7WZNQD.js +64 -0
- package/dist/run-suite-U7V432G2.js +29 -0
- package/dist/run-workflow-5WX7DK5T.js +36 -0
- package/dist/{search-traces-SOKAAMAR.js → search-traces-ZCHNOMTX.js} +3 -3
- package/dist/{set-model-provider-7MGULZDH.js → set-model-provider-6CFHMCNE.js} +4 -4
- package/dist/update-agent-UE6UWLZP.js +20 -0
- package/dist/update-dataset-4XQZZE4S.js +22 -0
- package/dist/update-dataset-record-GNNM5TKM.js +19 -0
- package/dist/{update-evaluator-A3XINFLJ.js → update-evaluator-LHVDXIZD.js} +4 -4
- package/dist/{update-prompt-IW7X2UQM.js → update-prompt-3XEHECJ7.js} +5 -3
- package/dist/{update-scenario-ZT7TOBFR.js → update-scenario-DFPREYCD.js} +4 -4
- package/dist/update-suite-RATU5THO.js +39 -0
- package/package.json +22 -8
- package/src/__tests__/all-tools.integration.test.ts +353 -0
- package/src/__tests__/config.unit.test.ts +81 -1
- package/src/__tests__/datasets.integration.test.ts +620 -0
- package/src/__tests__/datasets.unit.test.ts +244 -0
- package/src/__tests__/docker.integration.test.ts +234 -0
- package/src/__tests__/http-transport.integration.test.ts +397 -0
- package/src/__tests__/langwatch-api.unit.test.ts +174 -0
- package/src/__tests__/scenario-tools.unit.test.ts +3 -0
- package/src/__tests__/tools.unit.test.ts +177 -0
- package/src/config.d.ts +15 -0
- package/src/config.ts +85 -7
- package/src/create-mcp-server.d.ts +6 -0
- package/src/create-mcp-server.ts +1799 -0
- package/src/http-server.ts +329 -0
- package/src/index.ts +22 -593
- package/src/langwatch-api-agents.ts +108 -0
- package/src/langwatch-api-annotations.ts +49 -0
- package/src/langwatch-api-dashboards.ts +48 -0
- package/src/langwatch-api-datasets.ts +191 -0
- package/src/langwatch-api-evaluators.ts +10 -0
- package/src/langwatch-api-monitors.ts +82 -0
- package/src/langwatch-api-secrets.ts +48 -0
- package/src/langwatch-api-simulation-runs.ts +51 -0
- package/src/langwatch-api-suites.ts +118 -0
- package/src/langwatch-api-triggers.ts +48 -0
- package/src/langwatch-api-workflows.ts +41 -0
- package/src/langwatch-api.ts +65 -3
- package/src/schemas/create-dataset.ts +48 -0
- package/src/schemas/index.ts +1 -0
- package/src/tools/archive-suite.ts +12 -0
- package/src/tools/assign-prompt-tag.ts +16 -0
- package/src/tools/create-agent.ts +15 -0
- package/src/tools/create-annotation.ts +18 -0
- package/src/tools/create-dashboard.ts +7 -0
- package/src/tools/create-dataset-records.ts +23 -0
- package/src/tools/create-dataset.ts +22 -0
- package/src/tools/create-prompt-tag.ts +12 -0
- package/src/tools/create-prompt.ts +4 -0
- package/src/tools/create-suite.ts +42 -0
- package/src/tools/delete-agent.ts +7 -0
- package/src/tools/delete-annotation.ts +7 -0
- package/src/tools/delete-dashboard.ts +7 -0
- package/src/tools/delete-dataset-records.ts +22 -0
- package/src/tools/delete-dataset.ts +20 -0
- package/src/tools/delete-evaluator.ts +12 -0
- package/src/tools/delete-prompt-tag.ts +12 -0
- package/src/tools/delete-workflow.ts +7 -0
- package/src/tools/format-dataset-mutation.ts +25 -0
- package/src/tools/get-agent.ts +21 -0
- package/src/tools/get-analytics.ts +30 -3
- package/src/tools/get-dashboard.ts +22 -0
- package/src/tools/get-dataset.ts +63 -0
- package/src/tools/get-prompt.ts +2 -1
- package/src/tools/get-simulation-run.ts +60 -0
- package/src/tools/get-suite.ts +47 -0
- package/src/tools/get-workflow.ts +17 -0
- package/src/tools/list-agents.ts +27 -0
- package/src/tools/list-annotations.ts +33 -0
- package/src/tools/list-dashboards.ts +27 -0
- package/src/tools/list-dataset-records.ts +46 -0
- package/src/tools/list-datasets.ts +80 -0
- package/src/tools/list-prompt-tags.ts +21 -0
- package/src/tools/list-simulation-runs.ts +49 -0
- package/src/tools/list-suites.ts +43 -0
- package/src/tools/list-workflows.ts +31 -0
- package/src/tools/rename-prompt-tag.ts +14 -0
- package/src/tools/run-agent.ts +36 -0
- package/src/tools/run-evaluation.ts +87 -0
- package/src/tools/run-suite.ts +28 -0
- package/src/tools/run-workflow.ts +36 -0
- package/src/tools/update-agent.ts +13 -0
- package/src/tools/update-dataset-record.ts +21 -0
- package/src/tools/update-dataset.ts +23 -0
- package/src/tools/update-prompt.ts +3 -0
- package/src/tools/update-suite.ts +44 -0
- package/src/utils/escape-markdown.ts +12 -0
- package/uv.lock +188 -530
- package/build.js +0 -12
- package/dist/archive-scenario-YFD5THOR.js.map +0 -1
- package/dist/chunk-5UOPNRXW.js.map +0 -1
- package/dist/chunk-6U4TCGFC.js.map +0 -1
- package/dist/chunk-AAQNA53E.js +0 -28
- package/dist/chunk-AAQNA53E.js.map +0 -1
- package/dist/chunk-IX6QJKAD.js.map +0 -1
- package/dist/chunk-LLRQIF52.js.map +0 -1
- package/dist/chunk-ZXKLPC2E.js.map +0 -1
- package/dist/config-FIQWQRUB.js +0 -11
- package/dist/config-FIQWQRUB.js.map +0 -1
- package/dist/create-evaluator-E5X5ZP3B.js.map +0 -1
- package/dist/create-prompt-7Z35MIL6.js.map +0 -1
- package/dist/create-scenario-DIMPJRPY.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-analytics-4YJW4S5L.js.map +0 -1
- package/dist/get-evaluator-WDEH2F7M.js.map +0 -1
- package/dist/get-prompt-F6PDVC76.js.map +0 -1
- package/dist/get-scenario-H24ZYNT5.js.map +0 -1
- package/dist/get-trace-27USKGO7.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/list-evaluators-KRGI72EH.js.map +0 -1
- package/dist/list-model-providers-A5YCFTPI.js.map +0 -1
- package/dist/list-prompts-LKJSE7XN.js.map +0 -1
- package/dist/list-scenarios-ZK5CMGC4.js.map +0 -1
- package/dist/search-traces-SOKAAMAR.js.map +0 -1
- package/dist/set-model-provider-7MGULZDH.js.map +0 -1
- package/dist/update-evaluator-A3XINFLJ.js.map +0 -1
- package/dist/update-prompt-IW7X2UQM.js.map +0 -1
- package/dist/update-scenario-ZT7TOBFR.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 -10
- 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()
|