239 lines
7.5 KiB
Markdown
239 lines
7.5 KiB
Markdown
# Claude Bridge Model Design
|
|
|
|
## Purpose
|
|
|
|
Define how Claude-backed contractor agents integrate into OpenClaw using a custom model seam.
|
|
|
|
This document is specific to the Claude phase of ContractorAgent.
|
|
|
|
## Why this must be a custom model
|
|
|
|
OpenClaw expects every agent to have a primary model. For contractor-backed agents, the actual reasoning engine is not a normal OpenClaw LLM provider call, but a Claude Code session managed outside the usual stateless completion flow.
|
|
|
|
Therefore the contractor integration should present itself to OpenClaw as a custom model id, while internally acting as a stateful bridge to Claude Code.
|
|
|
|
Recommended model id for phase 1:
|
|
|
|
- `contractor-claude-bridge`
|
|
|
|
## Mental model
|
|
|
|
From OpenClaw's perspective:
|
|
|
|
- the agent has a normal primary model
|
|
- a model request is issued for each turn
|
|
- the model returns assistant output
|
|
|
|
From the plugin's perspective:
|
|
|
|
- the model request is actually a routing event
|
|
- the request identifies the OpenClaw session and agent
|
|
- the plugin resolves a mapped Claude Code session
|
|
- the plugin forwards only the newest actionable turn to Claude Code
|
|
- the plugin returns Claude's output as the model response
|
|
|
|
So this is a pseudo-model backend with sessionful behavior.
|
|
|
|
## Responsibilities of the bridge model
|
|
|
|
The bridge model should:
|
|
|
|
1. accept model requests for contractor-backed agents
|
|
2. identify the current OpenClaw session and contractor agent id
|
|
3. resolve or create the mapped Claude Code session
|
|
4. filter OpenClaw-managed envelope/context
|
|
5. forward only the latest actionable message plus minimal metadata
|
|
6. collect Claude Code output
|
|
7. normalize that output into an OpenClaw model response
|
|
8. persist session mapping metadata
|
|
|
|
The bridge model should not:
|
|
|
|
- act like a generic stateless LLM provider
|
|
- replay full OpenClaw session history every turn unless recovery is required
|
|
- try to mirror all Claude internal state into OpenClaw session files
|
|
|
|
## Model lifecycle
|
|
|
|
### First turn in an OpenClaw session
|
|
|
|
1. OpenClaw selects `contractor-claude-bridge` as the agent's primary model
|
|
2. bridge model receives the turn input
|
|
3. plugin extracts:
|
|
- agent id
|
|
- OpenClaw session key
|
|
- workspace
|
|
- latest user message
|
|
4. no session mapping exists yet
|
|
5. plugin creates a Claude Code session through ACP/runtime integration
|
|
6. plugin injects initial contractor instructions and minimal OpenClaw metadata
|
|
7. plugin sends the latest user message
|
|
8. Claude responds
|
|
9. plugin stores the new mapping and returns assistant output to OpenClaw
|
|
|
|
### Later turns
|
|
|
|
1. bridge model receives next turn
|
|
2. plugin resolves existing mapping
|
|
3. plugin resumes or continues the Claude Code session
|
|
4. plugin forwards latest user message only
|
|
5. Claude responds
|
|
6. plugin returns normalized response and updates mapping timestamps
|
|
|
|
### Reset or new session
|
|
|
|
Reset semantics should be explicit.
|
|
|
|
Recommended behavior:
|
|
|
|
- OpenClaw `/new` or reset-equivalent for this agent should create a fresh Claude session transcript
|
|
- keep the OpenClaw agent identity and routing stable
|
|
- replace the existing mapping for the OpenClaw session key
|
|
- reinject initial contractor instructions
|
|
|
|
## Session mapping contract
|
|
|
|
Bridge model depends on a persistent mapping store.
|
|
|
|
Suggested record shape:
|
|
|
|
```ts
|
|
type ContractorSessionMapEntry = {
|
|
openclawSessionKey: string
|
|
agentId: string
|
|
contractor: "claude"
|
|
claudeSessionId: string
|
|
workspace: string
|
|
createdAt: string
|
|
lastActivityAt: string
|
|
state: "active" | "closed" | "orphaned"
|
|
}
|
|
```
|
|
|
|
## Input filtering
|
|
|
|
The bridge model must not blindly forward the entire model input payload to Claude Code.
|
|
|
|
Instead it should derive a contractor payload with:
|
|
|
|
- latest user-visible message
|
|
- minimal agent metadata
|
|
- minimal workspace metadata
|
|
- optional turn metadata needed for reply formatting or approvals
|
|
|
|
It should ignore or strip:
|
|
|
|
- repeated long-form system envelope generated by OpenClaw
|
|
- redundant chat history already owned by Claude session memory
|
|
- internal bookkeeping not useful to Claude Code
|
|
|
|
This keeps Claude as the owner of live context.
|
|
|
|
## Initial contractor instructions
|
|
|
|
When creating a fresh Claude session, inject a stable bootstrap payload that includes:
|
|
|
|
- identity of the contractor role inside OpenClaw
|
|
- workspace path
|
|
- allowed interaction style with OpenClaw
|
|
- tool/skill access strategy
|
|
- output expectations for OpenClaw replies
|
|
- rule that session continuity lives primarily in Claude Code session state
|
|
|
|
This injection should happen on session creation and hard resets, not every turn.
|
|
|
|
## Output normalization
|
|
|
|
Claude output must be normalized before returning to OpenClaw.
|
|
|
|
Normalization should handle:
|
|
|
|
- plain assistant text
|
|
- tool-use related status text
|
|
- multi-part responses if Claude adapter streams or chunks
|
|
- failures or blocked actions
|
|
- explicit clarification requests
|
|
|
|
The custom model should emit output in a way OpenClaw can treat as a normal assistant response.
|
|
|
|
## Session file interaction
|
|
|
|
The current working assumption is:
|
|
|
|
- OpenClaw session files remain the system of record for visible conversation state
|
|
- Claude session state remains the system of record for internal live reasoning context
|
|
|
|
Therefore the bridge model should inject Claude responses back into OpenClaw's normal session response path, rather than bypassing it.
|
|
|
|
This means the plugin should preserve OpenClaw's normal transcript behavior while avoiding full upstream context replay.
|
|
|
|
## Recovery behavior
|
|
|
|
### Missing Claude session
|
|
|
|
If the mapped Claude session is missing or invalid:
|
|
|
|
1. mark mapping as `orphaned`
|
|
2. create a fresh Claude session
|
|
3. inject bootstrap context
|
|
4. optionally summarize minimal recent OpenClaw-visible context for recovery
|
|
5. store replacement mapping
|
|
|
|
This should be treated as degraded recovery, not the normal path.
|
|
|
|
### Mapping corruption
|
|
|
|
If mapping storage cannot be read:
|
|
|
|
- fail closed for the turn if data integrity is uncertain
|
|
- or create a new Claude session only when policy allows and user impact is acceptable
|
|
|
|
## Why not use a normal provider model directly
|
|
|
|
Because a normal provider model implies:
|
|
|
|
- stateless prompt in
|
|
- stateless completion out
|
|
- OpenClaw-owned context reconstruction each turn
|
|
|
|
That is the opposite of the intended contractor design.
|
|
|
|
The custom model seam is useful precisely because it lets OpenClaw keep the agent abstraction while delegating real session continuity to Claude Code.
|
|
|
|
## Open questions
|
|
|
|
1. Which provider/plugin registration seam is best for the bridge model id?
|
|
2. What exact request shape does the plugin receive for a model turn in OpenClaw runtime?
|
|
3. Where should bootstrap instructions be stored, generated text, template file, or config?
|
|
4. How should streaming behavior be represented if Claude session output arrives incrementally?
|
|
5. How should tool requests from Claude be surfaced back into OpenClaw tool execution?
|
|
|
|
## References
|
|
|
|
### OpenClaw plugin capability
|
|
|
|
> "Plugins extend OpenClaw with new capabilities: channels, model providers, ... agent tools, or any combination."
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/plugins/building-plugins
|
|
|
|
### Plugin entry model
|
|
|
|
> "For provider plugins, tool plugins, hook plugins, and anything that is not a messaging channel."
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/plugins/sdk-entrypoints
|
|
|
|
### Claude Code via ACP
|
|
|
|
> "ACP sessions let OpenClaw run external coding harnesses (for example ... Claude Code ...) through an ACP backend plugin."
|
|
|
|
> "For Claude Code through ACP, the stack is:
|
|
> 1. OpenClaw ACP session control plane
|
|
> 2. bundled `acpx` runtime plugin
|
|
> 3. Claude ACP adapter
|
|
> 4. Claude-side runtime/session machinery"
|
|
|
|
Source:
|
|
- https://docs.openclaw.ai/tools/acp-agents
|