Repository navigation
feat(schedule): add PostgreSQL schedule repository - #192
Merged
Wintercom merged 4 commits intoAug 11, 2026
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…res-storage # Conflicts: # backend/alembic/env.py # backend/src/timeflow/data/__init__.py # backend/src/timeflow/data/models.py # backend/tests/test_schedule_schema.py
Wintercom
pushed a commit
that referenced
this pull request
Aug 12, 2026
… fix (#210) * feat(realtime): implement schedule tools with account isolation and mapping layer - Add account_id to StreamInfo/StreamIdentity/StreamContext protocols - Change RealtimeAgent to use tools_factory for per-account tool binding - Extract tool mapping functions from conversation layer to tool_mapping.py - Implement ToolBox with five schedule tools and exception translation - Add SeededScheduleService as temporary data source - Validate candidates field for ambiguous_target questions Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat(realtime): enable schedule mutations with account isolation - schedule_create/update/delete join the existing query tool, with instructions covering when to ask before touching a schedule versus acting on it. - account_id now flows from the WS transport through to tool binding, so a session's tools are scoped to its authenticated account. - A session stays open past a turn that asked a question, so a follow-up answer reaches a model that still remembers asking it. - Hardens the Qwen-Audio transport pump: a binary frame is skipped rather than treated as fatal, and non-JSON text fails the turn with a reported reason instead of raising. * feat(realtime): wire schedule tools to the real database Switch main.py off the local duplicate data layer (DatabaseScheduleService plus its own repository and transaction handling) onto the already-merged ScheduleApplicationService + SqlAlchemyScheduleUnitOfWork (#192, #200), and update the two database-backed end-to-end tests to match. Drops ~900 lines of implementation and tests that duplicated what was already upstream. * fix(realtime): stop double-wrapping the command.result payload RealtimeAgent.tool_requested passed the whole ToolBox outcome dict (itself {operation, status, schedule}) into CommandResult.schedule, so the client received payload.schedule.schedule.title instead of payload.schedule.title -- every mutation reached the client with no usable schedule data. list_schedules had the same problem in reverse: its matches never had anywhere correct to go at all. CommandResult and the wire payload now carry separate optional schedule/schedules fields, matching protocol §5.5/§5.6, and only the one that applies is sent (schedules is exclude_none'd off the wire for a mutation, and vice versa for a query). Verified against a real voice round trip over the actual database, not just the added regression tests. * feat(realtime): add TIMEFLOW_VOICE_AGENT_MODE to select the agent backend Settings gains voice_agent_mode ("1" realtime model, "2" LLM+ASR+TTS pipeline), validated against those two values. main.py's _build_agent already dispatches on it (committed in 6b88acf); mode 2 fails closed with a clear message since the conversation pipeline does not implement the Agent port yet. * style(realtime): reformat test_realtime_sessions.py ruff format wanted a call collapsed onto one line; missed running the formatter locally before the earlier commit. * fix(realtime): preserve negative UTC offsets in datetime normalization normalize_datetime_args decided whether a datetime string already carried a timezone by checking for a literal "+" or "Z", which misses negative offsets like "-05:00". fromisoformat parses that as already aware, but the code then force-replaced its tzinfo with LOCAL anyway -- silently shifting the instant by the difference between the two zones (e.g. a schedule meant for 07:00-05:00 gets stored as 07:00+08:00, 13 hours off). Parse first and only attach LOCAL when the result is genuinely naive, matching how _optional_datetime already decides the same thing. Found by fennoai's review on PR #210. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This branch was successfully deployed
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.
Summary
created_atand caller-providedrevisioncannot be persistedVerification
ruff check .ruff format --check .mypy20260810_0005Scope
This PR contains only the PostgreSQL repository layer and its integration-test wiring on top of the schema merged in #186. ScheduleApplicationService, RRULE expansion, snapshot orchestration, WebSocket synchronization, and Agent-facing business APIs remain out of scope.
Replaces the PostgreSQL repository portion of #191.