Skip to content

Add callback session metadata for supervised launches and cross-adapter completion routing #104

@c-h-

Description

@c-h-

Summary

We want coding-agent completions to return to the same OpenClaw session/workspace that launched them when a callback target exists, with fallback to the current async/background event flow otherwise.

The cleanest place to originate that callback metadata is agentctl, because it is the cross-adapter supervision layer. Harness-specific completion events (Claude Code / OpenCode / Codex / etc.) should not each invent their own callback contract.

Why this belongs in agentctl

agentctl already has the right abstraction boundary:

  • it is the normalized launch surface across adapters
  • AgentSession already has meta: Record<string, unknown>
  • daemon launch metadata is already persisted and merged back into discovered sessions
  • event consumers (OrgLoop, etc.) can read one consistent session schema instead of adapter-specific payloads

Problem to solve

Today, downstream systems can observe that a coding agent completed, but they don't know where to route the result back in OpenClaw. That means completion often wakes a separate background session instead of returning to the session that launched the work.

We want agentctl to carry an optional callback target so downstream systems can do:

  1. preferred: direct callback into the originating OpenClaw session
  2. fallback: existing webhook/new-session behavior

Proposed change

Add launch-time callback metadata support, stored in AgentSession.meta and surfaced everywhere session metadata already flows.

CLI surface

Add generic flags such as:

  • --callback-session <sessionKey>
  • --callback-agent <agentId> (optional / future-proof)
  • possibly --callback-workspace <workspace> if needed, though this may be redundant if session key is sufficient

This should work for single-adapter and multi-adapter launches.

Data model

Persist into session.meta, e.g.:

{
  "openclaw_callback_session_key": "agent:personal:main",
  "openclaw_callback_agent_id": "personal",
  "launched_via": "openclaw"
}

Exact key names are up for discussion, but they should be:

  • explicit
  • stable
  • not adapter-specific

Existing relevant evidence

A few notes from the current codebase:

  • AgentSession.meta already exists in src/core/types.ts
  • daemon/session tracking already preserves meta
  • sessionToJson() includes meta
  • but agentctl events currently streams only the Claude Code adapter's event stream (getAdapter("claude-code")), which is not sufficient as the universal event surface for this use case

That last point is important: this issue is about callback metadata, but it also underscores that the event surface should be thought of as agentctl-level, not Claude-specific.

Acceptance criteria

  • agentctl launch accepts callback metadata flags
  • metadata is stored on launched sessions across adapters
  • metadata survives daemon tracking / enrichment
  • list --json, status, and any event JSON output include the metadata
  • multi-adapter launch preserves the callback metadata on each launched session
  • docs mention the callback pattern for supervised async tasks

Notes

This issue does not require implementing delivery into OpenClaw sessions; that's downstream. The responsibility here is to make callback intent a first-class, cross-adapter part of agentctl's session metadata contract.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions