Skip to content

feat: OpenClaw runtime model routing plugin and platform templates#320

Merged
mrcfps merged 29 commits intomainfrom
feat/session-chat-history
Mar 22, 2026
Merged

feat: OpenClaw runtime model routing plugin and platform templates#320
mrcfps merged 29 commits intomainfrom
feat/session-chat-history

Conversation

@lefarcen
Copy link
Copy Markdown
Collaborator

Summary

  • Zero-latency model routing: Add nexu-runtime-model OpenClaw plugin that intercepts before_model_resolve hook to override model provider/selection at runtime, eliminating the need for config reload when switching models
  • Platform templates: Seed new bot workspaces with official template files (AGENTS.md, SOUL.md, etc.) directly on creation, preserving user customizations on subsequent startups
  • OpenClaw hooks schema: Add proper schema support for hooks.internal.entries configuration structure

Changes

Runtime Model Plugin

  • apps/controller/static/runtime-plugins/nexu-runtime-model/ - Plugin implementation
  • apps/controller/src/runtime/openclaw-runtime-plugin-writer.ts - Plugin materialization logic
  • apps/controller/src/runtime/openclaw-runtime-model-writer.ts - Model config writer

Platform Templates

  • apps/controller/static/platform-templates/ - Official template files
  • apps/controller/src/runtime/workspace-template-writer.ts - Write to workspace root on bot creation
  • Only write on bot creation (not startup) to preserve user customizations

Other

  • packages/shared/src/schemas/openclaw-config.ts - Add hooks schema
  • apps/controller/src/app/env.ts - Add openclawExtensionsDir config
  • Update banner UI improvements

Test plan

  • Create new bot → verify workspace contains platform template files
  • Change model in UI → verify immediate effect without OpenClaw restart
  • Restart desktop → verify existing bot templates not overwritten

🤖 Generated with Claude Code

lefarcen and others added 26 commits March 19, 2026 00:25
- Rename channels: nightly-prod → beta, nightly-test → nightly
- New artifact naming: nexu-simplest-openclaw-desktop-{version}-{channel}-{arch}.{ext}
- Add latest artifacts: nexu-simplest-openclaw-desktop-latest-{channel}-{arch}.{ext}
- Patch latest-mac.yml to match new filenames for auto-update
- Remove desktop-nightly-test.yml, add desktop-beta.yml

Channel mapping:
- nightly: test environment (nexu.powerformer.net)
- beta: prod environment (nexu.io)
- stable: prod environment (nexu.io)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace all "Nexu Desktop" references with "Nexu" so that app.setName
matches the electron-builder productName.  This avoids userData path
drift — Electron derives the storage directory from app.name, and a
mismatch would silently move the data root on upgrade.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nels

For nightly and beta builds, patch package.json version at build time
(e.g. 0.1.1 → 0.1.1-nightly.20260319) so each daily build has a
unique version and electron-updater can detect it as an update.

Stable channel is unchanged — uses the version from package.json as-is.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…channels

# Conflicts:
#	apps/desktop/main/index.ts
Avoid confusion with generic "test" / "prod" naming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Sentry DSN lookup to match renamed nexu-test/nexu-prod environments
- Add build-config.json generation to desktop-release.yml (was missing)
- Add checksum upload to R2 in desktop-build.yml (parity with release)
- Stagger cron: nightly UTC 00:00, beta UTC 18:00

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove duplicate app.setName("Nexu Desktop") / app.dock.show() calls
(merge artifact). Set app name to "Nexu" once before any getPath() calls
to avoid userData/logs path inconsistency.

Update CI check scripts to match the new logs/userData directory name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…s endpoint

Replace the sidecar file-polling config sync with direct WS push using
OpenClaw's config.apply RPC. Config changes now take effect in <1s instead
of 5-15s.

Key changes:
- New openclaw-service.ts: unified WS communication module with pushConfig,
  getChannelsStatus, getChannelReadiness APIs
