langchain-trigger-server 0.2.8__py3-none-any.whl → 0.2.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langchain-trigger-server might be problematic. Click here for more details.
- {langchain_trigger_server-0.2.8.dist-info → langchain_trigger_server-0.2.9.dist-info}/METADATA +1 -1
- {langchain_trigger_server-0.2.8.dist-info → langchain_trigger_server-0.2.9.dist-info}/RECORD +5 -5
- langchain_triggers/app.py +44 -15
- langchain_triggers/cron_manager.py +5 -0
- {langchain_trigger_server-0.2.8.dist-info → langchain_trigger_server-0.2.9.dist-info}/WHEEL +0 -0
{langchain_trigger_server-0.2.8.dist-info → langchain_trigger_server-0.2.9.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain-trigger-server
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: Generic event-driven triggers framework
|
|
5
5
|
Project-URL: Homepage, https://github.com/langchain-ai/open-agent-platform
|
|
6
6
|
Project-URL: Repository, https://github.com/langchain-ai/open-agent-platform
|
{langchain_trigger_server-0.2.8.dist-info → langchain_trigger_server-0.2.9.dist-info}/RECORD
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
langchain_triggers/__init__.py,sha256=WoW9LC_FJRs42mLWq2iuM-jjPow2Rue50q2zm56Oul0,536
|
|
2
|
-
langchain_triggers/app.py,sha256=
|
|
2
|
+
langchain_triggers/app.py,sha256=MARlj82Ena79n0MG23m-Vu9w6YDQWqp0Ao24TuEKTzs,35325
|
|
3
3
|
langchain_triggers/core.py,sha256=_CNZRyj78yCHG8FACwhCmZ0zvRoWls924OIFYMOC27Q,3772
|
|
4
|
-
langchain_triggers/cron_manager.py,sha256=
|
|
4
|
+
langchain_triggers/cron_manager.py,sha256=ISo-P2gw7eQ6y7xWQOfojqcJr_K-zagZt9Ocy8nX0fw,10477
|
|
5
5
|
langchain_triggers/decorators.py,sha256=zsfgf171qkEDdIiSn8LUr--3dz6bxBBKZO6dpRM2ILs,3711
|
|
6
6
|
langchain_triggers/auth/__init__.py,sha256=RtDKuBoKYuyHzLNpKr74cmALO0PhHlWO9Ho7k3CUYFE,349
|
|
7
7
|
langchain_triggers/auth/slack_hmac.py,sha256=kiwjhTXITgQvLAtEcOv8BnnWJRJcxaQ9dXkQm3JJDQ4,2948
|
|
@@ -10,6 +10,6 @@ langchain_triggers/database/interface.py,sha256=jpADOOwcBQo1ZichgiZVaOvfZqEqVVo8
|
|
|
10
10
|
langchain_triggers/database/supabase.py,sha256=zi_75GbqRvzzlXd5EgfYof4h6vHWOLS4I1759wvY9kQ,17009
|
|
11
11
|
langchain_triggers/triggers/__init__.py,sha256=Uw1544gxzN4XDRn2RzpZ5EAG6EAF38ZYQtVvlciEsMs,146
|
|
12
12
|
langchain_triggers/triggers/cron_trigger.py,sha256=SeWz_ETBCBO1_r96tzTZgsvn4BdF4yMKabygjmHoGwY,3174
|
|
13
|
-
langchain_trigger_server-0.2.
|
|
14
|
-
langchain_trigger_server-0.2.
|
|
15
|
-
langchain_trigger_server-0.2.
|
|
13
|
+
langchain_trigger_server-0.2.9.dist-info/METADATA,sha256=8ER3hixfKxyvOIn308bFj64yjZkscTxotQRkah3pS60,1486
|
|
14
|
+
langchain_trigger_server-0.2.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
15
|
+
langchain_trigger_server-0.2.9.dist-info/RECORD,,
|
langchain_triggers/app.py
CHANGED
|
@@ -5,8 +5,10 @@ from __future__ import annotations
|
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
7
|
from collections.abc import Callable
|
|
8
|
+
from datetime import UTC, datetime, timedelta
|
|
8
9
|
from typing import Any
|
|
9
10
|
|
|
11
|
+
import jwt
|
|
10
12
|
from fastapi import Depends, FastAPI, HTTPException, Request
|
|
11
13
|
from langchain_auth.client import Client
|
|
12
14
|
from langgraph_sdk import get_client
|
|
@@ -27,6 +29,28 @@ from .triggers.cron_trigger import CRON_TRIGGER_ID
|
|
|
27
29
|
logger = logging.getLogger(__name__)
|
|
28
30
|
|
|
29
31
|
|
|
32
|
+
def get_x_service_jwt_token(
|
|
33
|
+
payload: dict[str, Any] | None = None, expiration_seconds: int = 60 * 60
|
|
34
|
+
) -> str:
|
|
35
|
+
exp_datetime = datetime.now(tz=UTC) + timedelta(seconds=expiration_seconds)
|
|
36
|
+
exp = int(exp_datetime.timestamp())
|
|
37
|
+
|
|
38
|
+
payload = payload or {}
|
|
39
|
+
payload = {
|
|
40
|
+
"sub": "unspecified",
|
|
41
|
+
"exp": exp,
|
|
42
|
+
**payload,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
secret = os.environ["X_SERVICE_AUTH_JWT_SECRET"]
|
|
46
|
+
|
|
47
|
+
return jwt.encode(
|
|
48
|
+
payload,
|
|
49
|
+
secret,
|
|
50
|
+
algorithm="HS256",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
30
54
|
class AuthenticationMiddleware(BaseHTTPMiddleware):
|
|
31
55
|
"""Middleware to handle authentication for API endpoints."""
|
|
32
56
|
|
|
@@ -106,7 +130,6 @@ class TriggerServer:
|
|
|
106
130
|
|
|
107
131
|
# LangGraph configuration
|
|
108
132
|
self.langgraph_api_url = os.getenv("LANGGRAPH_API_URL")
|
|
109
|
-
self.langsmith_api_key = os.getenv("LANGCHAIN_API_KEY")
|
|
110
133
|
self.trigger_server_auth_api_url = os.getenv("TRIGGER_SERVER_HOST_API_URL")
|
|
111
134
|
|
|
112
135
|
if not self.langgraph_api_url:
|
|
@@ -115,16 +138,10 @@ class TriggerServer:
|
|
|
115
138
|
self.langgraph_api_url = self.langgraph_api_url.rstrip("/")
|
|
116
139
|
|
|
117
140
|
# Initialize LangGraph SDK client
|
|
118
|
-
self.langgraph_client = get_client(
|
|
119
|
-
url=self.langgraph_api_url, api_key=self.langsmith_api_key
|
|
120
|
-
)
|
|
141
|
+
self.langgraph_client = get_client(url=self.langgraph_api_url, api_key=None)
|
|
121
142
|
logger.info(
|
|
122
143
|
f"✓ LangGraph client initialized with URL: {self.langgraph_api_url}"
|
|
123
144
|
)
|
|
124
|
-
if self.langsmith_api_key:
|
|
125
|
-
logger.info("✓ LangGraph client initialized with API key.")
|
|
126
|
-
else:
|
|
127
|
-
logger.warning("⚠ LangGraph client initialized without API key")
|
|
128
145
|
|
|
129
146
|
# Initialize LangChain auth client
|
|
130
147
|
langchain_api_key = os.getenv("LANGCHAIN_API_KEY")
|
|
@@ -585,6 +602,7 @@ class TriggerServer:
|
|
|
585
602
|
body_bytes = await request.body()
|
|
586
603
|
body_str = body_bytes.decode("utf-8")
|
|
587
604
|
|
|
605
|
+
# TODO(sam/palash): We should not have API specific things in this framework repo. We should clean this up.
|
|
588
606
|
if self._is_slack_trigger(trigger):
|
|
589
607
|
await self._verify_slack_webhook_auth_with_body(
|
|
590
608
|
request, body_str
|
|
@@ -629,6 +647,11 @@ class TriggerServer:
|
|
|
629
647
|
# Ensure agent_id and user_id are strings for JSON serialization
|
|
630
648
|
agent_id_str = str(agent_id)
|
|
631
649
|
user_id_str = str(result.registration["user_id"])
|
|
650
|
+
tenant_id_str = str(
|
|
651
|
+
result.registration.get("metadata", {})
|
|
652
|
+
.get("client_metadata", {})
|
|
653
|
+
.get("tenant_id")
|
|
654
|
+
)
|
|
632
655
|
|
|
633
656
|
agent_input = {"messages": [{"role": "human", "content": message}]}
|
|
634
657
|
|
|
@@ -636,6 +659,7 @@ class TriggerServer:
|
|
|
636
659
|
success = await self._invoke_agent(
|
|
637
660
|
agent_id=agent_id_str,
|
|
638
661
|
user_id=user_id_str,
|
|
662
|
+
tenant_id=tenant_id_str,
|
|
639
663
|
input_data=agent_input,
|
|
640
664
|
)
|
|
641
665
|
if success:
|
|
@@ -662,6 +686,7 @@ class TriggerServer:
|
|
|
662
686
|
self,
|
|
663
687
|
agent_id: str,
|
|
664
688
|
user_id: str,
|
|
689
|
+
tenant_id: str,
|
|
665
690
|
input_data: dict[str, Any],
|
|
666
691
|
) -> bool:
|
|
667
692
|
"""Invoke LangGraph agent using the SDK."""
|
|
@@ -671,20 +696,23 @@ class TriggerServer:
|
|
|
671
696
|
|
|
672
697
|
try:
|
|
673
698
|
headers = {
|
|
674
|
-
"x-
|
|
699
|
+
"x-api-key": "",
|
|
700
|
+
"x-auth-scheme": "langsmith-agent",
|
|
675
701
|
"x-user-id": user_id_str,
|
|
702
|
+
"x-tenant-id": tenant_id,
|
|
703
|
+
"x-service-key": get_x_service_jwt_token(
|
|
704
|
+
payload={
|
|
705
|
+
"tenant_id": tenant_id,
|
|
706
|
+
"user_id": user_id_str,
|
|
707
|
+
}
|
|
708
|
+
),
|
|
676
709
|
}
|
|
677
710
|
|
|
678
|
-
# Note: API key is already set in client initialization, no need to add to headers
|
|
679
|
-
if not self.langsmith_api_key:
|
|
680
|
-
logger.warning(
|
|
681
|
-
"No LANGSMITH_API_KEY available - authentication may fail"
|
|
682
|
-
)
|
|
683
|
-
|
|
684
711
|
thread = await self.langgraph_client.threads.create(
|
|
685
712
|
metadata={
|
|
686
713
|
"triggered_by": "langchain-triggers",
|
|
687
714
|
"user_id": user_id_str,
|
|
715
|
+
"tenant_id": tenant_id,
|
|
688
716
|
},
|
|
689
717
|
headers=headers,
|
|
690
718
|
)
|
|
@@ -697,6 +725,7 @@ class TriggerServer:
|
|
|
697
725
|
metadata={
|
|
698
726
|
"triggered_by": "langchain-triggers",
|
|
699
727
|
"user_id": user_id_str,
|
|
728
|
+
"tenant_id": tenant_id,
|
|
700
729
|
},
|
|
701
730
|
headers=headers,
|
|
702
731
|
)
|
|
@@ -202,6 +202,9 @@ class CronTriggerManager:
|
|
|
202
202
|
"""Execute a cron job - invoke agents. Can be called manually or by scheduler."""
|
|
203
203
|
registration_id = registration["id"]
|
|
204
204
|
user_id = registration["user_id"]
|
|
205
|
+
tenant_id = (
|
|
206
|
+
registration.get("metadata", {}).get("client_metadata", {}).get("tenant_id")
|
|
207
|
+
)
|
|
205
208
|
|
|
206
209
|
# Get agent links
|
|
207
210
|
agent_links = await self.trigger_server.database.get_agents_for_trigger(
|
|
@@ -222,6 +225,7 @@ class CronTriggerManager:
|
|
|
222
225
|
# Ensure agent_id and user_id are strings for JSON serialization
|
|
223
226
|
agent_id_str = str(agent_id)
|
|
224
227
|
user_id_str = str(user_id)
|
|
228
|
+
tenant_id_str = str(tenant_id)
|
|
225
229
|
|
|
226
230
|
current_time = datetime.utcnow()
|
|
227
231
|
current_time_str = current_time.strftime("%A, %B %d, %Y at %H:%M UTC")
|
|
@@ -239,6 +243,7 @@ class CronTriggerManager:
|
|
|
239
243
|
success = await self.trigger_server._invoke_agent(
|
|
240
244
|
agent_id=agent_id_str,
|
|
241
245
|
user_id=user_id_str,
|
|
246
|
+
tenant_id=tenant_id_str,
|
|
242
247
|
input_data=agent_input,
|
|
243
248
|
)
|
|
244
249
|
if success:
|
|
File without changes
|