Skip to content

Universal agent support: shim contract, agent types, Hermes & NanoClaw images - #208

Open
gluk-w wants to merge 1 commit into
mainfrom
feat/universal-agent-shim
Open

Universal agent support: shim contract, agent types, Hermes & NanoClaw images#208
gluk-w wants to merge 1 commit into
mainfrom
feat/universal-agent-shim

Conversation

@gluk-w

@gluk-w gluk-w commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Claworc can now manage any AI agent, not only OpenClaw. Agent images implement the Claworc Agent Shim Contract (docs/shim.md): exec-based scripts under /opt/claworc/shim/ invoked over the existing SSH channel — chat streamed as JSONL events, config get/set, configure-llm virtual-key routing, health, restart, and agent.txt/agent.svg identity files. No new daemons or ports.

Highlights

  • internal/agentshim package with strict layering (handlers → agentshim → sshproxy → orchestrator): Client/Session interfaces, agent-type registry, and a factory with two adapters — shimexec (the standard contract) and openclawnative (drives pre-shim OpenClaw images via their gateway WS/CLI). The factory probes images for the shim and falls back to native fail-open, so already-deployed OpenClaw instances keep working with zero rebuilds.
  • Chat, webhooks, config editor, and LLM virtual-key routing all go through the shim interface; the normalized event schema is also the browser chat protocol (frontend updated in lockstep, cumulative-snapshot semantics preserved).
  • Agent types in the product: agent_type on instances (+ backfill migration), per-type default images in Settings, type picker on create, GET /api/v1/agent-types, capability-gated Config tab and Control UI button.
  • Four images, all passing the 24-check shim-selftest conformance suite:
    • agent/openclaw (renamed from agent/instance) — shim bridges to the local gateway; legacy OPENCLAW_* env still honored
    • agent/hermes — Hermes v2026.8.3 pinned; native session resume; validated live against a stub LLM endpoint (chat/resume/reset/abort)
    • agent/nanoclaw — no Docker-in-Docker: a minimal patch lets the shim supervise the agent-runner as a child process; exact end-of-turn detection via NanoClaw's own processing_ack marker
    • agent/template — pure-shell copy-me starting point for bring-your-own-agent images
  • Kanban board hidden from navigation; kanban/moderator code untouched.
  • New reserved env vars CLAWORC_AGENT_TOKEN, CLAWORC_INITIAL_LLM_CONFIG, CLAWORC_LLM_PROXY_URL.

Testing

  • Full Go suite green (agentshim, handlers, database, migrations); shimexec adapter passes under -race -count=4
  • Frontend vite build passes with no new type errors
  • All three agent images build and boot (arm64); conformance selftests pass inside each image
  • Not yet exercised: real-LLM round trips for Hermes/NanoClaw (validated to the API-call boundary with stubs) and amd64 builds (handled by multi-arch CI push)

🤖 Generated with Claude Code

https://claude.ai/code/session_01AeFUE6d2wUXWBHqrcF69e1

…w images

Claworc can now manage any AI agent, not only OpenClaw. Agent images
implement the exec-based Claworc Agent Shim Contract (docs/shim.md):
well-known scripts under /opt/claworc/shim/ invoked over SSH, with chat
streamed as JSONL events (cumulative snapshots), config get/set,
configure-llm virtual-key routing, health, restart, and agent.txt/agent.svg
identity files.

- New internal/agentshim package: Client/Session interfaces, agent-type
  registry, and factory with two adapters — shimexec (the standard contract)
  and openclawnative (drives pre-shim OpenClaw images unchanged). Factory
  probes images for the shim and falls back to native, fail-open, so
  existing deployments keep working without rebuilds.
- Strict layering: handlers -> agentshim -> sshproxy -> orchestrator; the
  orchestrator no longer carries any agent-specific knowledge.
- Chat, webhooks, config editor, and LLM virtual-key routing all go through
  the shim interface; the normalized event schema is also the browser chat
  protocol (useChat.ts updated in lockstep).
- Instance.agent_type column + backfill migration, per-type default images,
  GET /api/v1/agent-types, type picker on create, capability-gated Config
  tab and Control UI button.
- agent/instance renamed to agent/openclaw and extended with the shim;
  new agent/hermes and agent/nanoclaw images (both pass the 24-check
  conformance selftest; NanoClaw runs without Docker-in-Docker via a
  minimal session-dir patch), plus agent/template as a copy-me starting
  point with shim-selftest.
- Kanban board hidden from navigation; kanban/moderator code untouched.
- New reserved env vars CLAWORC_AGENT_TOKEN, CLAWORC_INITIAL_LLM_CONFIG,
  CLAWORC_LLM_PROXY_URL; OPENCLAW_* names remain reserved and injected for
  OpenClaw instances.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AeFUE6d2wUXWBHqrcF69e1
}

send(frame) {
this.ws.send(JSON.stringify(frame));
try {
// Node's undici WebSocket accepts a non-standard `headers` option; the
// gateway expects a loopback Origin (mirrors gateway_dialer.go).
ws = new WebSocket(url, { headers: { Origin: GATEWAY_ORIGIN } });
// gateway expects a loopback Origin (mirrors gateway_dialer.go).
ws = new WebSocket(url, { headers: { Origin: GATEWAY_ORIGIN } });
} catch {
ws = new WebSocket(url);
if r.DefaultModel == "" {
return nil
}
models := make([]string, 0, 1+len(r.FallbackModels))
}
var ev agentshim.Event
if err := json.Unmarshal(line, &ev); err != nil {
log.Printf("[shimexec] session %s: skipping malformed event line: %v", s.key, err)
}
}
if serr := sc.Err(); serr != nil {
log.Printf("[shimexec] session %s: chat-send stdout read error: %v", s.key, serr)

if sawEnd {
if code != 0 || werr != nil {
log.Printf("[shimexec] session %s: chat-send exited code=%d err=%v after end event", s.key, code, werr)
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