lumera 0.24.2__tar.gz → 0.24.4__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.
- {lumera-0.24.2 → lumera-0.24.4}/PKG-INFO +1 -1
- {lumera-0.24.2 → lumera-0.24.4}/lumera/_utils.py +7 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/webhooks.py +11 -13
- {lumera-0.24.2 → lumera-0.24.4}/lumera.egg-info/PKG-INFO +1 -1
- {lumera-0.24.2 → lumera-0.24.4}/pyproject.toml +1 -1
- {lumera-0.24.2 → lumera-0.24.4}/tests/test_sdk.py +20 -0
- {lumera-0.24.2 → lumera-0.24.4}/tests/test_webhooks.py +2 -2
- {lumera-0.24.2 → lumera-0.24.4}/lumera/__init__.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/_live.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/agents.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/automations.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/email.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/exceptions.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/files.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/google.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/integrations/__init__.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/integrations/google.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/integrations/netsuite.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/integrations/slack.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/llm.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/pb.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/sdk.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera/storage.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera.egg-info/SOURCES.txt +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera.egg-info/dependency_links.txt +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera.egg-info/requires.txt +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/lumera.egg-info/top_level.txt +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/setup.cfg +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/tests/test_agents_live.py +0 -0
- {lumera-0.24.2 → lumera-0.24.4}/tests/test_automations.py +0 -0
|
@@ -692,6 +692,13 @@ def _api_headers(
|
|
|
692
692
|
if _project_eid:
|
|
693
693
|
headers["X-Lumera-Project"] = _project_eid
|
|
694
694
|
|
|
695
|
+
# User context: forward the human driving an agent turn so the backend
|
|
696
|
+
# attributes mutations to the user (with the agent preserved). Honored only
|
|
697
|
+
# for agent tokens; ignored otherwise. Mirrors the CLI and the lumera_api tool.
|
|
698
|
+
_user_id = os.getenv("LUMERA_USER_ID", "").strip()
|
|
699
|
+
if _user_id:
|
|
700
|
+
headers["X-Lumera-User-Id"] = _user_id
|
|
701
|
+
|
|
695
702
|
return headers
|
|
696
703
|
|
|
697
704
|
|
|
@@ -118,10 +118,13 @@ def create(
|
|
|
118
118
|
if description is not None:
|
|
119
119
|
payload["description"] = description.strip()
|
|
120
120
|
|
|
121
|
-
result = _api_request("POST",
|
|
121
|
+
result = _api_request("POST", "webhook-endpoints", json_body=payload)
|
|
122
122
|
if not isinstance(result, dict):
|
|
123
123
|
raise RuntimeError("unexpected response payload")
|
|
124
|
-
|
|
124
|
+
endpoint = result.get("endpoint")
|
|
125
|
+
if not isinstance(endpoint, dict):
|
|
126
|
+
raise RuntimeError("unexpected response payload")
|
|
127
|
+
return endpoint
|
|
125
128
|
|
|
126
129
|
|
|
127
130
|
def list(
|
|
@@ -233,10 +236,6 @@ def update(
|
|
|
233
236
|
if not external_id:
|
|
234
237
|
raise ValueError("external_id is required")
|
|
235
238
|
|
|
236
|
-
# First, find the endpoint to get its record ID
|
|
237
|
-
endpoint = get(external_id)
|
|
238
|
-
record_id = endpoint["id"]
|
|
239
|
-
|
|
240
239
|
payload: dict[str, Any] = {}
|
|
241
240
|
if name is not None:
|
|
242
241
|
payload["name"] = name.strip()
|
|
@@ -247,11 +246,14 @@ def update(
|
|
|
247
246
|
raise ValueError("at least one field (name or description) must be provided")
|
|
248
247
|
|
|
249
248
|
result = _api_request(
|
|
250
|
-
"PATCH", f"
|
|
249
|
+
"PATCH", f"webhook-endpoints/{external_id}", json_body=payload
|
|
251
250
|
)
|
|
252
251
|
if not isinstance(result, dict):
|
|
253
252
|
raise RuntimeError("unexpected response payload")
|
|
254
|
-
|
|
253
|
+
endpoint = result.get("endpoint")
|
|
254
|
+
if not isinstance(endpoint, dict):
|
|
255
|
+
raise RuntimeError("unexpected response payload")
|
|
256
|
+
return endpoint
|
|
255
257
|
|
|
256
258
|
|
|
257
259
|
def delete(external_id: str) -> None:
|
|
@@ -271,11 +273,7 @@ def delete(external_id: str) -> None:
|
|
|
271
273
|
if not external_id:
|
|
272
274
|
raise ValueError("external_id is required")
|
|
273
275
|
|
|
274
|
-
|
|
275
|
-
endpoint = get(external_id)
|
|
276
|
-
record_id = endpoint["id"]
|
|
277
|
-
|
|
278
|
-
_api_request("DELETE", f"collections/{_COLLECTION}/records/{record_id}")
|
|
276
|
+
_api_request("DELETE", f"webhook-endpoints/{external_id}")
|
|
279
277
|
|
|
280
278
|
|
|
281
279
|
def url(external_id: str) -> str:
|
|
@@ -162,6 +162,26 @@ def test_expected_test_error_env_adds_header(monkeypatch: pytest.MonkeyPatch) ->
|
|
|
162
162
|
assert headers[_utils.EXPECTED_TEST_HEADER] == "true"
|
|
163
163
|
|
|
164
164
|
|
|
165
|
+
def test_api_headers_forwards_user_id(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
166
|
+
monkeypatch.setenv(sdk.TOKEN_ENV, "tok")
|
|
167
|
+
monkeypatch.setenv("LUMERA_USER_ID", " mem_human ")
|
|
168
|
+
|
|
169
|
+
headers = _utils._api_headers()
|
|
170
|
+
|
|
171
|
+
# Trimmed and forwarded so the backend can attribute agent-made mutations
|
|
172
|
+
# to the human (with the agent preserved).
|
|
173
|
+
assert headers["X-Lumera-User-Id"] == "mem_human"
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def test_api_headers_omits_user_id_when_unset(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
177
|
+
monkeypatch.setenv(sdk.TOKEN_ENV, "tok")
|
|
178
|
+
monkeypatch.delenv("LUMERA_USER_ID", raising=False)
|
|
179
|
+
|
|
180
|
+
headers = _utils._api_headers()
|
|
181
|
+
|
|
182
|
+
assert "X-Lumera-User-Id" not in headers
|
|
183
|
+
|
|
184
|
+
|
|
165
185
|
def test_api_request_wrapper_delegates(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
166
186
|
captured: dict[str, object] = {}
|
|
167
187
|
|
|
@@ -15,7 +15,7 @@ def test_create_posts_payload_when_project_context_exists(monkeypatch):
|
|
|
15
15
|
|
|
16
16
|
def fake_api(method, path, **kwargs):
|
|
17
17
|
calls.append((method, path, kwargs))
|
|
18
|
-
return {"id": "rec_123", **kwargs["json_body"]}
|
|
18
|
+
return {"endpoint": {"id": "rec_123", **kwargs["json_body"]}}
|
|
19
19
|
|
|
20
20
|
monkeypatch.setenv("LUMERA_PROJECT_EXTERNAL_ID", "project-a")
|
|
21
21
|
monkeypatch.setattr(webhooks, "_api_request", fake_api)
|
|
@@ -30,7 +30,7 @@ def test_create_posts_payload_when_project_context_exists(monkeypatch):
|
|
|
30
30
|
assert calls == [
|
|
31
31
|
(
|
|
32
32
|
"POST",
|
|
33
|
-
"
|
|
33
|
+
"webhook-endpoints",
|
|
34
34
|
{
|
|
35
35
|
"json_body": {
|
|
36
36
|
"name": "Stripe Events",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|