Merged
Conversation
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[0.2.5] - 2026-04-12
Added
Conversation Sharing + Admin Conversation Browser
view(read-only) andedit(can add messages). Owner can share, list shares, and revoke access. Recipients can also leave shared conversationsConversationSharemodel — New DB model across all 5 variants (PG+SQLModel, PG+SQLAlchemy, SQLite+SQLModel, SQLite+SQLAlchemy, MongoDB). Fields: conversation_id, shared_by, shared_with, share_token, permission. Unique constraint on (conversation_id, shared_with)POST /conversations/{id}/shares(share or generate link),GET /conversations/{id}/shares(list shares, owner only),DELETE /conversations/{id}/shares/{share_id}(revoke),GET /conversations/shared-with-me(list shared with current user),GET /conversations/shared/{token}(public access, no auth)GET /admin/conversations(paginated, searchable by title, filterable by user_id, includes message_count and user_email),GET /admin/conversations/{id}(full conversation with messages),GET /admin/conversations/users(user list with conversation counts, searchable)/admin/conversationspage with tabs (Conversations/Users), table views, search, click-to-preview (read-only), user → conversations drill-down/shared/[token]SSR page renders conversation transcript without sidebar or input. Clean read-only view using server-side fetchuseConversationShares(share, fetch, revoke, shared-with-me) anduseAdminConversations(admin list, users, detail preview)Slack Multi-Bot Channel Integration
SlackAdapter(ChannelAdapter)supporting both Events API (production webhook) and Socket Mode (development polling). Thread-aware: Slack thread replies foldthread_tsintoplatform_chat_id({channel}:{thread_ts}) so each thread gets its ownChannelSessionandConversationPOST /slack/{bot_id}/eventsendpoint handles Slack URL verification challenge and event dispatch. Signature verified via HMAC-SHA256 (v0={timestamp}:{body}) with 5-minute replay-protection window. Fire-and-forget background dispatch meets Slack's 3s response requirementslack-sdk'sSocketModeClient. Bot-scoped tasks with 5s back-off restart on crash. Lifecycle managed in app lifespan alongside Telegram pollinguse_slackcookiecutter variable — Gates all Slack infrastructure. CLI interactive prompt for "Enable Slack integration" added alongside Telegram. Enables:slack-sdk>=3.35.0, Slack-specific config vars (SLACK_SIGNING_SECRET,SLACK_BOT_TOKEN,SLACK_APP_TOKEN),POST /slack/{bot_id}/eventsrouteChannelAdapterbase, models, repos, services, router, commands) gated fromuse_telegram→use_telegram or use_slackso both platforms share the same session/identity/bot management layerasyncio.Lock(keyed on{bot_id}:{platform_chat_id}) inChannelMessageRouter.route(). Serializes concurrent messages from the same group/channel to prevent: duplicateChannelSessioncreation (DB constraint violation), interleaved agent invocations on the sameConversation, and rate-limit counter races. Affects both Telegram groups and Slack channelsTelegram Multi-Bot Channel Integration
ChannelAdapterbase class with concreteTelegramAdapter(aiogram v3). Adapter registry pattern for future platform extensions (Discord, Slack, etc.)ChannelBot(encrypted token, access policy, webhook config),ChannelIdentity(platform user ↔ app user linking with link codes),ChannelSession(bot+chat → conversation mapping)/channels/bots), activate/deactivate, webhook register/delete, session listing. All endpoints require admin role with properChannelBotCreate/ChannelBotUpdate/ChannelBotReadschemasPOST /telegram/{bot_id}/webhookwith signature verification, fire-and-forget async processing to stay within Telegram's 5s timeoutchannel-list-bots,channel-add-bot,channel-webhook-register,channel-webhook-delete,channel-test-messageAgentInvocationService— Framework-agnostic non-streaming agent invocation for all 6 AI frameworks, used by Telegram channel routeruse_telegramcookiecutter variable — Gates all Telegram code via Jinja2 conditionals. CLI interactive prompt addedPydanticDeep Framework (6th AI Framework)
sandbox_backendcookiecutter variable — ConfiguresPYDANTIC_DEEP_BACKEND_TYPE/DEEPAGENTS_BACKEND_TYPEin generated Settingsdocker cp(or backend API) so the agent can access them withread_file. File paths are automatically included in the user message. Falls back to inline content for StateBackendws/projects/{project_id}/chats/{conversation_id}for shared Docker containers per projectPydanticAI Capabilities
WebSearch()andWebFetch()capabilities. Provider-adaptive: uses builtin when the model supports it natively, falls back to DuckDuckGo (search) and markdownify (fetch)duckduckgoandweb-fetchextras for local fallback supportChanged
PYDANTIC_DEEP_WORKSPACE_DIRsetting — No longer needed without LocalBackendFixed
Telegram Channel Code Review Fixes
channels/router.py— Maderoute()alwaysasync def(was sync for SQLite, causingasyncio.get_event_loop().run_until_complete()crash). Removed broken_handle_command_sync,_resolve_identity_sync,_resolve_session_syncmethods. Added SQLite branches to all async methodschannels/router.py— Fixed/linkcommand: replaced non-existentchannel_link_repo.redeem_code()withchannel_identity_repo.get_by_link_code(). Code is invalidated after usechannels/router.py— Fixedbot.encrypted_token→bot.token_encryptedin_send_reply(). Fixedbot.system_prompt→bot.system_prompt_overrideandbot.model_override→bot.ai_model_overridechannels/router.py— Fixed MongoDB import paths:from app.db.models.channel import→from app.db.models.channel_identity import/from app.db.models.channel_session importchannels/router.py— Added_parse_policy()helper to normalizeaccess_policyfrom JSON string (SQLite) or dict (PostgreSQL/MongoDB)channels/telegram.py— Removed module-level singleton that conflicted with lifespan-managed adapter inmain.py. Fixed SQLite_handle_updatetoawait router.route()api/routes/v1/channels.py— Fixed all service method names (service.list_bots()→service.list(), etc.). Replaceddata: Anywith properChannelBotCreate/ChannelBotUpdateschemas. Addedresponse_modelto all endpoints. Made SQLite webhook routesasync(was usingasyncio.run()inside running loop)api/routes/v1/telegram_webhook.py— Fixed SQLite branch toawait router.route()(route is now always async)services/channel_bot.py— Generatewebhook_secretviasecrets.token_urlsafe(32)whenwebhook_mode=True(was alwaysNone). Addedlist_sessions()method to all 3 backendsrepositories/channel_session.py— Addedlist_by_bot()andcount_by_bot()functions to all 3 backendscommands/channel.py— Fixedbot.encrypted_token→bot.token_encrypted. Fixedchannel_bot_repo.list_all(platform=...)(no such parameter) → conditionalget_by_platform(). Fixedencrypted_token=→token_encrypted=in createTooling
ty checkstep (was present in minimal and PostgreSQL jobs but absent from MongoDB)v0.8.0tov0.15.0(consistent withpyproject.toml >=0.15.0)Dependencies
>=1.77.0→>=1.80.0(all providers + pydantic-deep)duckduckgoandweb-fetchextras for WebSearch/WebFetch local fallback>=3.17,<4.0(new — Telegram adapter)>=3.35.0(new — Slack Web API, Socket Mode, Events API)>=44.0.0(new — Fernet token encryption, gated underuse_telegram or use_slack)