- publishPoolConfigSnapshot() now pushes config via WS after DB write
- Channel readiness endpoint (GET /channels/{id}/readiness) for frontend polling
- Frontend polls readiness after channel connect with progressive toast feedback
- Remove runPollLoop from gateway sidecar (config push replaces file polling)
- Various channel connection robustness fixes (transactions, upsert, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…channels

# Conflicts:
#	apps/web/src/pages/home.tsx
#	pnpm-lock.yaml
# Conflicts:
#	apps/desktop/main/runtime/manifests.ts
#	apps/desktop/scripts/prepare-pglite-sidecar.mjs
#	apps/web/lib/api/sdk.gen.ts
#	apps/web/lib/api/types.gen.ts
- Add chat history API: controller reads JSONL session files and exposes
  GET /api/v1/sessions/{id}/messages endpoint
- Add legacy API runtime session routes via OpenClaw WS RPC
- Rewrite sessions page as chat view with user/assistant message bubbles
  (user right-aligned dark, assistant left-aligned light with brand avatar)
- Add SidebarSession mapping layer for unified sidebar data source
- Reduce sidebar polling to 10s, chat history polls at 5s
- Add i18n keys for chat view (en + zh-CN)
- Fix merge issues: channel readiness API rename, import ordering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…isplay

- Load workspace root .env in controller for LiteLLM env vars
  (fixes desktop sidecar not reading LITELLM_BASE_URL/API_KEY)
- Inject LiteLLM provider and prefix bare model IDs with litellm/
  (fixes "Unknown model: anthropic/claude-sonnet-4")
- Infer session title and channelType from JSONL first user message
  (shows sender name instead of UUID in sidebar)
- Strip OpenClaw metadata blocks from user message display
  (removes Conversation/Sender metadata and timestamp prefixes)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves conflicts in openclaw-service, pool-config-service,
sdk.gen, channel-connect-modal, inline-model-selector, switch,
i18n, index.css, workspace-layout, and home page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Feishu Card Kit streaming API returns 400 when the app doesn't
have streaming card permissions. Fall back to non-streaming replies.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts:
#	apps/web/lib/api/sdk.gen.ts
Sessions page:
- Header with Group badge and "Open in {channel}" button
- User avatar: circular gradient background with sender initials
- Extract sender name from OpenClaw metadata for avatar display
- Artifact card for tool call messages (green status + link)
- Improved bubble styles matching design spec

Sidebar:
- Add feishu platform icon (blue bg + bird emoji)
- Show relative time + channel type in session subtitle
- Active status green dot indicator

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add POST /api/internal/desktop/shell-open controller endpoint so
  browser-mode "Open Folder" works by delegating to the OS shell
  (path restricted to OPENCLAW_STATE_DIR for safety)
- Update frontend openLocalFolderUrl() fallback to call controller API
  instead of blocked file:// window.open
- Chat view UI overhaul matching product design
- Add desktop sleep-guard, channel-links, platform-icons
- Add tests for sessions-runtime, desktop-links, activity-feed,
  workspace-layout, sessions, sleep-guard

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move Feishu openChatId/chat metadata resolution to controller-side
sessions-runtime so the web frontend can directly open the correct
bot chat. Remove client-side getFeishuOpenId fallback that is no
longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve pnpm-lock.yaml conflict after main removed legacy apps/api,
apps/gateway, deploy/, and numerous SaaS-era assets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Runtime Model Routing Plugin
- Add nexu-runtime-model plugin for zero-latency model switching
- Plugin intercepts before_model_resolve hook to override provider/model
- Supports runtime model selection without OpenClaw config reload
- Add plugin writer to materialize plugin files on startup

## Platform Templates
- Add platform template files (AGENTS.md, SOUL.md, etc.) for new bots
- Write templates directly to workspace root on bot creation
- Remove startup template sync to preserve user customizations

## Other Changes
- Add OpenClaw hooks schema support (internal.entries structure)
- Improve update banner UI with dismissed state
- Add openclawExtensionsDir to controller env configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolve merge conflicts:
- Use main's UpdateFloatCard component for update UI
- Keep HEAD's use-auto-update.ts logic (state regression prevention)
- Remove obsolete skills system (replaced by SkillHub)
- Keep runtime plugin/model writers for zero-latency model routing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Mar 21, 2026

Deploying nexu-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1839c50
Status: ✅  Deploy successful!
Preview URL: https://8c466543.nexu-docs.pages.dev
Branch Preview URL: https://feat-session-chat-history.nexu-docs.pages.dev

View logs

lefarcen and others added 3 commits March 21, 2026 16:01
The web app uses @nexu/shared but didn't declare it as a dependency,
causing pnpm to run builds in parallel. This led to CI failures where
vite couldn't resolve @nexu/shared because its dist wasn't built yet.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add secret existence check to prevent workflow failure when the
CLOUDFLARE_ZONE_ID secret is not configured.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mrcfps mrcfps merged commit e0abcf8 into main Mar 22, 2026
6 checks passed
@mrcfps mrcfps deleted the feat/session-chat-history branch March 22, 2026 05:14
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.

2 participants