roomkit 0.1.0__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.
- roomkit/AGENTS.md +362 -0
- roomkit/__init__.py +372 -0
- roomkit/_version.py +1 -0
- roomkit/ai_docs.py +93 -0
- roomkit/channels/__init__.py +194 -0
- roomkit/channels/ai.py +238 -0
- roomkit/channels/base.py +66 -0
- roomkit/channels/transport.py +115 -0
- roomkit/channels/websocket.py +85 -0
- roomkit/core/__init__.py +0 -0
- roomkit/core/_channel_ops.py +252 -0
- roomkit/core/_helpers.py +296 -0
- roomkit/core/_inbound.py +435 -0
- roomkit/core/_room_lifecycle.py +275 -0
- roomkit/core/circuit_breaker.py +84 -0
- roomkit/core/event_router.py +401 -0
- roomkit/core/framework.py +793 -0
- roomkit/core/hooks.py +232 -0
- roomkit/core/inbound_router.py +57 -0
- roomkit/core/locks.py +66 -0
- roomkit/core/rate_limiter.py +67 -0
- roomkit/core/retry.py +49 -0
- roomkit/core/router.py +24 -0
- roomkit/core/transcoder.py +85 -0
- roomkit/identity/__init__.py +0 -0
- roomkit/identity/base.py +27 -0
- roomkit/identity/mock.py +49 -0
- roomkit/llms.txt +52 -0
- roomkit/models/__init__.py +104 -0
- roomkit/models/channel.py +99 -0
- roomkit/models/context.py +35 -0
- roomkit/models/delivery.py +76 -0
- roomkit/models/enums.py +170 -0
- roomkit/models/event.py +203 -0
- roomkit/models/framework_event.py +19 -0
- roomkit/models/hook.py +68 -0
- roomkit/models/identity.py +81 -0
- roomkit/models/participant.py +34 -0
- roomkit/models/room.py +33 -0
- roomkit/models/task.py +36 -0
- roomkit/providers/__init__.py +0 -0
- roomkit/providers/ai/__init__.py +0 -0
- roomkit/providers/ai/base.py +140 -0
- roomkit/providers/ai/mock.py +33 -0
- roomkit/providers/anthropic/__init__.py +6 -0
- roomkit/providers/anthropic/ai.py +145 -0
- roomkit/providers/anthropic/config.py +14 -0
- roomkit/providers/elasticemail/__init__.py +6 -0
- roomkit/providers/elasticemail/config.py +16 -0
- roomkit/providers/elasticemail/email.py +97 -0
- roomkit/providers/email/__init__.py +0 -0
- roomkit/providers/email/base.py +46 -0
- roomkit/providers/email/mock.py +34 -0
- roomkit/providers/gemini/__init__.py +6 -0
- roomkit/providers/gemini/ai.py +153 -0
- roomkit/providers/gemini/config.py +14 -0
- roomkit/providers/http/__init__.py +15 -0
- roomkit/providers/http/base.py +33 -0
- roomkit/providers/http/config.py +14 -0
- roomkit/providers/http/mock.py +21 -0
- roomkit/providers/http/provider.py +105 -0
- roomkit/providers/http/webhook.py +33 -0
- roomkit/providers/messenger/__init__.py +15 -0
- roomkit/providers/messenger/base.py +33 -0
- roomkit/providers/messenger/config.py +17 -0
- roomkit/providers/messenger/facebook.py +95 -0
- roomkit/providers/messenger/mock.py +21 -0
- roomkit/providers/messenger/webhook.py +42 -0
- roomkit/providers/openai/__init__.py +6 -0
- roomkit/providers/openai/ai.py +155 -0
- roomkit/providers/openai/config.py +24 -0
- roomkit/providers/pydantic_ai/__init__.py +5 -0
- roomkit/providers/pydantic_ai/config.py +14 -0
- roomkit/providers/rcs/__init__.py +9 -0
- roomkit/providers/rcs/base.py +95 -0
- roomkit/providers/rcs/mock.py +78 -0
- roomkit/providers/sendgrid/__init__.py +5 -0
- roomkit/providers/sendgrid/config.py +13 -0
- roomkit/providers/sinch/__init__.py +6 -0
- roomkit/providers/sinch/config.py +22 -0
- roomkit/providers/sinch/sms.py +192 -0
- roomkit/providers/sms/__init__.py +15 -0
- roomkit/providers/sms/base.py +67 -0
- roomkit/providers/sms/meta.py +401 -0
- roomkit/providers/sms/mock.py +24 -0
- roomkit/providers/sms/phone.py +77 -0
- roomkit/providers/telnyx/__init__.py +21 -0
- roomkit/providers/telnyx/config.py +14 -0
- roomkit/providers/telnyx/rcs.py +352 -0
- roomkit/providers/telnyx/sms.py +231 -0
- roomkit/providers/twilio/__init__.py +18 -0
- roomkit/providers/twilio/config.py +19 -0
- roomkit/providers/twilio/rcs.py +183 -0
- roomkit/providers/twilio/sms.py +200 -0
- roomkit/providers/voicemeup/__init__.py +15 -0
- roomkit/providers/voicemeup/config.py +21 -0
- roomkit/providers/voicemeup/sms.py +374 -0
- roomkit/providers/whatsapp/__init__.py +0 -0
- roomkit/providers/whatsapp/base.py +44 -0
- roomkit/providers/whatsapp/mock.py +21 -0
- roomkit/py.typed +0 -0
- roomkit/realtime/__init__.py +17 -0
- roomkit/realtime/base.py +111 -0
- roomkit/realtime/memory.py +158 -0
- roomkit/sources/__init__.py +35 -0
- roomkit/sources/base.py +207 -0
- roomkit/sources/websocket.py +260 -0
- roomkit/store/__init__.py +0 -0
- roomkit/store/base.py +230 -0
- roomkit/store/memory.py +293 -0
- roomkit-0.1.0.dist-info/METADATA +567 -0
- roomkit-0.1.0.dist-info/RECORD +114 -0
- roomkit-0.1.0.dist-info/WHEEL +4 -0
- roomkit-0.1.0.dist-info/licenses/LICENSE +21 -0
roomkit/__init__.py
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"""RoomKit - Pure async Python library for multi-channel conversations."""
|
|
2
|
+
|
|
3
|
+
from roomkit._version import __version__
|
|
4
|
+
from roomkit.channels import (
|
|
5
|
+
EmailChannel,
|
|
6
|
+
HTTPChannel,
|
|
7
|
+
MessengerChannel,
|
|
8
|
+
RCSChannel,
|
|
9
|
+
SMSChannel,
|
|
10
|
+
WhatsAppChannel,
|
|
11
|
+
)
|
|
12
|
+
from roomkit.channels.ai import AIChannel
|
|
13
|
+
from roomkit.channels.base import Channel
|
|
14
|
+
from roomkit.channels.transport import TransportChannel
|
|
15
|
+
from roomkit.channels.websocket import WebSocketChannel
|
|
16
|
+
from roomkit.core.framework import (
|
|
17
|
+
ChannelNotFoundError,
|
|
18
|
+
ChannelNotRegisteredError,
|
|
19
|
+
IdentityNotFoundError,
|
|
20
|
+
ParticipantNotFoundError,
|
|
21
|
+
RoomKit,
|
|
22
|
+
RoomKitError,
|
|
23
|
+
RoomNotFoundError,
|
|
24
|
+
SourceAlreadyAttachedError,
|
|
25
|
+
SourceNotFoundError,
|
|
26
|
+
)
|
|
27
|
+
from roomkit.core.hooks import HookEngine, HookRegistration
|
|
28
|
+
from roomkit.core.inbound_router import DefaultInboundRoomRouter, InboundRoomRouter
|
|
29
|
+
from roomkit.core.locks import InMemoryLockManager, RoomLockManager
|
|
30
|
+
from roomkit.identity.base import IdentityResolver
|
|
31
|
+
from roomkit.identity.mock import MockIdentityResolver
|
|
32
|
+
from roomkit.models.channel import (
|
|
33
|
+
ChannelBinding,
|
|
34
|
+
ChannelCapabilities,
|
|
35
|
+
ChannelOutput,
|
|
36
|
+
RateLimit,
|
|
37
|
+
RetryPolicy,
|
|
38
|
+
)
|
|
39
|
+
from roomkit.models.context import RoomContext
|
|
40
|
+
from roomkit.models.delivery import (
|
|
41
|
+
DeliveryResult,
|
|
42
|
+
DeliveryStatus,
|
|
43
|
+
InboundMessage,
|
|
44
|
+
InboundResult,
|
|
45
|
+
ProviderResult,
|
|
46
|
+
)
|
|
47
|
+
from roomkit.models.enums import (
|
|
48
|
+
Access,
|
|
49
|
+
ChannelCategory,
|
|
50
|
+
ChannelDirection,
|
|
51
|
+
ChannelMediaType,
|
|
52
|
+
ChannelType,
|
|
53
|
+
DeliveryMode,
|
|
54
|
+
EventStatus,
|
|
55
|
+
EventType,
|
|
56
|
+
HookExecution,
|
|
57
|
+
HookTrigger,
|
|
58
|
+
IdentificationStatus,
|
|
59
|
+
ParticipantRole,
|
|
60
|
+
ParticipantStatus,
|
|
61
|
+
RoomStatus,
|
|
62
|
+
TaskStatus,
|
|
63
|
+
)
|
|
64
|
+
from roomkit.models.event import (
|
|
65
|
+
AudioContent,
|
|
66
|
+
CompositeContent,
|
|
67
|
+
EventContent,
|
|
68
|
+
EventSource,
|
|
69
|
+
LocationContent,
|
|
70
|
+
MediaContent,
|
|
71
|
+
RichContent,
|
|
72
|
+
RoomEvent,
|
|
73
|
+
SystemContent,
|
|
74
|
+
TemplateContent,
|
|
75
|
+
TextContent,
|
|
76
|
+
VideoContent,
|
|
77
|
+
)
|
|
78
|
+
from roomkit.models.framework_event import FrameworkEvent
|
|
79
|
+
from roomkit.models.hook import HookResult, InjectedEvent
|
|
80
|
+
from roomkit.models.identity import Identity, IdentityHookResult, IdentityResult
|
|
81
|
+
from roomkit.models.participant import Participant
|
|
82
|
+
from roomkit.models.room import Room, RoomTimers
|
|
83
|
+
from roomkit.models.task import Observation, Task
|
|
84
|
+
from roomkit.providers.ai.base import (
|
|
85
|
+
AIContext,
|
|
86
|
+
AIImagePart,
|
|
87
|
+
AIMessage,
|
|
88
|
+
AIProvider,
|
|
89
|
+
AIResponse,
|
|
90
|
+
AITextPart,
|
|
91
|
+
AITool,
|
|
92
|
+
AIToolCall,
|
|
93
|
+
ProviderError,
|
|
94
|
+
)
|
|
95
|
+
from roomkit.providers.ai.mock import MockAIProvider
|
|
96
|
+
from roomkit.providers.anthropic.ai import AnthropicAIProvider
|
|
97
|
+
from roomkit.providers.anthropic.config import AnthropicConfig
|
|
98
|
+
from roomkit.providers.elasticemail.config import ElasticEmailConfig
|
|
99
|
+
from roomkit.providers.elasticemail.email import ElasticEmailProvider
|
|
100
|
+
from roomkit.providers.email.base import EmailProvider
|
|
101
|
+
from roomkit.providers.email.mock import MockEmailProvider
|
|
102
|
+
from roomkit.providers.gemini.ai import GeminiAIProvider
|
|
103
|
+
from roomkit.providers.gemini.config import GeminiConfig
|
|
104
|
+
from roomkit.providers.http.base import HTTPProvider
|
|
105
|
+
from roomkit.providers.http.config import HTTPProviderConfig
|
|
106
|
+
from roomkit.providers.http.mock import MockHTTPProvider
|
|
107
|
+
from roomkit.providers.http.provider import WebhookHTTPProvider
|
|
108
|
+
from roomkit.providers.http.webhook import parse_http_webhook
|
|
109
|
+
from roomkit.providers.messenger.base import MessengerProvider
|
|
110
|
+
from roomkit.providers.messenger.config import MessengerConfig
|
|
111
|
+
from roomkit.providers.messenger.facebook import FacebookMessengerProvider
|
|
112
|
+
from roomkit.providers.messenger.mock import MockMessengerProvider
|
|
113
|
+
from roomkit.providers.messenger.webhook import parse_messenger_webhook
|
|
114
|
+
from roomkit.providers.openai.ai import OpenAIAIProvider
|
|
115
|
+
from roomkit.providers.openai.config import OpenAIConfig
|
|
116
|
+
from roomkit.providers.rcs.base import RCSDeliveryResult, RCSProvider
|
|
117
|
+
from roomkit.providers.rcs.mock import MockRCSProvider
|
|
118
|
+
from roomkit.providers.sinch.config import SinchConfig
|
|
119
|
+
from roomkit.providers.sinch.sms import SinchSMSProvider, parse_sinch_webhook
|
|
120
|
+
from roomkit.providers.sms.base import SMSProvider
|
|
121
|
+
from roomkit.providers.sms.meta import WebhookMeta, extract_sms_meta
|
|
122
|
+
from roomkit.providers.sms.mock import MockSMSProvider
|
|
123
|
+
from roomkit.providers.sms.phone import is_valid_phone, normalize_phone
|
|
124
|
+
from roomkit.providers.telnyx.config import TelnyxConfig
|
|
125
|
+
from roomkit.providers.telnyx.rcs import (
|
|
126
|
+
TelnyxRCSConfig,
|
|
127
|
+
TelnyxRCSProvider,
|
|
128
|
+
parse_telnyx_rcs_webhook,
|
|
129
|
+
)
|
|
130
|
+
from roomkit.providers.telnyx.sms import (
|
|
131
|
+
TelnyxSMSProvider,
|
|
132
|
+
parse_telnyx_webhook,
|
|
133
|
+
)
|
|
134
|
+
from roomkit.providers.twilio.config import TwilioConfig
|
|
135
|
+
from roomkit.providers.twilio.rcs import (
|
|
136
|
+
TwilioRCSConfig,
|
|
137
|
+
TwilioRCSProvider,
|
|
138
|
+
parse_twilio_rcs_webhook,
|
|
139
|
+
)
|
|
140
|
+
from roomkit.providers.twilio.sms import TwilioSMSProvider, parse_twilio_webhook
|
|
141
|
+
from roomkit.providers.voicemeup.config import VoiceMeUpConfig
|
|
142
|
+
from roomkit.providers.voicemeup.sms import (
|
|
143
|
+
VoiceMeUpSMSProvider,
|
|
144
|
+
configure_voicemeup_mms,
|
|
145
|
+
parse_voicemeup_webhook,
|
|
146
|
+
)
|
|
147
|
+
from roomkit.providers.whatsapp.base import WhatsAppProvider
|
|
148
|
+
from roomkit.providers.whatsapp.mock import MockWhatsAppProvider
|
|
149
|
+
from roomkit.realtime.base import (
|
|
150
|
+
EphemeralCallback,
|
|
151
|
+
EphemeralEvent,
|
|
152
|
+
EphemeralEventType,
|
|
153
|
+
RealtimeBackend,
|
|
154
|
+
)
|
|
155
|
+
from roomkit.realtime.memory import InMemoryRealtime
|
|
156
|
+
from roomkit.sources.base import (
|
|
157
|
+
BaseSourceProvider,
|
|
158
|
+
EmitCallback,
|
|
159
|
+
SourceHealth,
|
|
160
|
+
SourceProvider,
|
|
161
|
+
SourceStatus,
|
|
162
|
+
)
|
|
163
|
+
from roomkit.store.base import ConversationStore
|
|
164
|
+
from roomkit.store.memory import InMemoryStore
|
|
165
|
+
|
|
166
|
+
# AI documentation helpers (lazy import to avoid file I/O at import time)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def get_llms_txt() -> str:
|
|
170
|
+
"""Get the contents of llms.txt for LLM consumption."""
|
|
171
|
+
from roomkit.ai_docs import get_llms_txt as _get_llms_txt
|
|
172
|
+
|
|
173
|
+
return _get_llms_txt()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def get_agents_md() -> str:
|
|
177
|
+
"""Get the contents of AGENTS.md for AI coding assistants."""
|
|
178
|
+
from roomkit.ai_docs import get_agents_md as _get_agents_md
|
|
179
|
+
|
|
180
|
+
return _get_agents_md()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def get_ai_context() -> str:
|
|
184
|
+
"""Get combined AI context (AGENTS.md + llms.txt)."""
|
|
185
|
+
from roomkit.ai_docs import get_ai_context as _get_ai_context
|
|
186
|
+
|
|
187
|
+
return _get_ai_context()
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
__all__ = [
|
|
191
|
+
"__version__",
|
|
192
|
+
# Core
|
|
193
|
+
"RoomKit",
|
|
194
|
+
"RoomKitError",
|
|
195
|
+
"RoomNotFoundError",
|
|
196
|
+
"ChannelNotFoundError",
|
|
197
|
+
"ChannelNotRegisteredError",
|
|
198
|
+
"ParticipantNotFoundError",
|
|
199
|
+
"IdentityNotFoundError",
|
|
200
|
+
"SourceAlreadyAttachedError",
|
|
201
|
+
"SourceNotFoundError",
|
|
202
|
+
"RoomLockManager",
|
|
203
|
+
"InMemoryLockManager",
|
|
204
|
+
# Sources (event-driven)
|
|
205
|
+
"BaseSourceProvider",
|
|
206
|
+
"EmitCallback",
|
|
207
|
+
"SourceHealth",
|
|
208
|
+
"SourceProvider",
|
|
209
|
+
"SourceStatus",
|
|
210
|
+
# Routing
|
|
211
|
+
"InboundRoomRouter",
|
|
212
|
+
"DefaultInboundRoomRouter",
|
|
213
|
+
# Channels
|
|
214
|
+
"Channel",
|
|
215
|
+
"TransportChannel",
|
|
216
|
+
"AIChannel",
|
|
217
|
+
"EmailChannel",
|
|
218
|
+
"RCSChannel",
|
|
219
|
+
"SMSChannel",
|
|
220
|
+
"WebSocketChannel",
|
|
221
|
+
"MessengerChannel",
|
|
222
|
+
"HTTPChannel",
|
|
223
|
+
"WhatsAppChannel",
|
|
224
|
+
# Models - Enums
|
|
225
|
+
"Access",
|
|
226
|
+
"ChannelCategory",
|
|
227
|
+
"ChannelDirection",
|
|
228
|
+
"ChannelMediaType",
|
|
229
|
+
"ChannelType",
|
|
230
|
+
"DeliveryMode",
|
|
231
|
+
"EventStatus",
|
|
232
|
+
"EventType",
|
|
233
|
+
"HookExecution",
|
|
234
|
+
"HookTrigger",
|
|
235
|
+
"IdentificationStatus",
|
|
236
|
+
"ParticipantRole",
|
|
237
|
+
"ParticipantStatus",
|
|
238
|
+
"RoomStatus",
|
|
239
|
+
"TaskStatus",
|
|
240
|
+
# Models - Data
|
|
241
|
+
"AudioContent",
|
|
242
|
+
"ChannelBinding",
|
|
243
|
+
"ChannelCapabilities",
|
|
244
|
+
"ChannelOutput",
|
|
245
|
+
"CompositeContent",
|
|
246
|
+
"DeliveryResult",
|
|
247
|
+
"DeliveryStatus",
|
|
248
|
+
"EventContent",
|
|
249
|
+
"EventSource",
|
|
250
|
+
"FrameworkEvent",
|
|
251
|
+
"HookResult",
|
|
252
|
+
"Identity",
|
|
253
|
+
"IdentityHookResult",
|
|
254
|
+
"IdentityResult",
|
|
255
|
+
"InboundMessage",
|
|
256
|
+
"InboundResult",
|
|
257
|
+
"InjectedEvent",
|
|
258
|
+
"LocationContent",
|
|
259
|
+
"MediaContent",
|
|
260
|
+
"Observation",
|
|
261
|
+
"Participant",
|
|
262
|
+
"ProviderResult",
|
|
263
|
+
"RateLimit",
|
|
264
|
+
"RetryPolicy",
|
|
265
|
+
"RichContent",
|
|
266
|
+
"Room",
|
|
267
|
+
"RoomContext",
|
|
268
|
+
"RoomEvent",
|
|
269
|
+
"RoomTimers",
|
|
270
|
+
"SystemContent",
|
|
271
|
+
"Task",
|
|
272
|
+
"TemplateContent",
|
|
273
|
+
"TextContent",
|
|
274
|
+
"VideoContent",
|
|
275
|
+
# Hooks
|
|
276
|
+
"HookEngine",
|
|
277
|
+
"HookRegistration",
|
|
278
|
+
# Provider Errors
|
|
279
|
+
"ProviderError",
|
|
280
|
+
# Provider ABCs
|
|
281
|
+
"AIProvider",
|
|
282
|
+
"EmailProvider",
|
|
283
|
+
"HTTPProvider",
|
|
284
|
+
"MessengerProvider",
|
|
285
|
+
"RCSProvider",
|
|
286
|
+
"SMSProvider",
|
|
287
|
+
"WhatsAppProvider",
|
|
288
|
+
# AI
|
|
289
|
+
"AIContext",
|
|
290
|
+
"AIImagePart",
|
|
291
|
+
"AIMessage",
|
|
292
|
+
"AIResponse",
|
|
293
|
+
"AITextPart",
|
|
294
|
+
"AITool",
|
|
295
|
+
"AIToolCall",
|
|
296
|
+
"MockAIProvider",
|
|
297
|
+
# AI – Anthropic
|
|
298
|
+
"AnthropicAIProvider",
|
|
299
|
+
"AnthropicConfig",
|
|
300
|
+
# AI – Gemini
|
|
301
|
+
"GeminiAIProvider",
|
|
302
|
+
"GeminiConfig",
|
|
303
|
+
# AI – OpenAI
|
|
304
|
+
"OpenAIAIProvider",
|
|
305
|
+
"OpenAIConfig",
|
|
306
|
+
# HTTP – Generic Webhook
|
|
307
|
+
"HTTPProviderConfig",
|
|
308
|
+
"MockHTTPProvider",
|
|
309
|
+
"WebhookHTTPProvider",
|
|
310
|
+
"parse_http_webhook",
|
|
311
|
+
# Email
|
|
312
|
+
"ElasticEmailConfig",
|
|
313
|
+
"ElasticEmailProvider",
|
|
314
|
+
"MockEmailProvider",
|
|
315
|
+
# Messenger
|
|
316
|
+
"FacebookMessengerProvider",
|
|
317
|
+
"MessengerConfig",
|
|
318
|
+
"MockMessengerProvider",
|
|
319
|
+
"parse_messenger_webhook",
|
|
320
|
+
# SMS
|
|
321
|
+
"MockSMSProvider",
|
|
322
|
+
"WebhookMeta",
|
|
323
|
+
"extract_sms_meta",
|
|
324
|
+
"is_valid_phone",
|
|
325
|
+
"normalize_phone",
|
|
326
|
+
# SMS - Sinch
|
|
327
|
+
"SinchConfig",
|
|
328
|
+
"SinchSMSProvider",
|
|
329
|
+
"parse_sinch_webhook",
|
|
330
|
+
# SMS - Telnyx
|
|
331
|
+
"TelnyxConfig",
|
|
332
|
+
"TelnyxSMSProvider",
|
|
333
|
+
"parse_telnyx_webhook",
|
|
334
|
+
# RCS - Telnyx
|
|
335
|
+
"TelnyxRCSConfig",
|
|
336
|
+
"TelnyxRCSProvider",
|
|
337
|
+
"parse_telnyx_rcs_webhook",
|
|
338
|
+
# SMS - Twilio
|
|
339
|
+
"TwilioConfig",
|
|
340
|
+
"TwilioSMSProvider",
|
|
341
|
+
"parse_twilio_webhook",
|
|
342
|
+
# SMS - VoiceMeUp
|
|
343
|
+
"VoiceMeUpConfig",
|
|
344
|
+
"VoiceMeUpSMSProvider",
|
|
345
|
+
"configure_voicemeup_mms",
|
|
346
|
+
"parse_voicemeup_webhook",
|
|
347
|
+
# RCS
|
|
348
|
+
"MockRCSProvider",
|
|
349
|
+
"RCSDeliveryResult",
|
|
350
|
+
# RCS - Twilio
|
|
351
|
+
"TwilioRCSConfig",
|
|
352
|
+
"TwilioRCSProvider",
|
|
353
|
+
"parse_twilio_rcs_webhook",
|
|
354
|
+
# WhatsApp
|
|
355
|
+
"MockWhatsAppProvider",
|
|
356
|
+
# Identity
|
|
357
|
+
"IdentityResolver",
|
|
358
|
+
"MockIdentityResolver",
|
|
359
|
+
# Store
|
|
360
|
+
"ConversationStore",
|
|
361
|
+
"InMemoryStore",
|
|
362
|
+
# Realtime
|
|
363
|
+
"EphemeralCallback",
|
|
364
|
+
"EphemeralEvent",
|
|
365
|
+
"EphemeralEventType",
|
|
366
|
+
"InMemoryRealtime",
|
|
367
|
+
"RealtimeBackend",
|
|
368
|
+
# AI Docs
|
|
369
|
+
"get_agents_md",
|
|
370
|
+
"get_ai_context",
|
|
371
|
+
"get_llms_txt",
|
|
372
|
+
]
|
roomkit/_version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
roomkit/ai_docs.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""AI documentation helpers for llms.txt and AGENTS.md access."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import resources
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _find_file(filename: str) -> str:
|
|
10
|
+
"""Find and read a file from package or repository root."""
|
|
11
|
+
# Try 1: importlib.resources (installed package)
|
|
12
|
+
try:
|
|
13
|
+
files = resources.files("roomkit")
|
|
14
|
+
return (files / filename).read_text(encoding="utf-8")
|
|
15
|
+
except (FileNotFoundError, TypeError):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
# Try 2: package directory (editable install with files copied)
|
|
19
|
+
pkg_dir = Path(__file__).parent
|
|
20
|
+
pkg_path = pkg_dir / filename
|
|
21
|
+
if pkg_path.exists():
|
|
22
|
+
return pkg_path.read_text(encoding="utf-8")
|
|
23
|
+
|
|
24
|
+
# Try 3: repository root (development mode)
|
|
25
|
+
# Go up from src/roomkit to repository root
|
|
26
|
+
repo_root = pkg_dir.parent.parent
|
|
27
|
+
repo_path = repo_root / filename
|
|
28
|
+
if repo_path.exists():
|
|
29
|
+
return repo_path.read_text(encoding="utf-8")
|
|
30
|
+
|
|
31
|
+
raise FileNotFoundError(f"{filename} not found in roomkit package or repository")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_llms_txt() -> str:
|
|
35
|
+
"""Get the contents of llms.txt for LLM consumption.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
The llms.txt content as a string.
|
|
39
|
+
|
|
40
|
+
Example:
|
|
41
|
+
>>> from roomkit.ai_docs import get_llms_txt
|
|
42
|
+
>>> content = get_llms_txt()
|
|
43
|
+
>>> print(content[:50])
|
|
44
|
+
# RoomKit
|
|
45
|
+
...
|
|
46
|
+
"""
|
|
47
|
+
return _find_file("llms.txt")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_agents_md() -> str:
|
|
51
|
+
"""Get the contents of AGENTS.md for AI coding assistants.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
The AGENTS.md content as a string.
|
|
55
|
+
|
|
56
|
+
Example:
|
|
57
|
+
>>> from roomkit.ai_docs import get_agents_md
|
|
58
|
+
>>> content = get_agents_md()
|
|
59
|
+
>>> print(content[:50])
|
|
60
|
+
# RoomKit
|
|
61
|
+
...
|
|
62
|
+
"""
|
|
63
|
+
return _find_file("AGENTS.md")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def get_ai_context() -> str:
|
|
67
|
+
"""Get combined AI context (AGENTS.md + llms.txt summary).
|
|
68
|
+
|
|
69
|
+
Useful for providing complete context to AI assistants.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Combined content optimized for AI consumption.
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
>>> from roomkit.ai_docs import get_ai_context
|
|
76
|
+
>>> context = get_ai_context()
|
|
77
|
+
>>> # Pass to AI assistant as system context
|
|
78
|
+
"""
|
|
79
|
+
agents = get_agents_md()
|
|
80
|
+
llms = get_llms_txt()
|
|
81
|
+
|
|
82
|
+
return f"""# RoomKit AI Context
|
|
83
|
+
|
|
84
|
+
## Project Guidelines (AGENTS.md)
|
|
85
|
+
|
|
86
|
+
{agents}
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Documentation Index (llms.txt)
|
|
91
|
+
|
|
92
|
+
{llms}
|
|
93
|
+
"""
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Channel implementations and transport-channel factories."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from roomkit.channels.transport import TransportChannel
|
|
8
|
+
from roomkit.models.channel import ChannelCapabilities
|
|
9
|
+
from roomkit.models.enums import ChannelMediaType, ChannelType
|
|
10
|
+
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
# Capability constants
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
SMS_CAPABILITIES = ChannelCapabilities(
|
|
16
|
+
media_types=[ChannelMediaType.TEXT, ChannelMediaType.MEDIA],
|
|
17
|
+
max_length=1600,
|
|
18
|
+
supports_read_receipts=True,
|
|
19
|
+
supports_media=True,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
EMAIL_CAPABILITIES = ChannelCapabilities(
|
|
23
|
+
media_types=[
|
|
24
|
+
ChannelMediaType.TEXT,
|
|
25
|
+
ChannelMediaType.RICH,
|
|
26
|
+
ChannelMediaType.MEDIA,
|
|
27
|
+
],
|
|
28
|
+
supports_threading=True,
|
|
29
|
+
supports_rich_text=True,
|
|
30
|
+
supports_media=True,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
WHATSAPP_CAPABILITIES = ChannelCapabilities(
|
|
34
|
+
media_types=[
|
|
35
|
+
ChannelMediaType.TEXT,
|
|
36
|
+
ChannelMediaType.RICH,
|
|
37
|
+
ChannelMediaType.MEDIA,
|
|
38
|
+
ChannelMediaType.LOCATION,
|
|
39
|
+
ChannelMediaType.TEMPLATE,
|
|
40
|
+
],
|
|
41
|
+
max_length=4096,
|
|
42
|
+
supports_read_receipts=True,
|
|
43
|
+
supports_reactions=True,
|
|
44
|
+
supports_templates=True,
|
|
45
|
+
supports_rich_text=True,
|
|
46
|
+
supports_buttons=True,
|
|
47
|
+
max_buttons=3,
|
|
48
|
+
supports_quick_replies=True,
|
|
49
|
+
supports_media=True,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
MESSENGER_CAPABILITIES = ChannelCapabilities(
|
|
53
|
+
media_types=[
|
|
54
|
+
ChannelMediaType.TEXT,
|
|
55
|
+
ChannelMediaType.RICH,
|
|
56
|
+
ChannelMediaType.MEDIA,
|
|
57
|
+
ChannelMediaType.TEMPLATE,
|
|
58
|
+
],
|
|
59
|
+
max_length=2000,
|
|
60
|
+
supports_read_receipts=True,
|
|
61
|
+
supports_buttons=True,
|
|
62
|
+
max_buttons=3,
|
|
63
|
+
supports_quick_replies=True,
|
|
64
|
+
supports_media=True,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
HTTP_CAPABILITIES = ChannelCapabilities(
|
|
68
|
+
media_types=[ChannelMediaType.TEXT, ChannelMediaType.RICH],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
RCS_CAPABILITIES = ChannelCapabilities(
|
|
72
|
+
media_types=[
|
|
73
|
+
ChannelMediaType.TEXT,
|
|
74
|
+
ChannelMediaType.RICH,
|
|
75
|
+
ChannelMediaType.MEDIA,
|
|
76
|
+
],
|
|
77
|
+
max_length=8000, # RCS supports longer messages
|
|
78
|
+
supports_read_receipts=True,
|
|
79
|
+
supports_typing=True,
|
|
80
|
+
supports_rich_text=True,
|
|
81
|
+
supports_buttons=True,
|
|
82
|
+
supports_quick_replies=True,
|
|
83
|
+
supports_cards=True,
|
|
84
|
+
supports_media=True,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# ---------------------------------------------------------------------------
|
|
88
|
+
# Factory functions
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def SMSChannel(
|
|
93
|
+
channel_id: str,
|
|
94
|
+
*,
|
|
95
|
+
provider: Any = None,
|
|
96
|
+
from_number: str | None = None,
|
|
97
|
+
) -> TransportChannel:
|
|
98
|
+
"""Create an SMS transport channel."""
|
|
99
|
+
return TransportChannel(
|
|
100
|
+
channel_id,
|
|
101
|
+
ChannelType.SMS,
|
|
102
|
+
provider=provider,
|
|
103
|
+
capabilities=SMS_CAPABILITIES,
|
|
104
|
+
recipient_key="phone_number",
|
|
105
|
+
defaults={"from_": from_number},
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def EmailChannel(
|
|
110
|
+
channel_id: str,
|
|
111
|
+
*,
|
|
112
|
+
provider: Any = None,
|
|
113
|
+
from_address: str | None = None,
|
|
114
|
+
) -> TransportChannel:
|
|
115
|
+
"""Create an Email transport channel."""
|
|
116
|
+
return TransportChannel(
|
|
117
|
+
channel_id,
|
|
118
|
+
ChannelType.EMAIL,
|
|
119
|
+
provider=provider,
|
|
120
|
+
capabilities=EMAIL_CAPABILITIES,
|
|
121
|
+
recipient_key="email_address",
|
|
122
|
+
defaults={"from_": from_address, "subject": None},
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def WhatsAppChannel(
|
|
127
|
+
channel_id: str,
|
|
128
|
+
*,
|
|
129
|
+
provider: Any = None,
|
|
130
|
+
) -> TransportChannel:
|
|
131
|
+
"""Create a WhatsApp transport channel."""
|
|
132
|
+
return TransportChannel(
|
|
133
|
+
channel_id,
|
|
134
|
+
ChannelType.WHATSAPP,
|
|
135
|
+
provider=provider,
|
|
136
|
+
capabilities=WHATSAPP_CAPABILITIES,
|
|
137
|
+
recipient_key="phone_number",
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def MessengerChannel(
|
|
142
|
+
channel_id: str,
|
|
143
|
+
*,
|
|
144
|
+
provider: Any = None,
|
|
145
|
+
) -> TransportChannel:
|
|
146
|
+
"""Create a Facebook Messenger transport channel."""
|
|
147
|
+
return TransportChannel(
|
|
148
|
+
channel_id,
|
|
149
|
+
ChannelType.MESSENGER,
|
|
150
|
+
provider=provider,
|
|
151
|
+
capabilities=MESSENGER_CAPABILITIES,
|
|
152
|
+
recipient_key="facebook_user_id",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def HTTPChannel(
|
|
157
|
+
channel_id: str,
|
|
158
|
+
*,
|
|
159
|
+
provider: Any = None,
|
|
160
|
+
) -> TransportChannel:
|
|
161
|
+
"""Create an HTTP webhook transport channel."""
|
|
162
|
+
return TransportChannel(
|
|
163
|
+
channel_id,
|
|
164
|
+
ChannelType.WEBHOOK,
|
|
165
|
+
provider=provider,
|
|
166
|
+
capabilities=HTTP_CAPABILITIES,
|
|
167
|
+
recipient_key="recipient_id",
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def RCSChannel(
|
|
172
|
+
channel_id: str,
|
|
173
|
+
*,
|
|
174
|
+
provider: Any = None,
|
|
175
|
+
fallback: bool = True,
|
|
176
|
+
) -> TransportChannel:
|
|
177
|
+
"""Create an RCS (Rich Communication Services) transport channel.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
channel_id: Unique identifier for this channel.
|
|
181
|
+
provider: RCS provider instance (e.g., TwilioRCSProvider).
|
|
182
|
+
fallback: If True (default), allow SMS fallback when RCS unavailable.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
A TransportChannel configured for RCS messaging.
|
|
186
|
+
"""
|
|
187
|
+
return TransportChannel(
|
|
188
|
+
channel_id,
|
|
189
|
+
ChannelType.RCS,
|
|
190
|
+
provider=provider,
|
|
191
|
+
capabilities=RCS_CAPABILITIES,
|
|
192
|
+
recipient_key="phone_number",
|
|
193
|
+
defaults={"fallback": fallback},
|
|
194
|
+
)
|