DRU-376 - Operator chat - #517
Open
chaosk wants to merge 9 commits into
Open
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…it (#421) Co-authored-by: druks-operator-treadstone[bot] <322217521+druks-operator-treadstone[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Krzysztof Socha <ksocha@ksocha.com>
Each thread belongs to one account; messages are rows, not events. Talk lands later, so there is no workflow yet. Co-authored-by: Cursor <cursoragent@cursor.com>
#415) The first POST creates the thread and starts the run; later lines answer the gate. A fifteen-minute hold keeps the warm VM across turns. Co-authored-by: Cursor <cursoragent@cursor.com>
…rt and follow conversations from the dashboard. (#416) Co-authored-by: Cursor <cursoragent@cursor.com>
…hrough a call-scoped MCP token. (#417) * Let Chat operate this appliance as the signed-in operator through a call-scoped MCP token. Co-authored-by: Cursor <cursoragent@cursor.com> * Stop advertising mutating /mcp response schemas so confirm can defer a create. Confirm returns a deferred stub, not the route's 201 body. MCP outputSchema validation rejected that stub on any write whose model requires fields like identifier, so the tool failed and the write never reached the operator gate. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…gate. (#418) Talk was feeding the whole thread and parking a review-shaped turn. Bound the prompt, fill an empty title from the first user line, and answer ChatTurn through send/stop so stop ends the run without a message row. Co-authored-by: Cursor <cursoragent@cursor.com>
…operator chat app. (#518) Co-authored-by: Cursor <cursoragent@cursor.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
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.
Linear ticket: DRU-376
Dashboard chat that keeps several conversations, reuses the sandbox across turns instead of provisioning on every send, and can operate this Druks appliance as that operator through the existing MCP tool catalog. Autonomy (
propose/confirm/full) is a per-conversation setting.This is not a live socket into a running harness and not a 14-day parked VM. A turn is still a durable gate. While the operator is actively chatting, the host lease stays up so the next line does not wait for a new machine.
What the operator gets
backend/druks/contrib/chat/), same packaging as Issues. Not adruks.chatnamespace and not adist/SPA.Talkrun per conversation: agent turn → assistant message → optional confirm gate →ChatTurn.wait(hold_sandbox=15m)→ send or stop. Stop ends the run and does not write a message.account_id.druks doctor: Chat is always installed;/mcpis probed (or skipped when sandbox execution is off).Sandbox hold
Drukbox already has
POST /hosts/{id}/renew. The SDK already exposesSandboxAPI.renew_host. This branch wraps that asClient.set_expiry.Gate.wait(..., hold_sandbox=…)clips the lease instead of reaping.review()still reaps. After the clipped lease, the next line provisions cold.Tickets (landed on
integration/chat)renew_host(drukbox-python-sdk)Client.set_expiry(merged locally; GitHub merge conflicted afterclient.pymoved)Gate.waitsandbox holdOut of scope
Mid-call interrupt / stdin into a live harness. Holding a VM for the 14-day gate TTL. Persistent leaseless workstations. A
druks.chatnamespace or a second SSE system. A 150-minute Drukbox renew ceiling. Replacing external Claude/Codex MCP.Risk
Alembic for chat conversation/message tables.
Replay: parks with
hold_sandboxclip the lease;review()andhold_sandbox=Falsestill delete the host. Workflowfinallystill reaps on terminal exit. Call-scoped MCP tokens do not outlive the agent call.Verification
uv run ruff check backenduv run ruff format --check backenduv pip install -e backend/tests/druks-field_notesuv run pytest backend/npm --prefix frontend run lintnpm --prefix frontend testnpm --prefix frontend run buildreview()and anyhold_sandbox=Falsepark still delete the host immediately.