feat(desktop,core): Mac client agent loop — real runAgent in renderer#61
Merged
Conversation
Fixes the biggest v1-blocker hole: window.deepcode.agent.start() now
runs @deepcode/core's `runAgent` directly in the Tauri renderer. Users
can have a real conversation in DeepCode.app for the first time.
## Architecture
The Tauri webview can run runAgent because:
1. agent loop is IO-agnostic — just calls tool.execute(input, ctx)
2. We provide Mac-flavored ToolHandler implementations that route
fs/bash through Tauri commands → Rust executes them natively
3. DeepSeek's `openai` SDK ships browser-safe builds
## Rust (apps/desktop/src-tauri/src/)
· NEW tools.rs (~270 lines) — 6 commands: tool_read / tool_write /
tool_edit / tool_bash / tool_glob / tool_grep. Async tokio for
spawning + concurrent stdout/stderr capture + tokio::time::timeout
for command kill on timeout. Edit enforces uniqueness check (parity
with CLI's Edit tool).
· lib.rs — registers the 6 new commands.
## Renderer (apps/desktop/src/lib/)
· NEW mac-tools.ts — 6 ToolHandler wrappers. Each calls invoke()
instead of node:fs / node:child_process. Same interface as
@deepcode/core BUILTIN_TOOLS so the agent loop is unaware of the
swap.
· NEW mac-agent.ts — startAgentTurn() / abortAgentTurn() driver.
Owns the per-session history. Ensures provider via Tauri creds
read. Wraps a LocalToolRegistry (mirrors core's ToolRegistry shape
without dragging BUILTIN_TOOLS into the bundle).
· window-shim.ts — agent.start now invokes startAgentTurn; events
fan out through a listener bus to whoever called agent.onEvent.
## Renderer ↔ core wiring
· vite.config.ts — alias `@deepcode/core/dist/<path>` resolves to
compiled dist/, so the renderer cherry-picks { runAgent,
DeepSeekProvider, types } without dragging the whole index (which
re-exports node-fs-dependent modules).
· packages/core/package.json — added subpath exports for agent.js /
providers/deepseek.js / types.js.
· packages/core/src/agent.ts — buildSystemReminders changed to
runtime-variable dynamic import with @vite-ignore so rollup
doesn't bundle reminders/ (which imports node:fs via todo.ts).
Renderer passes systemReminders:false → branch never executes.
SessionManager import switched to type-only (was already type-
erased; comment for clarity).
## UI (apps/desktop/src/screens/Repl.tsx)
· Subscribes to agent.onEvent on mount; routes text_delta /
tool_use / tool_result / error events to the message list.
· Streaming assistant message gets a pulse caret while live.
· Stop button calls agent.abort on the active turnId.
Tests: 549 still passing. Builds: core ✓, desktop renderer (Vite) ✓
(318 KB JS / 90 KB gzipped — up from 165 KB because agent loop +
provider are now bundled).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Closes the biggest v1-blocker. Mac client can now have real DeepSeek conversations. Architecture: renderer runs @deepcode/core's runAgent; Mac tools route fs/bash through Tauri commands (6 new Rust commands). Bundle 318KB. 549 tests pass.