Skip to content

feat(desktop,core): Mac client agent loop — real runAgent in renderer#61

Merged
oratis merged 1 commit into
mainfrom
feat/mac-agent-loop-real
May 28, 2026
Merged

feat(desktop,core): Mac client agent loop — real runAgent in renderer#61
oratis merged 1 commit into
mainfrom
feat/mac-agent-loop-real

Conversation

@oratis

@oratis oratis commented May 28, 2026

Copy link
Copy Markdown
Owner

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.

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>
@oratis oratis merged commit f6d62c8 into main May 28, 2026
@oratis oratis deleted the feat/mac-agent-loop-real branch May 28, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant