langchain-trigger-server 0.3.8__tar.gz → 0.3.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of langchain-trigger-server might be problematic. Click here for more details.
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/PKG-INFO +1 -1
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/app.py +10 -33
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/database/interface.py +0 -24
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/decorators.py +20 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/triggers/cron_trigger.py +5 -1
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/pyproject.toml +1 -1
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/tests/unit/test_trigger_server_api.py +16 -25
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/uv.lock +1 -1
- langchain_trigger_server-0.3.9/version_comparison.txt +1 -0
- langchain_trigger_server-0.3.8/version_comparison.txt +0 -1
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/actions/uv_setup/action.yml +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/_lint.yml +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/_test.yml +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/ci.yml +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/release.yml +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.gitignore +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/Makefile +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/README.md +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/__init__.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/auth/__init__.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/core.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/cron_manager.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/database/__init__.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/triggers/__init__.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/util.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/tests/__init__.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/tests/unit/__init__.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/tests/unit/test_cron_manager_polling_filter.py +0 -0
- {langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/tests/unit/test_cron_manager_schedule_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langchain-trigger-server
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -157,7 +157,6 @@ class TriggerServer:
|
|
|
157
157
|
# Add startup and shutdown events
|
|
158
158
|
@self.app.on_event("startup")
|
|
159
159
|
async def startup_event():
|
|
160
|
-
await self.ensure_trigger_templates()
|
|
161
160
|
await self.cron_manager.start()
|
|
162
161
|
|
|
163
162
|
@self.app.on_event("shutdown")
|
|
@@ -210,29 +209,6 @@ class TriggerServer:
|
|
|
210
209
|
f"Registered trigger template in memory: {trigger.name} ({trigger.id})"
|
|
211
210
|
)
|
|
212
211
|
|
|
213
|
-
async def ensure_trigger_templates(self) -> None:
|
|
214
|
-
"""Ensure all registered trigger templates exist in the database."""
|
|
215
|
-
for trigger in self.triggers:
|
|
216
|
-
existing = await self.database.get_trigger_template(trigger.id)
|
|
217
|
-
if not existing:
|
|
218
|
-
logger.info(
|
|
219
|
-
f"Creating new trigger template in database: {trigger.name} ({trigger.id})"
|
|
220
|
-
)
|
|
221
|
-
await self.database.create_trigger_template(
|
|
222
|
-
id=trigger.id,
|
|
223
|
-
provider=trigger.provider,
|
|
224
|
-
name=trigger.name,
|
|
225
|
-
description=trigger.description,
|
|
226
|
-
registration_schema=trigger.registration_model.model_json_schema(),
|
|
227
|
-
)
|
|
228
|
-
logger.info(
|
|
229
|
-
f"✓ Successfully created trigger template: {trigger.name} ({trigger.id})"
|
|
230
|
-
)
|
|
231
|
-
else:
|
|
232
|
-
logger.info(
|
|
233
|
-
f"✓ Trigger template already exists in database: {trigger.name} ({trigger.id})"
|
|
234
|
-
)
|
|
235
|
-
|
|
236
212
|
def add_triggers(self, triggers: list[TriggerTemplate]) -> None:
|
|
237
213
|
"""Add multiple triggers."""
|
|
238
214
|
for trigger in triggers:
|
|
@@ -251,19 +227,20 @@ class TriggerServer:
|
|
|
251
227
|
|
|
252
228
|
@self.app.get("/v1/triggers")
|
|
253
229
|
async def api_list_triggers() -> dict[str, Any]:
|
|
254
|
-
"""List available trigger templates."""
|
|
255
|
-
templates = await self.database.get_trigger_templates()
|
|
230
|
+
"""List available trigger templates from in-memory registry."""
|
|
256
231
|
trigger_list = []
|
|
257
|
-
for
|
|
232
|
+
for trigger in self.triggers:
|
|
258
233
|
trigger_list.append(
|
|
259
234
|
{
|
|
260
|
-
"id":
|
|
261
|
-
"provider":
|
|
262
|
-
"displayName":
|
|
263
|
-
"description":
|
|
235
|
+
"id": trigger.id,
|
|
236
|
+
"provider": trigger.provider,
|
|
237
|
+
"displayName": trigger.name,
|
|
238
|
+
"description": trigger.description,
|
|
264
239
|
"path": "/v1/triggers/registrations",
|
|
265
240
|
"method": "POST",
|
|
266
|
-
"payloadSchema":
|
|
241
|
+
"payloadSchema": trigger.registration_model.model_json_schema(),
|
|
242
|
+
"display_name": trigger.display_name,
|
|
243
|
+
"integration": trigger.integration,
|
|
267
244
|
}
|
|
268
245
|
)
|
|
269
246
|
|
|
@@ -292,7 +269,7 @@ class TriggerServer:
|
|
|
292
269
|
{
|
|
293
270
|
"id": reg["id"],
|
|
294
271
|
"user_id": reg["user_id"],
|
|
295
|
-
"template_id": reg.get("
|
|
272
|
+
"template_id": reg.get("template_id"),
|
|
296
273
|
"resource": reg["resource"],
|
|
297
274
|
"linked_agent_ids": reg.get("linked_agent_ids", []),
|
|
298
275
|
"created_at": reg["created_at"],
|
|
@@ -7,30 +7,6 @@ from typing import Any
|
|
|
7
7
|
class TriggerDatabaseInterface(ABC):
|
|
8
8
|
"""Abstract interface for trigger database operations."""
|
|
9
9
|
|
|
10
|
-
# ========== Trigger Templates ==========
|
|
11
|
-
|
|
12
|
-
@abstractmethod
|
|
13
|
-
async def create_trigger_template(
|
|
14
|
-
self,
|
|
15
|
-
id: str,
|
|
16
|
-
provider: str,
|
|
17
|
-
name: str,
|
|
18
|
-
description: str = None,
|
|
19
|
-
registration_schema: dict = None,
|
|
20
|
-
) -> dict[str, Any] | None:
|
|
21
|
-
"""Create a new trigger template."""
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
@abstractmethod
|
|
25
|
-
async def get_trigger_templates(self) -> list[dict[str, Any]]:
|
|
26
|
-
"""Get all available trigger templates."""
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
@abstractmethod
|
|
30
|
-
async def get_trigger_template(self, id: str) -> dict[str, Any] | None:
|
|
31
|
-
"""Get a specific trigger template by ID."""
|
|
32
|
-
pass
|
|
33
|
-
|
|
34
10
|
# ========== Trigger Registrations ==========
|
|
35
11
|
|
|
36
12
|
@abstractmethod
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/decorators.py
RENAMED
|
@@ -31,7 +31,25 @@ class TriggerTemplate:
|
|
|
31
31
|
trigger_type: TriggerType = TriggerType.WEBHOOK,
|
|
32
32
|
poll_handler: Any | None = None,
|
|
33
33
|
default_crontab: str | None = None,
|
|
34
|
+
display_name: str | None = None,
|
|
35
|
+
integration: str | None = None,
|
|
34
36
|
):
|
|
37
|
+
"""Initialize a trigger template.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
id: Unique identifier for the trigger
|
|
41
|
+
provider: (DEPRECATED: use display_name) Display name for grouping in UI
|
|
42
|
+
name: Human-readable name for the trigger
|
|
43
|
+
description: Description of what the trigger does
|
|
44
|
+
registration_model: Pydantic model for registration data
|
|
45
|
+
registration_handler: Async function to handle registration
|
|
46
|
+
trigger_handler: Async function to handle webhook events (for webhook triggers)
|
|
47
|
+
trigger_type: Type of trigger (webhook or polling)
|
|
48
|
+
poll_handler: Async function to handle polling (for polling triggers)
|
|
49
|
+
default_crontab: Default cron schedule for polling triggers
|
|
50
|
+
display_name: Display name for grouping triggers (e.g., "Slack", "Gmail")
|
|
51
|
+
integration: Integration ID for logo mapping (e.g., "slack", "gmail")
|
|
52
|
+
"""
|
|
35
53
|
self.id = id
|
|
36
54
|
self.provider = provider
|
|
37
55
|
self.name = name
|
|
@@ -42,6 +60,8 @@ class TriggerTemplate:
|
|
|
42
60
|
self.trigger_type = trigger_type
|
|
43
61
|
self.poll_handler = poll_handler
|
|
44
62
|
self.default_crontab = default_crontab
|
|
63
|
+
self.display_name = display_name
|
|
64
|
+
self.integration = integration
|
|
45
65
|
|
|
46
66
|
self._validate_handler_signatures()
|
|
47
67
|
|
|
@@ -121,7 +121,9 @@ async def cron_poll_handler(
|
|
|
121
121
|
headers=headers,
|
|
122
122
|
)
|
|
123
123
|
except Exception as thread_err:
|
|
124
|
-
logger.warning(
|
|
124
|
+
logger.warning(
|
|
125
|
+
f"cron_thread_create_failed thread_id={thread_id} error={str(thread_err)}"
|
|
126
|
+
)
|
|
125
127
|
|
|
126
128
|
await client.runs.create(
|
|
127
129
|
thread_id,
|
|
@@ -157,4 +159,6 @@ cron_trigger = TriggerTemplate(
|
|
|
157
159
|
registration_handler=cron_registration_handler,
|
|
158
160
|
trigger_type=TriggerType.POLLING,
|
|
159
161
|
poll_handler=cron_poll_handler,
|
|
162
|
+
display_name="Cron",
|
|
163
|
+
integration=None,
|
|
160
164
|
)
|
|
@@ -40,29 +40,9 @@ class MockDatabase:
|
|
|
40
40
|
"""Mock database for testing."""
|
|
41
41
|
|
|
42
42
|
def __init__(self):
|
|
43
|
-
self.templates = []
|
|
44
43
|
self.registrations = []
|
|
45
44
|
self.agent_links = []
|
|
46
45
|
|
|
47
|
-
async def create_trigger_template(
|
|
48
|
-
self, id, provider, name, description, registration_schema
|
|
49
|
-
):
|
|
50
|
-
template = {
|
|
51
|
-
"id": id,
|
|
52
|
-
"provider": provider,
|
|
53
|
-
"name": name,
|
|
54
|
-
"description": description,
|
|
55
|
-
"registration_schema": registration_schema,
|
|
56
|
-
}
|
|
57
|
-
self.templates.append(template)
|
|
58
|
-
return template
|
|
59
|
-
|
|
60
|
-
async def get_trigger_template(self, id):
|
|
61
|
-
return next((t for t in self.templates if t["id"] == id), None)
|
|
62
|
-
|
|
63
|
-
async def get_trigger_templates(self):
|
|
64
|
-
return self.templates
|
|
65
|
-
|
|
66
46
|
async def create_trigger_registration(
|
|
67
47
|
self, user_id, tenant_id, template_id, resource, metadata
|
|
68
48
|
):
|
|
@@ -83,7 +63,6 @@ class MockDatabase:
|
|
|
83
63
|
return [
|
|
84
64
|
{
|
|
85
65
|
**reg,
|
|
86
|
-
"trigger_templates": {"id": reg["template_id"]},
|
|
87
66
|
"linked_agent_ids": reg.get("linked_agent_ids", []),
|
|
88
67
|
}
|
|
89
68
|
for reg in self.registrations
|
|
@@ -233,15 +212,27 @@ async def test_health_endpoint(trigger_server):
|
|
|
233
212
|
|
|
234
213
|
@pytest.mark.asyncio
|
|
235
214
|
async def test_list_triggers_endpoint(trigger_server):
|
|
236
|
-
"""Test listing trigger templates."""
|
|
237
|
-
|
|
238
|
-
|
|
215
|
+
"""Test listing trigger templates from in-memory registry."""
|
|
216
|
+
from langchain_triggers import (
|
|
217
|
+
TriggerRegistrationResult,
|
|
218
|
+
TriggerTemplate,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# Create a test trigger registration handler
|
|
222
|
+
async def test_registration_handler(request, user_id, registration):
|
|
223
|
+
return TriggerRegistrationResult()
|
|
224
|
+
|
|
225
|
+
# Add a trigger template to the in-memory registry
|
|
226
|
+
test_trigger = TriggerTemplate(
|
|
239
227
|
id="test_trigger",
|
|
240
228
|
provider="test",
|
|
241
229
|
name="Test Trigger",
|
|
242
230
|
description="A test trigger",
|
|
243
|
-
|
|
231
|
+
registration_model=TestRegistration,
|
|
232
|
+
registration_handler=test_registration_handler,
|
|
233
|
+
trigger_handler=dummy_trigger_handler,
|
|
244
234
|
)
|
|
235
|
+
trigger_server.add_trigger(test_trigger)
|
|
245
236
|
|
|
246
237
|
transport = ASGITransport(app=trigger_server.app, raise_app_exceptions=True)
|
|
247
238
|
async with AsyncClient(base_url="http://localhost", transport=transport) as client:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Current: 0.3.9, PyPI: 0.3.8, Should publish: True
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Current: 0.3.8, PyPI: 0.3.7, Should publish: True
|
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/_lint.yml
RENAMED
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/_test.yml
RENAMED
|
File without changes
|
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/.github/workflows/release.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/core.py
RENAMED
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/cron_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{langchain_trigger_server-0.3.8 → langchain_trigger_server-0.3.9}/langchain_triggers/util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|