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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions