Files
DottaandPaperclip 2ec82c5774 fix(runner): preserve task context when tool connections change (#14963)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use tools through company-scoped connections and provider
sessions.
> - Resolving a tool connection currently forces a fresh session even
when the provider can load new tools into the existing conversation.
> - A fresh provider conversation can receive too little history to
continue the task.
> - This pull request adds explicit tool-refresh capabilities and uses
them in both runner paths.
> - Fresh attempts receive bounded task history with source IDs and
retrieval instructions.
> - The benefit is that agents can continue the same task after a
connection changes.

## Linked Issues or Issue Description

**What happened?**

A resolved tool connection forced a fresh provider conversation. The new
conversation could lose the original goal and prior answers. Claude also
rejected resume when only the MCP server set changed.

**Expected behavior**

Resume the provider conversation when its harness can refresh tools.
When a fresh session is required, supply enough bounded history to
continue the task. Preserve company, agent, task, workspace, model,
instruction, and skill checks.

**Steps to reproduce**

1. Start a conversation and agree on a task and its constraints.
2. Request and connect a tool needed for the task.
3. Continue the conversation after the connection resolves.
4. Check that the agent remembers the task and can use the new tool.

**Paperclip version or commit**

The bug was reproduced on master at `c46e41e81`. This branch is rebased
on current master.

**Deployment mode**

Self-hosted server. Both legacy adapters and the native runner are
affected.

Related public work: Refs #13282 for task-backed conversations. Refs
#13057 for the broader session-compaction proposal. Refs #14659 for
another report about local CLI session continuity. This change fixes
tool-connection continuation. Provider authentication repairs keep their
existing recovery behavior.

## What Changed

- Expose tool-refresh support in native harness descriptors and legacy
adapter metadata.
- Request tool refresh after connection resolution. Keep provider
authentication repair as a fresh-session wake.
- Reload current tools and credentials while retaining supported Claude,
Codex, Grok, and other provider conversations.
- Allow MCP-only changes during qualified native recovery. Keep all
other compatibility checks.
- Refresh managed-provider and ACPX tool bindings when attaching a new
run.
- Add a fresh-session handoff for both runner paths. Bound database
reads, excerpts, and the final packet to 24,000 bytes.
- Include the original request, recent messages, decisions, plans, prior
answers, and source IDs. Mark omitted content. Apply reset boundaries,
wake cutoffs, quarantine, and secret redaction.
- Add regression tests and document the capabilities and handoff
behavior.

## Verification

- `pnpm -r typecheck` and `pnpm build` passed. Rust formatting passed.
- Final review fixes passed 314 server tests, 333 adapter utility tests,
139 native-session runtime tests, and 12 managed-provider Rust tests.
They verify historical quarantine, raised budgets across attachment, no
history reads on successful resume, and handoff delivery on fresh retry.
- Broader branch verification also passed 1,401 adapter utility tests,
1,047 runner TypeScript tests, 43 Grok adapter tests, and 311 Rust core
tests.
- Live Claude CLI and Grok ACP probes preserved the provider session ID,
recalled a prior task constraint, and called a newly added read-only MCP
tool.
- GitHub CI passed on `b21486d18084a7aa4cafbe8e012f7cad6585d9cc`: 55
successful checks and 4 skipped checks. This includes all test shards,
all eight browser shards, runner checks, and the Grok clean public npm
install canary. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/37057514976).
- A full local test attempt encountered a separate Git snapshot timeout.
All affected local suites passed after the final edits, and the full CI
test gates passed.
- Review the capability matrix in `packages/paperclip-runner/README.md`.
Repeat the four reproduction steps with a supported provider and with an
unsupported harness.

## Risks

- Provider tool refresh can fail. Existing recovery falls back to a
fresh conversation where policy permits it.
- A new transport can replace an old process while preserving the
provider conversation. Tests cover current credentials and unchanged
identity.
- Long history can omit older context. Explicit markers and source IDs
let the agent retrieve needed context within task scope.
- Unknown and unqualified harnesses use the fresh-session path. No
database migration is required.

## Model Used

OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and live
provider testing. The exact model ID and context-window size are not
exposed in this session. Claude and Grok also ran as test subjects.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-02 15:11:44 -05:00
..

OpenClaw Gateway Adapter

This document describes how @paperclipai/adapter-openclaw-gateway invokes OpenClaw over the Gateway protocol.

Transport

This adapter always uses WebSocket gateway transport.

  • URL must be ws:// or wss://
  • Connect flow follows gateway protocol:
  1. receive connect.challenge
  2. send req connect (protocol/client/auth/device payload)
  3. send req agent
  4. wait for completion via req agent.wait
  5. stream event agent frames into Paperclip logs/transcript parsing

Auth Modes

Gateway credentials can be provided in any of these ways:

  • authToken / token in adapter config
  • headers.x-openclaw-token
  • headers.x-openclaw-auth (legacy)
  • password (shared password mode)

When a token is present and authorization header is missing, the adapter derives Authorization: Bearer <token>.

Device Auth

By default the adapter sends a signed device payload in connect params.

  • set disableDeviceAuth=true to omit device signing
  • set devicePrivateKeyPem to pin a stable signing key
  • without devicePrivateKeyPem, the adapter generates an ephemeral Ed25519 keypair per run
  • when autoPairOnFirstConnect is enabled (default), the adapter handles one initial pairing required by calling device.pair.list + device.pair.approve over shared auth, then retries once.

Session Strategy

The adapter supports the same session routing model as HTTP OpenClaw mode:

  • sessionKeyStrategy=issue|fixed|run
  • sessionKey is used when strategy is fixed

Resolved session key is sent as agent.sessionKey.

Payload Mapping

The agent request is built as:

  • required fields:
    • message (wake text plus optional payloadTemplate.message/payloadTemplate.text prefix)
    • idempotencyKey (Paperclip runId)
    • sessionKey (resolved strategy)
  • optional additions:
    • all payloadTemplate fields merged in
    • agentId from config if set and not already in template

Timeouts

  • timeoutSec controls adapter-level request budget
  • waitTimeoutMs controls agent.wait.timeoutMs

If agent.wait returns timeout, adapter returns openclaw_gateway_wait_timeout.

Log Format

Structured gateway event logs use:

  • [openclaw-gateway] ... for lifecycle/system logs
  • [openclaw-gateway:event] run=<id> stream=<stream> data=<json> for event agent frames

UI/CLI parsers consume these lines to render transcript updates.

No-remote-git contract

Like every Paperclip adapter, this one must treat the local execution-workspace cwd as the only persistence boundary across runs — no git push from runtime code, no assuming a git remote exists. The gateway transport here doesn't touch the workspace directly, but if you extend the adapter to ship code to the OpenClaw side, use the round-trip helpers in @paperclipai/adapter-utils (prepareWorkspaceForSshExecution → restoreWorkspaceFromSshExecution) rather than reaching for a git remote. See packages/adapters/AUTHORING.md for the full contract and the pinning test at packages/adapter-utils/src/ssh-fixture.test.ts.