nornweave 0.1.2__py3-none-any.whl → 0.1.4__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.
- nornweave/adapters/resend.py +57 -7
- nornweave/core/config.py +50 -1
- nornweave/core/interfaces.py +63 -1
- nornweave/huginn/client.py +137 -8
- nornweave/huginn/resources.py +9 -0
- nornweave/huginn/server.py +148 -9
- nornweave/models/thread.py +2 -0
- nornweave/muninn/tools.py +267 -19
- nornweave/storage/database.py +1 -1
- nornweave/urdr/adapters/base.py +173 -3
- nornweave/urdr/migrations/versions/20260205_0003_llm_thread_summary.py +54 -0
- nornweave/urdr/orm.py +27 -1
- nornweave/verdandi/llm/__init__.py +52 -0
- nornweave/verdandi/llm/anthropic.py +63 -0
- nornweave/verdandi/llm/base.py +35 -0
- nornweave/verdandi/llm/gemini.py +78 -0
- nornweave/verdandi/llm/openai.py +60 -0
- nornweave/verdandi/parser.py +2 -1
- nornweave/verdandi/summarize.py +231 -0
- nornweave/yggdrasil/app.py +2 -1
- nornweave/yggdrasil/dependencies.py +11 -6
- nornweave/yggdrasil/routes/v1/attachments.py +317 -0
- nornweave/yggdrasil/routes/v1/messages.py +180 -20
- nornweave/yggdrasil/routes/v1/threads.py +4 -0
- nornweave/yggdrasil/routes/webhooks/mailgun.py +4 -0
- nornweave/yggdrasil/routes/webhooks/resend.py +76 -16
- {nornweave-0.1.2.dist-info → nornweave-0.1.4.dist-info}/METADATA +19 -1
- {nornweave-0.1.2.dist-info → nornweave-0.1.4.dist-info}/RECORD +31 -23
- {nornweave-0.1.2.dist-info → nornweave-0.1.4.dist-info}/WHEEL +0 -0
- {nornweave-0.1.2.dist-info → nornweave-0.1.4.dist-info}/entry_points.txt +0 -0
- {nornweave-0.1.2.dist-info → nornweave-0.1.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -13,9 +13,11 @@ from nornweave.core.config import Settings, get_settings
|
|
|
13
13
|
from nornweave.core.interfaces import (
|
|
14
14
|
StorageInterface, # noqa: TC001 - needed at runtime for FastAPI
|
|
15
15
|
)
|
|
16
|
+
from nornweave.core.storage import AttachmentMetadata, create_attachment_storage
|
|
16
17
|
from nornweave.models.message import Message, MessageDirection
|
|
17
18
|
from nornweave.models.thread import Thread
|
|
18
19
|
from nornweave.verdandi.parser import html_to_markdown
|
|
20
|
+
from nornweave.verdandi.summarize import generate_thread_summary
|
|
19
21
|
from nornweave.yggdrasil.dependencies import get_storage
|
|
20
22
|
|
|
21
23
|
router = APIRouter()
|
|
@@ -112,7 +114,7 @@ async def resend_webhook(
|
|
|
112
114
|
|
|
113
115
|
# Route based on event type
|
|
114
116
|
if event_type == "email.received":
|
|
115
|
-
return await _handle_inbound_email(adapter, payload, storage)
|
|
117
|
+
return await _handle_inbound_email(adapter, payload, storage, settings)
|
|
116
118
|
elif event_type in DELIVERY_EVENT_TYPES:
|
|
117
119
|
return _handle_delivery_event(event_type, payload)
|
|
118
120
|
else:
|
|
@@ -124,10 +126,12 @@ async def _handle_inbound_email(
|
|
|
124
126
|
adapter: ResendAdapter,
|
|
125
127
|
payload: dict[str, Any],
|
|
126
128
|
storage: StorageInterface,
|
|
129
|
+
settings: Settings,
|
|
127
130
|
) -> dict[str, str]:
|
|
128
131
|
"""Handle email.received event.
|
|
129
132
|
|
|
130
133
|
Fetches full email content from Resend API and stores the message.
|
|
134
|
+
Stores attachments using the configured storage backend.
|
|
131
135
|
"""
|
|
132
136
|
data = payload.get("data", {})
|
|
133
137
|
email_id = data.get("email_id", "unknown")
|
|
@@ -187,6 +191,22 @@ async def _handle_inbound_email(
|
|
|
187
191
|
|
|
188
192
|
logger.info("Found inbox %s for recipient %s", inbox.id, inbound.to_address)
|
|
189
193
|
|
|
194
|
+
# Check for duplicate webhook delivery (idempotency)
|
|
195
|
+
if inbound.message_id:
|
|
196
|
+
existing_msg = await storage.get_message_by_provider_id(inbox.id, inbound.message_id)
|
|
197
|
+
if existing_msg:
|
|
198
|
+
logger.info(
|
|
199
|
+
"Duplicate webhook detected: message %s already exists for provider_message_id %s",
|
|
200
|
+
existing_msg.id,
|
|
201
|
+
inbound.message_id,
|
|
202
|
+
)
|
|
203
|
+
return {
|
|
204
|
+
"status": "duplicate",
|
|
205
|
+
"message_id": existing_msg.id,
|
|
206
|
+
"thread_id": existing_msg.thread_id,
|
|
207
|
+
"email_id": email_id,
|
|
208
|
+
}
|
|
209
|
+
|
|
190
210
|
# Try to find existing thread by Message-ID references (for replies)
|
|
191
211
|
thread_id: str | None = None
|
|
192
212
|
|
|
@@ -256,21 +276,57 @@ async def _handle_inbound_email(
|
|
|
256
276
|
created_message = await storage.create_message(message)
|
|
257
277
|
logger.info("Created message %s in thread %s", created_message.id, thread_id)
|
|
258
278
|
|
|
259
|
-
# Store attachments if present
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
279
|
+
# Store attachments if present - using the configured storage backend
|
|
280
|
+
if inbound.attachments:
|
|
281
|
+
# Create storage backend for attachments
|
|
282
|
+
storage_backend = create_attachment_storage(settings)
|
|
283
|
+
|
|
284
|
+
for att in inbound.attachments:
|
|
285
|
+
if att.content and att.size_bytes > 0:
|
|
286
|
+
try:
|
|
287
|
+
# Generate attachment ID
|
|
288
|
+
attachment_id = str(uuid.uuid4())
|
|
289
|
+
|
|
290
|
+
# Create metadata for storage backend
|
|
291
|
+
metadata = AttachmentMetadata(
|
|
292
|
+
attachment_id=attachment_id,
|
|
293
|
+
message_id=created_message.id,
|
|
294
|
+
filename=att.filename,
|
|
295
|
+
content_type=att.content_type,
|
|
296
|
+
content_disposition=att.disposition.value,
|
|
297
|
+
content_id=att.content_id,
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# Store in configured backend (local, s3, gcs, or database)
|
|
301
|
+
storage_result = await storage_backend.store(
|
|
302
|
+
attachment_id=attachment_id,
|
|
303
|
+
content=att.content,
|
|
304
|
+
metadata=metadata,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
# Create database record with storage info
|
|
308
|
+
await storage.create_attachment(
|
|
309
|
+
message_id=created_message.id,
|
|
310
|
+
filename=att.filename,
|
|
311
|
+
content_type=att.content_type,
|
|
312
|
+
size_bytes=storage_result.size_bytes,
|
|
313
|
+
disposition=att.disposition.value,
|
|
314
|
+
content_id=att.content_id,
|
|
315
|
+
storage_path=storage_result.storage_key,
|
|
316
|
+
storage_backend=storage_result.backend,
|
|
317
|
+
content_hash=storage_result.content_hash,
|
|
318
|
+
# For database backend, also store the content
|
|
319
|
+
content=att.content if storage_result.backend == "database" else None,
|
|
320
|
+
)
|
|
321
|
+
logger.info(
|
|
322
|
+
"Stored attachment %s (%s, %d bytes) via %s backend",
|
|
323
|
+
att.filename,
|
|
324
|
+
att.content_type,
|
|
325
|
+
storage_result.size_bytes,
|
|
326
|
+
storage_result.backend,
|
|
327
|
+
)
|
|
328
|
+
except (ValueError, RuntimeError) as e:
|
|
329
|
+
logger.warning("Failed to store attachment %s: %s", att.filename, e)
|
|
274
330
|
|
|
275
331
|
# Update thread's last_message_at
|
|
276
332
|
if thread:
|
|
@@ -278,6 +334,10 @@ async def _handle_inbound_email(
|
|
|
278
334
|
thread.received_timestamp = created_message.created_at
|
|
279
335
|
await storage.update_thread(thread)
|
|
280
336
|
|
|
337
|
+
# Fire-and-forget thread summarization
|
|
338
|
+
if thread_id:
|
|
339
|
+
await generate_thread_summary(storage, thread_id)
|
|
340
|
+
|
|
281
341
|
result = {
|
|
282
342
|
"status": "received",
|
|
283
343
|
"message_id": created_message.id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nornweave
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Open-source, self-hosted Inbox-as-a-Service API for AI Agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/DataCovey/nornweave
|
|
6
6
|
Project-URL: Documentation, https://nornweave.datacovey.com/docs/
|
|
@@ -38,8 +38,12 @@ Requires-Dist: sqlalchemy[asyncio]>=2.0.36
|
|
|
38
38
|
Requires-Dist: svix>=1.24.0
|
|
39
39
|
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
40
40
|
Provides-Extra: all
|
|
41
|
+
Requires-Dist: anthropic>=0.42.0; extra == 'all'
|
|
41
42
|
Requires-Dist: asyncpg>=0.30.0; extra == 'all'
|
|
43
|
+
Requires-Dist: boto3>=1.35.0; extra == 'all'
|
|
42
44
|
Requires-Dist: fastmcp>=2.0.0; extra == 'all'
|
|
45
|
+
Requires-Dist: google-cloud-storage>=2.18.0; extra == 'all'
|
|
46
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'all'
|
|
43
47
|
Requires-Dist: mcp>=1.0.0; extra == 'all'
|
|
44
48
|
Requires-Dist: openai>=1.57.0; extra == 'all'
|
|
45
49
|
Requires-Dist: pgvector>=0.3.6; extra == 'all'
|
|
@@ -47,6 +51,8 @@ Requires-Dist: psycopg2-binary>=2.9.0; extra == 'all'
|
|
|
47
51
|
Requires-Dist: pypdf>=5.1.0; extra == 'all'
|
|
48
52
|
Requires-Dist: python-magic>=0.4.27; extra == 'all'
|
|
49
53
|
Requires-Dist: redis>=5.2.0; extra == 'all'
|
|
54
|
+
Provides-Extra: anthropic
|
|
55
|
+
Requires-Dist: anthropic>=0.42.0; extra == 'anthropic'
|
|
50
56
|
Provides-Extra: attachments
|
|
51
57
|
Requires-Dist: pypdf>=5.1.0; extra == 'attachments'
|
|
52
58
|
Requires-Dist: python-magic>=0.4.27; extra == 'attachments'
|
|
@@ -59,14 +65,26 @@ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
|
59
65
|
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
60
66
|
Requires-Dist: pytest>=8.3.0; extra == 'dev'
|
|
61
67
|
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
68
|
+
Provides-Extra: gcs
|
|
69
|
+
Requires-Dist: google-cloud-storage>=2.18.0; extra == 'gcs'
|
|
70
|
+
Provides-Extra: gemini
|
|
71
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'gemini'
|
|
72
|
+
Provides-Extra: llm
|
|
73
|
+
Requires-Dist: anthropic>=0.42.0; extra == 'llm'
|
|
74
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'llm'
|
|
75
|
+
Requires-Dist: openai>=1.57.0; extra == 'llm'
|
|
62
76
|
Provides-Extra: mcp
|
|
63
77
|
Requires-Dist: fastmcp>=2.0.0; extra == 'mcp'
|
|
64
78
|
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
|
|
79
|
+
Provides-Extra: openai
|
|
80
|
+
Requires-Dist: openai>=1.57.0; extra == 'openai'
|
|
65
81
|
Provides-Extra: postgres
|
|
66
82
|
Requires-Dist: asyncpg>=0.30.0; extra == 'postgres'
|
|
67
83
|
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'postgres'
|
|
68
84
|
Provides-Extra: ratelimit
|
|
69
85
|
Requires-Dist: redis>=5.2.0; extra == 'ratelimit'
|
|
86
|
+
Provides-Extra: s3
|
|
87
|
+
Requires-Dist: boto3>=1.35.0; extra == 's3'
|
|
70
88
|
Provides-Extra: search
|
|
71
89
|
Requires-Dist: openai>=1.57.0; extra == 'search'
|
|
72
90
|
Requires-Dist: pgvector>=0.3.6; extra == 'search'
|
|
@@ -3,28 +3,28 @@ nornweave/cli.py,sha256=zFrIjmruvh1YTthYbUsMfkjMb0Tk9cmUR-vYQ9naAK0,4231
|
|
|
3
3
|
nornweave/adapters/__init__.py,sha256=eBMqa9HmAuMZreZ0cca-xkxCS0yes247NQ8363pAkkc,38
|
|
4
4
|
nornweave/adapters/base.py,sha256=Dq68F1IZsUa87lY0J2goEh1Vog14w1XxmBzWPe6XOis,164
|
|
5
5
|
nornweave/adapters/mailgun.py,sha256=3YdKI7l-bdaF3HF_kJuGmKQQiraFUHTbmq4HL44W_fw,6756
|
|
6
|
-
nornweave/adapters/resend.py,sha256=
|
|
6
|
+
nornweave/adapters/resend.py,sha256=7GCN7ShXjPOO52c_qrr71ecHtpdfqRe5Yyur2-_rh18,19942
|
|
7
7
|
nornweave/adapters/sendgrid.py,sha256=dF_hmLAkEh1VQ8_O5OhcfCDhMAI-pEDF441im4DC9P4,17855
|
|
8
8
|
nornweave/adapters/ses.py,sha256=-6_ej9tILPkLjO5ujKEVQF8vHI0WhsiGY345FU7PN74,29683
|
|
9
9
|
nornweave/core/__init__.py,sha256=q-EsoqN07mZL67qbDEyBVxpAitvMVxiyVwkSxGZx868,533
|
|
10
|
-
nornweave/core/config.py,sha256=
|
|
10
|
+
nornweave/core/config.py,sha256=CutIB4UiL5RwUEhkTYpTzc0bEs9MF5s2BTQJurJKb-M,8305
|
|
11
11
|
nornweave/core/exceptions.py,sha256=Du1NKDpNxOLb75XUavI_Cc7IDOU3WdPnacqwG_8h14U,425
|
|
12
|
-
nornweave/core/interfaces.py,sha256=
|
|
12
|
+
nornweave/core/interfaces.py,sha256=IMmGAuU7-J3Zs44lUx3GveVBitPi2uywKGucHCTud0o,14258
|
|
13
13
|
nornweave/core/storage.py,sha256=MGxTyudFAYmPl7O2O_X68x3mkGu_lnUixRBdKYqiv0E,5234
|
|
14
14
|
nornweave/core/utils.py,sha256=FTiXmwf7iWIWSyo6DMUeu4MFfvGW-FnFNnqWrkiRlrs,696
|
|
15
15
|
nornweave/huginn/__init__.py,sha256=4mC_VL1ERiSoZXHpWD26efzqKwN20ED4GTHljJ8AGbs,338
|
|
16
|
-
nornweave/huginn/client.py,sha256=
|
|
16
|
+
nornweave/huginn/client.py,sha256=EjWSRQQMx8PM1q2tWp8qgfi9jvP6DFX9lOo5C2l-vzc,13688
|
|
17
17
|
nornweave/huginn/config.py,sha256=G1VE9bFtTaJAf-iipqxGkYnviq_yeHKOHySyc_w5tt4,1413
|
|
18
|
-
nornweave/huginn/resources.py,sha256
|
|
19
|
-
nornweave/huginn/server.py,sha256=
|
|
18
|
+
nornweave/huginn/resources.py,sha256=WsBntF9L2uDHwgL98ij0AjEkQK7NFf6XEosCL3ZSshA,5217
|
|
19
|
+
nornweave/huginn/server.py,sha256=8wbibOjuclQNAycRIOJJRnH77LobVkjnxlDPWFyOwVc,10084
|
|
20
20
|
nornweave/models/__init__.py,sha256=qHHVmAIstLJFQzZlYjp4k-KDz6Fs_YqvOl9BWOaejYY,2616
|
|
21
21
|
nornweave/models/attachment.py,sha256=TeeN3Fe42bo0DAyqBmOgAVOesVytKFJN6i45lz7C-7I,4021
|
|
22
22
|
nornweave/models/event.py,sha256=JmndUxsEJvoqMyBYJMNLh8ZDaIORcyDCHzo5vYNzjig,6772
|
|
23
23
|
nornweave/models/inbox.py,sha256=Vwpr2JZKep6BcBpWZNR9Ne_rHnIOvlOv97_GgyhV6U8,905
|
|
24
24
|
nornweave/models/message.py,sha256=m5rUc7TeKwLU7I7UZbCC2Wuk0u5yE95o943eL-SIPDI,10676
|
|
25
|
-
nornweave/models/thread.py,sha256=
|
|
25
|
+
nornweave/models/thread.py,sha256=ke_0b4_NHzYEMe7dHvNHyh-gyWchh0XkOyTYKv4L4qk,7299
|
|
26
26
|
nornweave/muninn/__init__.py,sha256=IoRWFRDDH8SesVsBbARQs1xGTQsqnQ-YDyTog8HnmyY,322
|
|
27
|
-
nornweave/muninn/tools.py,sha256=
|
|
27
|
+
nornweave/muninn/tools.py,sha256=VysbtgBbJ4ensmMCqJiCGCginkdczUEiY_OZdUrnBqg,14870
|
|
28
28
|
nornweave/search/__init__.py,sha256=qjj7B9j7oB3wKOtQa9qa8Z5XAAGVc1lMINFaxeP2ji0,33
|
|
29
29
|
nornweave/search/embeddings.py,sha256=BoHKqNGzgIztQ_dzoIxMtw43xJU3p2ALrG6rXreAHeA,57
|
|
30
30
|
nornweave/search/vector_store.py,sha256=xz2p0Tx7XIRIKEK-c3bE9Kv_II3XRbuWNjtWzfqTkrs,50
|
|
@@ -34,14 +34,14 @@ nornweave/skuld/scheduler.py,sha256=1PKSlfOCIEg6-J1Gy18eWkxHCrpV0UdL87foceVMUxE,
|
|
|
34
34
|
nornweave/skuld/sender.py,sha256=TFANid5iUasXZeHNjYgBG0qeG7hrdhKH8qguUgQ1H6w,585
|
|
35
35
|
nornweave/skuld/webhooks.py,sha256=i9FSTMyQfvGeNkFaaDwTfoBF1SnIlSMKjegBYuWvhq0,55
|
|
36
36
|
nornweave/storage/__init__.py,sha256=grAAxi_YamDxYOghqVS4DI6LTtaVfxd8lwPWhYhPzWA,623
|
|
37
|
-
nornweave/storage/database.py,sha256=
|
|
37
|
+
nornweave/storage/database.py,sha256=_QLTVRgrfZbGvPq-CS8Y9snaeDVUi9Kc0m--yRZwWcI,5328
|
|
38
38
|
nornweave/storage/gcs.py,sha256=tWIA6fbh-RTlIjP8XDQ5QHCXRXLrzpg7xv-F3Z1spWU,4471
|
|
39
39
|
nornweave/storage/local.py,sha256=mWfAa7tJxC9BxM35o4HnF9kQ4VxUjIs9s0FwdR7IQcI,4698
|
|
40
40
|
nornweave/storage/s3.py,sha256=5Fp9PO7lAPVD2kt1X6LtZ_7WJ5p11V4nfKRVx3amSUA,5126
|
|
41
41
|
nornweave/urdr/__init__.py,sha256=l6_ktIdR38XprrJysxNgt8nPeGwkjKhto40AdmlVs5g,363
|
|
42
|
-
nornweave/urdr/orm.py,sha256=
|
|
42
|
+
nornweave/urdr/orm.py,sha256=k48YvuJXAl5pdTwWZoTU1OBPjyMnQ7XUc9OcyhR7a3g,20725
|
|
43
43
|
nornweave/urdr/adapters/__init__.py,sha256=PxF3WsKO4P1PxUtQ0IBRt4Ie_QVgUs8Yp7GBBJKdzeE,461
|
|
44
|
-
nornweave/urdr/adapters/base.py,sha256=
|
|
44
|
+
nornweave/urdr/adapters/base.py,sha256=drQcVVE9yd4EKh4WzCcVPV6ont67EntdkjPKId0_Pmo,20736
|
|
45
45
|
nornweave/urdr/adapters/postgres.py,sha256=2gk52Dz2Ah6nxUOC44ucL5PHT6xViIbbuhbyBOVI3S4,1502
|
|
46
46
|
nornweave/urdr/adapters/sqlite.py,sha256=DopxiBZ-JMJrxxkzrjk3saYfkvcJwfXHbYNjpsn7rc4,1626
|
|
47
47
|
nornweave/urdr/migrations/env.py,sha256=NbmCO-73mj5gsNdTNgkXx0IveS3BKJFcLDRqt09BJMw,2596
|
|
@@ -49,32 +49,40 @@ nornweave/urdr/migrations/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9N
|
|
|
49
49
|
nornweave/urdr/migrations/versions/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
50
|
nornweave/urdr/migrations/versions/20260131_0001_initial_schema.py,sha256=0QLxVEhDlEX-zMFd2XqYvwj-L78dzq8bkQOXYxaDqMw,6004
|
|
51
51
|
nornweave/urdr/migrations/versions/20260131_0002_extended_schema.py,sha256=KaYoK5XjASYbhq8wxaA7D1dhw9xahLBI7-vjF6W8fFg,9502
|
|
52
|
+
nornweave/urdr/migrations/versions/20260205_0003_llm_thread_summary.py,sha256=z_cV2mfEkBWBRb1OpBQID3F5mxtETXHl7tiL_IkP7ME,1658
|
|
52
53
|
nornweave/verdandi/__init__.py,sha256=TegCxwFoPZgwXZxzilXi2n9aA9huF0Vnta3tahvdVvw,1033
|
|
53
54
|
nornweave/verdandi/attachments.py,sha256=oYytlfktR0WOzshx3xxmJrr3vnIVd5UeKjSGHcfvAxA,12659
|
|
54
55
|
nornweave/verdandi/content.py,sha256=C_S7IFJ_9WMcLlKmz5uiQ3x0DlKS8pVOsumvYZcMNME,11644
|
|
55
56
|
nornweave/verdandi/headers.py,sha256=Jb_3OGWa0oZj15qstl2qpLjW1qUPCS7dlWJ5Zw8gk0Q,10706
|
|
56
|
-
nornweave/verdandi/parser.py,sha256=
|
|
57
|
+
nornweave/verdandi/parser.py,sha256=TDWyzm2lUY6CCA4M5rKDJUnozFon4NArXgvnrjb31Wk,686
|
|
57
58
|
nornweave/verdandi/sanitizer.py,sha256=aLDiuslCkuBDgAhPKDDTaHtG51MWIRAbjDEzpN1cNQo,296
|
|
59
|
+
nornweave/verdandi/summarize.py,sha256=hrxCcyxGe3l2z_ZaOQqPzct1Lg76vfep9XI5HvAd1Ys,7504
|
|
58
60
|
nornweave/verdandi/threading.py,sha256=8XWVphAFDAPEMQZ-EzJPZiYcRhnkUuRwyb9-_oNdsmQ,10543
|
|
61
|
+
nornweave/verdandi/llm/__init__.py,sha256=JDtH2gQxWbLcs-y7FJZdtdUmbJDpYKCOhWMEe2ZDXEc,1680
|
|
62
|
+
nornweave/verdandi/llm/anthropic.py,sha256=9r8B5NhXgGyeSgQ94U6jfwfy6VJGsikrNYc-AI2U6vM,1936
|
|
63
|
+
nornweave/verdandi/llm/base.py,sha256=dqXwPP6sfcByfJjeeoKyGkMelX-mK3H7am1k4Kd7iOs,827
|
|
64
|
+
nornweave/verdandi/llm/gemini.py,sha256=NOJZ1hn5b9LXDurHtutDYULJrAbtegnIOUnZ6VO3CA0,2758
|
|
65
|
+
nornweave/verdandi/llm/openai.py,sha256=r7IGf2O-zRmkNzZUi6htHwTjCro7OeFwlSZAyoMAviA,1949
|
|
59
66
|
nornweave/yggdrasil/__init__.py,sha256=AmtQ0PBXOqLWnaEXN4c4it0JzsbhPR4ACdTgsTZ0_Ak,41
|
|
60
|
-
nornweave/yggdrasil/app.py,sha256=
|
|
61
|
-
nornweave/yggdrasil/dependencies.py,sha256=
|
|
67
|
+
nornweave/yggdrasil/app.py,sha256=UzWFTd2HlQ1AhN3wVosar7dUemI3PyFada82pXSaa0w,2688
|
|
68
|
+
nornweave/yggdrasil/dependencies.py,sha256=TgrJXYEdBPCNkVmwbvgm36_Tdvkvtpr2g4M2avz4Vxw,6579
|
|
62
69
|
nornweave/yggdrasil/middleware/__init__.py,sha256=epGY0eVYG4p8CSN2HrDVr3D34E_Vj_ZhKhHtSvZfuBo,33
|
|
63
70
|
nornweave/yggdrasil/middleware/auth.py,sha256=v-JDrb3jIicrjg_QchHeiYgfnpIIiM31SHGdioBFaEk,54
|
|
64
71
|
nornweave/yggdrasil/middleware/logging.py,sha256=AxAWfVLorrR6OWRfNHm6RP3QgG0UhIOsNyYKkaKLWTw,56
|
|
65
72
|
nornweave/yggdrasil/routes/__init__.py,sha256=B_IMQ-HRZVaz2X6OonhdX1ksEtIi2xOmtBA7Dsm3wlU,18
|
|
66
73
|
nornweave/yggdrasil/routes/v1/__init__.py,sha256=DLf9PHY_O_gzj4lXg-Gq_Qh_i4b0DQ27z3_6S-FjyAw,26
|
|
74
|
+
nornweave/yggdrasil/routes/v1/attachments.py,sha256=JKh56GFXiHsnDM0S5GRZR4uCSwN1VgQOBCMwHufOWQQ,11052
|
|
67
75
|
nornweave/yggdrasil/routes/v1/inboxes.py,sha256=8R8bmbwmM4V25iAhwKL7ZphRjqvJYN9KQhRq-3FiIH0,3506
|
|
68
|
-
nornweave/yggdrasil/routes/v1/messages.py,sha256=
|
|
76
|
+
nornweave/yggdrasil/routes/v1/messages.py,sha256=E_TBatWen77bf4Xn4noUqcRfNqx_gU7t_hCeAEBKes4,12493
|
|
69
77
|
nornweave/yggdrasil/routes/v1/search.py,sha256=5rMC99H8YNDK9gYzsg2gc_fLnWHiogXTTByXh05_0ek,2293
|
|
70
|
-
nornweave/yggdrasil/routes/v1/threads.py,sha256=
|
|
78
|
+
nornweave/yggdrasil/routes/v1/threads.py,sha256=N9PRhKsD7C-AeUAVKOj21URkn_4bFr8PRPR8HzbtXlo,4212
|
|
71
79
|
nornweave/yggdrasil/routes/webhooks/__init__.py,sha256=Kt9atFe_bmd0784Ug7QDI04VnLcKJ4vEAynjYdVWWuM,47
|
|
72
|
-
nornweave/yggdrasil/routes/webhooks/mailgun.py,sha256=
|
|
73
|
-
nornweave/yggdrasil/routes/webhooks/resend.py,sha256=
|
|
80
|
+
nornweave/yggdrasil/routes/webhooks/mailgun.py,sha256=ccxcp-_TrBkK05Lne4Sg5iZ-nvzNHs0a-GpzJV4qUt8,5213
|
|
81
|
+
nornweave/yggdrasil/routes/webhooks/resend.py,sha256=gaHbmCsfxkeeIK9xGCUcBwo3a80wHcmdsQfE3IgJGsY,15095
|
|
74
82
|
nornweave/yggdrasil/routes/webhooks/sendgrid.py,sha256=ABcpjRTJ8QE2h9_vzhfXtCwOyL_UEVObrghWwQoPyvc,465
|
|
75
83
|
nornweave/yggdrasil/routes/webhooks/ses.py,sha256=c0cUs_DLjHGTXW26Dp20xQ76-SKZ9uzLTRNQlp6G06M,472
|
|
76
|
-
nornweave-0.1.
|
|
77
|
-
nornweave-0.1.
|
|
78
|
-
nornweave-0.1.
|
|
79
|
-
nornweave-0.1.
|
|
80
|
-
nornweave-0.1.
|
|
84
|
+
nornweave-0.1.4.dist-info/METADATA,sha256=SyA_dLtgN2raDaQgpbZ7umriLrvP5wgRxVj7YhWgMeI,11097
|
|
85
|
+
nornweave-0.1.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
86
|
+
nornweave-0.1.4.dist-info/entry_points.txt,sha256=0FFL4MJSIBy8S2YJ5fUpAQbTyH5D5c30rEM6KTc93yk,112
|
|
87
|
+
nornweave-0.1.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
88
|
+
nornweave-0.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|