OpenSpace/docs/codex-desktop-sidecar-evolution.md

246 lines
7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Codex Desktop Sidecar Evolution Integration
## Goal
This integration keeps the normal Codex Desktop workflow unchanged while moving OpenSpace skill capture and self-evolution onto a separate provider-backed sidecar path.
The target user experience is:
- Main coding still happens in Codex Desktop with the user's normal subscription login.
- OpenSpace does not take over the main task loop.
- Sidecar evolution can be invoked explicitly after a task and spend provider API tokens instead of the main Codex Desktop session.
## Short Answer: Was this mainly an API-level dual routing change?
No.
The final effect does **not** come from a simple in-process "dual route" inside one OpenSpace runtime where:
- coding uses Codex Desktop subscription auth, and
- evolution uses a provider API
That approach is not viable because Codex Desktop subscription login is not exposed to the Python process as a reusable API credential.
Instead, the final implementation uses **process-level split routing**:
- the main coding session remains in Codex Desktop
- self-evolution runs through an isolated OpenSpace sidecar with its own provider-backed MCP server
API compatibility work was still necessary, but it is only one part of the solution.
## Embedding Split Routing
The sidecar now also supports a separate skill-embedding route from the main LLM.
Recommended setup:
```bash
OPENSPACE_MODEL=gpt-5.4
OPENSPACE_LLM_API_KEY=sk-xxx
OPENSPACE_LLM_API_BASE=http://127.0.0.1:8080/v1
OPENSPACE_SKILL_EMBEDDING_BACKEND=local
OPENSPACE_SKILL_EMBEDDING_MODEL=BAAI/bge-small-en-v1.5
```
If you want a dedicated remote endpoint for skill embeddings instead of local
fastembed, set:
```bash
OPENSPACE_SKILL_EMBEDDING_BACKEND=remote
OPENSPACE_SKILL_EMBEDDING_API_KEY=sk-embed-xxx
OPENSPACE_SKILL_EMBEDDING_API_BASE=https://example.com/v1
OPENSPACE_SKILL_EMBEDDING_MODEL=openai/text-embedding-3-small
```
## What Was Implemented
### 1. OpenAI-compatible provider bridge for OpenSpace
File:
- `openspace/llm/client.py`
Why it was needed:
- The third-party relay worked with Codex's `/responses` path.
- OpenSpace uses LiteLLM / OpenAI-style chat completion flows.
- The relay was not reliable enough for OpenSpace's normal streaming path.
What changed:
- Added an OpenAI-compatible streaming fallback that talks directly to `/chat/completions`.
- Reconstructed streamed text, reasoning content, and tool calls into the shape OpenSpace already expects.
- Enabled this path through `OPENSPACE_LLM_OPENAI_STREAM_COMPAT`.
Effect:
- OpenSpace can use the relay provider for evolution workloads.
### 2. Evolution-only MCP sidecar
File:
- `openspace/evolution_mcp_server.py`
Why it was needed:
- The user wanted OpenSpace to handle only post-task evolution and skill capture.
- The main coding loop had to stay outside OpenSpace.
What changed:
- Added a separate MCP server exposing only `evolve_from_context`.
- This server builds context from the current workspace, conversation summary, and git diff.
- It captures reusable skills without becoming the main task executor.
Effect:
- OpenSpace now has a narrow sidecar role instead of replacing the host coding agent.
### 3. Sidecar-capable skill engine without full task recording
File:
- `openspace/tool_layer.py`
Why it was needed:
- The original skill evolution path assumed a fuller OpenSpace task/recording pipeline.
- The new sidecar path needed to create skills without enabling the normal OpenSpace recording flow.
What changed:
- Added `enable_skill_engine_without_recording`.
- Kept execution analysis tied to recording.
- Allowed skill evolution and skill store initialization in sidecar mode without enabling full task recordings.
Effect:
- Sidecar capture can work independently without creating full OpenSpace task sessions.
### 4. Isolated Desktop launcher overlay
File:
- `scripts/codex-desktop-evolution`
Why it was needed:
- The main Codex Desktop session had to keep the user's normal login and defaults.
- The sidecar config had to be added without polluting `~/.codex`.
What changed:
- Created an overlay `CODEX_HOME` at `~/.codex-openspace-desktop`.
- Copied the primary Desktop auth and config base into the overlay.
- Added only one extra MCP server: `openspace_evolution`.
- Scrubbed `OPENSPACE_*` variables before launching the main Codex process.
- Avoided inheriting arbitrary shell state or leaking sidecar credentials into the main coding session.
Effect:
- Main Codex Desktop remains normal.
- The sidecar is available only in the isolated overlay profile.
### 5. Agent instruction trigger for sidecar capture
File:
- `AGENTS.md`
Why it was needed:
- The sidecar should be callable naturally from the Desktop workflow.
- The user should not need to restate the full MCP call every time.
What changed:
- Added a repo-level instruction that maps phrases like `sidecar 自进化一下` to `openspace_evolution.evolve_from_context`.
- Limited the default behavior to:
- no code changes
- no main-task takeover
- at most one high-reuse skill by default
Effect:
- The sidecar behaves like a narrow post-task tool integrated into the normal Desktop workflow.
## Other Supporting Changes
### MCP stdout flush fix
File:
- `openspace/mcp_server.py`
What changed:
- Avoided a final stdout flush crash when the MCP stdio transport closes before Python exit.
### Missing dependency for MCP backend
Files:
- `pyproject.toml`
- `requirements.txt`
What changed:
- Added `websockets>=15.0.0`
- Added `openspace-evolution-mcp` as a console entrypoint
### Frontend dependency refresh
File:
- `frontend/package-lock.json`
What changed:
- Updated `lodash-es`
- Updated `vite`
This was a maintenance fix and is not part of the sidecar architecture itself.
## Architecture Summary
The final architecture is:
1. Codex Desktop remains the main coding agent.
2. Codex Desktop keeps using the user's normal subscription login.
3. A separate overlay profile adds an `openspace_evolution` MCP server.
4. That MCP server runs OpenSpace with provider-backed credentials.
5. OpenSpace uses the provider only for post-task evolution and skill capture.
This means the practical "dual routing" exists at the workflow/process boundary, not as a single shared in-process auth router.
## Usage
Launch the Desktop profile that includes the sidecar:
```bash
cd /Users/admin/PycharmProjects/openspace
./scripts/codex-desktop-evolution app
```
Inside that Desktop session, trigger sidecar capture with:
```text
sidecar 自进化一下
```
or the longer explicit form:
```text
对当前这轮工作做一次 sidecar 自进化。不要改代码,不要接管任务。请调用 openspace_evolution.evolve_from_context,基于当前对话、git diff 和关键改动,自动提炼 task/summary,最多生成 1 个高复用 skill,并告诉我 skill 名称、路径、为什么值得保留。
```
## Result
The implemented effect is:
- normal Codex Desktop coding stays unchanged
- OpenSpace self-evolution is available on demand
- provider token spend is isolated to the sidecar path
- the sidecar does not silently take over the main workflow