Commit 1ea14c5
Feat/copilotkit chat (#859)
* Integrated copilotkit to integrate with chatui.
* Cleaned changelog.
* build(deps): bump ag-ui-langgraph from 0.0.31 to 0.0.34
Drop the now-redundant set_message_in_progress override on
RuntimeContextLangGraphAGUIAgent: upstream already guards the None
sentinel merge with or {}, so the override was a no-op (and was
triggering Liskov type-check errors because its signature widened
MessageInProgress to dict[str, Any]).
The get_stream_kwargs override is kept because upstream still dict-
merges config/context via .update(), which is incompatible with our
frozen RuntimeCtx dataclass passed to LangGraph as context_schema.
* test(chat): Rewrite chat API tests for AG-UI endpoint
The old tests imported MODEL_ID and hit /models endpoints that were
removed when the chat API was rewritten on top of CopilotKit/AG-UI.
They failed at collection time.
Replace them with coverage of the view's only custom behavior: the
404 raised when X-Repo-ID or X-Ref headers are missing. Everything
past that point is third-party (AG-UI, LangGraph, ninja) and not
worth exercising in unit tests.
* feat(activity): add Activity.thread_id for LangGraph checkpoint persistence
* feat(chat): scaffold chat app and shared checkpointer factory
* feat(jobs): persist agent-run state via AsyncRedisSaver; accept thread_id
* feat(activity): mint thread_id per run and persist on Activity
* feat(chat): ChatThread model with per-user ownership
* feat(chat): dual-auth endpoint with thread ownership and concurrency check
* feat(chat): dashboard views (list, detail, from-activity bridge)
* feat(chat): list/detail/message/composer templates and Alpine streaming component
* feat(chat): sidebar entry, chat icon, and 'Continue as chat' button on activity detail
* style(chat): silence ty diagnostics introduced by new code
* refactor(chat): simplify views and reuse open_checkpointer in addressors
- Use aget_or_create to resolve TOCTOU races on thread creation (ChatThread.aget_or_create_from_activity and the API endpoint's implicit-create path)
- Replace role-normalization ternary with a lookup dict
- Use reverse("chat_list") instead of hardcoded URLs in breadcrumbs
- Rewrite _extract_first_user_message as a generator expression
- Drop dead <template id="message-template"> block and the stale template lookup in chat-stream.js; the inline renderer has always been the only path
- Index tool_calls by id (Map) for O(1) lookup instead of Array.find on every arg chunk
- Debounce scrollToBottom via requestAnimationFrame to avoid layout thrash under high-rate TEXT_MESSAGE_CHUNK events
- Drop unused 'expired' Alpine prop; the template already handles it server-side
- Route issue_addressor.py and review_addressor.py through core.checkpointer.open_checkpointer instead of inline AsyncRedisSaver.from_conn_string
* fix(chat): surface stream errors and close TOCTOU race on active_run_id
- Wrap the AG-UI event generator in try/except: on any exception, log and emit
a synthetic RUN_ERROR event so the browser surfaces a real error instead of
silently terminating the SSE stream with an empty assistant bubble.
- Replace read-then-write with a single conditional aupdate that claims the
active_run_id slot only if currently empty — parallel tabs now race to a
single winner and the loser gets 409.
- Lift slot release out of the handler into a _release_thread helper used by
the generator's finally block.
- Add tests: happy-path active_run_id cleanup, exception-path cleanup with
RUN_ERROR emission, plus unit tests for _extract_first_user_message edge
cases (empty, non-string content, whitespace-only).
- Client: console.error on network failure + friendlier user message, map
known HTTP errors (403/404/409) to actionable copy instead of dumping raw
response body, escalate malformed SSE frames from warn to error.
* feat(chat): scaffold build_turns helper module
* feat(chat): build_turns handles HumanMessage content
* feat(chat): build_turns handles AIMessage with string content
* feat(chat): build_turns preserves Anthropic block interleaving
* feat(chat): build_turns pairs ToolMessage results, drops orphans
* feat(chat): view emits turns via build_turns
* feat(chat): renderMarkdown wrapper around marked + highlight.js
* feat(chat): per-tool signature + expanded-body renderers
* feat(chat): diff/grep/bash/todos stylesheet for expanded tool views
* feat(chat): component styles for shell, turn, tool cards, composer, rail
* feat(chat): right-rail partial with repo, status, todos, files touched
* feat(chat): sticky composer with kbd hint, send/stop states, jump pill
* feat(chat): rewrite stream controller around turns/segments
* feat(chat): rewrite detail template around turns/segments with rail + composer
* chore(chat): remove legacy _message and _tool_call_card partials
* fix(chat): bash tool renderer key, icon templates, user bubble sizing
* fix(chat): right-align user bubble, persistent status bar, unblocked CDN scripts, slimmer rail
* fix(chat): drop turn markers, keep streaming signal as left thread line
* feat(chat): task renderer + suppress nested frames while task runs
* feat(chat): hero repo picker, reasoning segments, file-op rail, run resume
- Empty state now mounts a single-repo picker (extracted partial reused
by activity); composer fades in once a repo is chosen.
- Render reasoning/thinking blocks as collapsible segments, including
out-of-band reasoning_content from DeepSeek/Qwen/xAI providers.
- Fold the skill tool's injected SKILL.md body into the tool result so
reload doesn't show it as a phantom user turn.
- Files-touched rail derives ops (added/modified/deleted/renamed) from
the sandbox's unified-diff patch, covering bash mutations too.
- edit_file diff body uses jsdiff for real hunks; tool signatures parse
partial-JSON args so summaries update mid-stream.
- New /threads/{id}/status endpoint + activeRunId hydration lets a
reloaded page detect when an in-flight run releases its slot.
- OpenRouter reasoning kwargs send enabled=true (z.ai GLM ignores effort
alone).
* style(chat): markdown hierarchy + grep/glob signatures
- Flesh out chat-text typography: heading scale with editorial rules
under h1/h2, list markers and task-list checkboxes, blockquote
side rail, fading hr, kbd keycap, mark/img defaults, and an
amber-tinted inline-code chip with a heading-aware override.
- Tables get a 100% width, scroll on overflow, header tint, zebra
rows, and hover highlight so transcripts read as data, not text.
- Pre blocks pick up a thin custom scrollbar so horizontal scroll
feels intentional.
- grep signature folds an optional glob arg into the scope label;
glob expanded body parses the Python-list-repr result so users
see one path per line instead of a quoted one-liner.
* feat(nav): promote chat to sidebar CTA, move run button to activity
* feat(chat): surface pre-existing MR pill on branches with open MRs
When a chat opens on a branch that already has an open merge request
(created in a prior conversation, by the agent on a different thread,
or by a human via the platform UI), the composer pill now appears
without waiting for the agent to touch git state.
- New RepoClient.get_merge_request_by_branches abstract + GitLab/GitHub
implementations; SWE client raises NotImplementedError.
- Shared chat.repo_state.aget_existing_mr_payload helper backed by the
cached RepositoryConfig.get_config for default-branch lookup.
- ChatThreadDetailView falls back to the helper at server-render time.
- _emit_repo_state falls back to the helper when LangGraph state has no
MR, so the streamed daiv:repo_state event surfaces existing MRs after
the first message of a new chat.
* feat(chat): publish-phase chips, MR pill, empty-state polish
- Render diff_to_metadata subagent structured-response tools
(PullRequestMetadata, CommitMetadata) as compact phase chips in the
assistant turn and status bar; silence their text/reasoning frames
upstream via emit-messages: False so partial JSON never leaks.
- Add an MR pill next to the repo chip that hydrates from the
server-rendered checkpoint and updates live on daiv:repo_state custom
events, with an accent on the branch segment once GitMiddleware
commits to a working ref.
- Tighten the new-chat empty state: drop the rail column, dock the
composer under the hero, stack subtitles in one grid cell to kill the
layout jump on repo pick, and soften the composer fade so the top
border stays visible.
- Suppress asyncio CancelledError tracebacks logged by asgiref when an
SSE client disconnects mid-stream; cleanup already runs in the view's
finally, the trace is just noise.
* feat(chat): step counter on running task, surface sibling tasks
Stop suppressing tool-call events whose id differs from the active task
when the call itself is another task — sibling parallel-audit subagents
were being dropped on the floor, leaving the matching TOOL_CALL_RESULT
with nothing to bind to until a page reload rehydrated from checkpoint.
For genuinely inner tool calls, tick an innerToolsCount on the parent
task segment so the user has some live signal during the long quiet
window, surfaced as a small "N steps" chip on the running task card.
* refactor(chat): drive MR pill via STATE_SNAPSHOT, split api/views
Move from a post-run ``daiv:repo_state`` CustomEvent to AG-UI's native
STATE_SNAPSHOT stream for the composer MR pill. ``GitMiddleware`` now
publishes ``merge_request`` on the public output schema and seeds it
with any pre-existing open MR on the current branch, so the pill
reflects reality from the first turn — no end-of-run checkpoint probe.
Split ``chat/api/views.py`` into ``streaming.py`` (SSE generator +
``RuntimeContextLangGraphAGUIAgent``), ``threads.py`` (run-slot claim/
release + ref persistence), and ``event_filter.py`` (the subagent
event reorder/suppress that previously lived inline). Drop the
running-task step counter; the filter now handles nested frames
server-side, so the client-side workaround is dead weight.
Tool-stream polish:
- web_search returns a JSON array; the renderer parses it into per-hit
cards and a hit-count badge
- web_fetch / gitlab / gh prefix failures with ``error:`` and the gitlab
CLI truncation appends a sentinel — both feed result-row badges
- new body renderers for web_fetch, web_search, gitlab, gh
- activity-stream uses class-map objects so Alpine swaps status
variants cleanly instead of letting old classes linger
* Review improvements.
* fix(chat): Handle parallel tool_calls and misrouted arg deltas
ag_ui_langgraph only tracks one current_stream.tool_call_id, so when
the LLM emits parallel tool_calls in one AIMessage, sibling args are
attributed to the first call's id and concatenated into its segment.
Generalize the subagent event filter to:
- synthesize TOOL_CALL_START/ARGS/END for any tcid not naturally
started (covers the dropped-start case AND parallel siblings),
- drop TOOL_CALL_ARGS whose underlying chunk index > 0 (misrouted),
- yield STATE_SNAPSHOT before synthesized segments so state-driven UI
updates commit first.
Also surface read_file errors and "no matches" in grep results in the
chat tool renderer.
* fix(chat): Defer textarea autosize until after DOM update
* feat(chat): Add new chat link to expired conversation banner
* docs(mcp): Reflect MR reuse on existing branches in submit_job
* feat(titling): Add LLM-generated titles for activities and chat threads
Introduces a shared titling pipeline (heuristic + LLM fallback via
django-tasks) that backfills concise human-readable titles on Activity
and ChatThread rows. Webhook-triggered activities reuse the issue/MR
title; scheduled batch runs get a deterministic name; prompt-driven
runs and chat threads enqueue an async generation task with LangSmith
monitoring metadata. Threads created from an activity reuse its
existing title to avoid a duplicate LLM call.
* Potential fix for pull request finding 'CodeQL / Double escaping or unescaping'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* test(mcp): Update _FakeActivity mock for title-task enqueue
Add a pk attribute to _FakeActivity and patch generate_title_task so
the post-create title enqueue path introduced in 166e628 doesn't
crash mock-driven submit_job tests.
---------
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>1 parent 71522a0 commit 1ea14c5
93 files changed
Lines changed: 7597 additions & 509 deletions
File tree
- daiv
- accounts
- templates/accounts
- activity
- migrations
- static/activity/js
- templates/activity
- templatetags
- automation
- agent
- diff_to_metadata
- middlewares
- titling
- chat
- api
- migrations
- static/chat
- css
- js
- templates/chat
- codebase
- clients
- github
- api
- gitlab
- api
- managers
- templates/codebase
- core
- api
- static/core/img/icons
- daiv
- settings/components
- jobs
- api
- mcp_server
- notifications/migrations
- static_src/css
- tests/unit_tests
- activity
- automation
- agent/middlewares
- titling
- chat
- api
- codebase
- clients
- github
- gitlab
- jobs
- api
- mcp_server
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
14 | | - | |
| 13 | + | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
13 | | - | |
14 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
45 | 52 | | |
46 | 53 | | |
47 | 54 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
| 91 | + | |
| 92 | + | |
91 | 93 | | |
92 | 94 | | |
93 | 95 | | |
| |||
96 | 98 | | |
97 | 99 | | |
98 | 100 | | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
99 | 111 | | |
100 | 112 | | |
101 | 113 | | |
| |||
175 | 187 | | |
176 | 188 | | |
177 | 189 | | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
178 | 198 | | |
179 | 199 | | |
180 | 200 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
13 | 16 | | |
14 | 17 | | |
15 | 18 | | |
| |||
96 | 99 | | |
97 | 100 | | |
98 | 101 | | |
| 102 | + | |
| 103 | + | |
99 | 104 | | |
100 | 105 | | |
101 | 106 | | |
| |||
116 | 121 | | |
117 | 122 | | |
118 | 123 | | |
| 124 | + | |
| 125 | + | |
119 | 126 | | |
120 | 127 | | |
121 | 128 | | |
| |||
135 | 142 | | |
136 | 143 | | |
137 | 144 | | |
| 145 | + | |
| 146 | + | |
138 | 147 | | |
139 | 148 | | |
140 | 149 | | |
| |||
152 | 161 | | |
153 | 162 | | |
154 | 163 | | |
| 164 | + | |
| 165 | + | |
155 | 166 | | |
156 | 167 | | |
157 | 168 | | |
| |||
175 | 186 | | |
176 | 187 | | |
177 | 188 | | |
178 | | - | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
179 | 194 | | |
| 195 | + | |
180 | 196 | | |
181 | | - | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
182 | 200 | | |
183 | 201 | | |
184 | 202 | | |
185 | 203 | | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
186 | 208 | | |
187 | | - | |
| 209 | + | |
188 | 210 | | |
189 | 211 | | |
190 | 212 | | |
| |||
196 | 218 | | |
197 | 219 | | |
198 | 220 | | |
| 221 | + | |
| 222 | + | |
199 | 223 | | |
200 | 224 | | |
201 | 225 | | |
| |||
205 | 229 | | |
206 | 230 | | |
207 | 231 | | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
208 | 245 | | |
209 | 246 | | |
210 | | - | |
| 247 | + | |
211 | 248 | | |
212 | 249 | | |
213 | 250 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | | - | |
| 5 | + | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
9 | 14 | | |
10 | 15 | | |
11 | 16 | | |
12 | 17 | | |
13 | 18 | | |
| 19 | + | |
| 20 | + | |
14 | 21 | | |
15 | 22 | | |
16 | 23 | | |
| |||
25 | 32 | | |
26 | 33 | | |
27 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
28 | 39 | | |
29 | 40 | | |
30 | 41 | | |
| |||
42 | 53 | | |
43 | 54 | | |
44 | 55 | | |
45 | | - | |
| 56 | + | |
46 | 57 | | |
47 | 58 | | |
48 | | - | |
| 59 | + | |
49 | 60 | | |
50 | 61 | | |
51 | 62 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| 26 | + | |
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| |||
45 | 47 | | |
46 | 48 | | |
47 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
48 | 59 | | |
49 | 60 | | |
50 | 61 | | |
| |||
109 | 120 | | |
110 | 121 | | |
111 | 122 | | |
| 123 | + | |
112 | 124 | | |
113 | 125 | | |
114 | 126 | | |
| |||
122 | 134 | | |
123 | 135 | | |
124 | 136 | | |
| 137 | + | |
125 | 138 | | |
126 | 139 | | |
127 | 140 | | |
| |||
134 | 147 | | |
135 | 148 | | |
136 | 149 | | |
| 150 | + | |
137 | 151 | | |
138 | 152 | | |
139 | 153 | | |
| |||
0 commit comments