@linkedclaw/consumer-runtime 0.9.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -6,20 +6,34 @@ interface HireParams {
6
6
  maxMessages?: number;
7
7
  referredBy?: string;
8
8
  autoActivate?: boolean;
9
- /** Override the default relay URL (defaults to the cloud relay /ws endpoint). */
9
+ /** Override the default relay URL (only used when ``tryAcp: true``). */
10
10
  relayUrl?: string;
11
11
  /**
12
- * Try /acp (OpenClaw sub-agent bridge) before /ws. Default false — mirrors
13
- * `SkillConfig.try_acp = False` on the provider side (upstream commit
14
- * 2dbc36c). Native providers register on /ws and are reachable there; only
15
- * opt in when the target is an ACP-routed agent (OpenClaw sub-agent). When
16
- * opted in, falls back to /ws if /acp connect fails or the recipient is
17
- * absent from /acp's connection table.
12
+ * Try /acp (OpenClaw sub-agent bridge) before /ws. Default false.
13
+ *
14
+ * **Default flow (recommended)** no WS opens at all on the requester side:
15
+ * `POST /sessions` `POST /activate`. The cloud drives the
16
+ * SESSION_CREATE/ACCEPT handshake to the provider on its own (relay's
17
+ * `deliver_session_create_and_await_accept`, upstream `1f1b363f`). The
18
+ * /activate call returns 200 once the provider accepts, with timing /
19
+ * failure surfaced as 503 / 408 / 403 status codes.
20
+ *
21
+ * **Opt-in WS path (`tryAcp: true`)** — only needed for OpenClaw
22
+ * sub-agent / ACP-routed agents. Opens a transient WS to /acp first
23
+ * (2s connect timeout); falls back to /ws if /acp connect fails or
24
+ * the recipient is absent from /acp's connection table. When this
25
+ * path runs, /activate sees the in-memory session as already active
26
+ * and short-circuits.
18
27
  */
19
28
  tryAcp?: boolean;
20
- /** API key + agent ID for the IDENTIFY frame. */
29
+ /** API key (Bearer token + WS IDENTIFY token when tryAcp is enabled). */
21
30
  apiKey: string;
22
- agentId: string;
31
+ /**
32
+ * Required only when `tryAcp: true` — the WS IDENTIFY frame validates
33
+ * `listing.owner_id == user_id` against this string. Default HTTP path
34
+ * does not need a registered listing — leave undefined.
35
+ */
36
+ agentId?: string;
23
37
  }
24
38
  interface HireResult {
25
39
  session: Session;
@@ -37,11 +51,15 @@ declare class RequesterFlows {
37
51
  sort?: string;
38
52
  }): Promise<Agent[]>;
39
53
  /**
40
- * Open a session. HTTP create → WS handshake (SESSION_CREATE/ACCEPT) → done.
54
+ * Open a session.
55
+ *
56
+ * Default: pure HTTP — `POST /sessions` then `POST /activate`. Cloud
57
+ * drives the SESSION_CREATE handshake to the provider server-side. No
58
+ * WebSocket opens on the requester side; no `agentId` registration
59
+ * required.
41
60
  *
42
- * Default transport is /ws native providers register there
43
- * (`SkillConfig.try_acp=False` upstream default). Set `tryAcp: true` to try
44
- * /acp first; on opt-in, falls back to /ws when the recipient isn't on /acp.
61
+ * `tryAcp: true` opts into the legacy WS handshake path for OpenClaw
62
+ * sub-agent / ACP-routed scenarios see {@link HireParams.tryAcp}.
45
63
  */
46
64
  hire(params: HireParams): Promise<HireResult>;
47
65
  private attemptHandshake;
package/dist/index.js CHANGED
@@ -25,11 +25,15 @@ var RequesterFlows = class {
25
25
  return this.client.discover({ capability, ...extra });
26
26
  }
27
27
  /**
28
- * Open a session. HTTP create → WS handshake (SESSION_CREATE/ACCEPT) → done.
28
+ * Open a session.
29
29
  *
30
- * Default transport is /ws native providers register there
31
- * (`SkillConfig.try_acp=False` upstream default). Set `tryAcp: true` to try
32
- * /acp first; on opt-in, falls back to /ws when the recipient isn't on /acp.
30
+ * Default: pure HTTP — `POST /sessions` then `POST /activate`. Cloud
31
+ * drives the SESSION_CREATE handshake to the provider server-side. No
32
+ * WebSocket opens on the requester side; no `agentId` registration
33
+ * required.
34
+ *
35
+ * `tryAcp: true` opts into the legacy WS handshake path for OpenClaw
36
+ * sub-agent / ACP-routed scenarios — see {@link HireParams.tryAcp}.
33
37
  */
34
38
  async hire(params) {
35
39
  const session = await this.client.createSession({
@@ -39,9 +43,9 @@ var RequesterFlows = class {
39
43
  ...params.referredBy !== void 0 ? { referred_by: params.referredBy } : {}
40
44
  });
41
45
  if (params.autoActivate === false) return { session, activated: false };
42
- const relayUrl = params.relayUrl ?? DEFAULT_RELAY_URL;
43
46
  try {
44
47
  if (params.tryAcp) {
48
+ const relayUrl = params.relayUrl ?? DEFAULT_RELAY_URL;
45
49
  const acpUrl = relayUrl.replace(/\/ws$/, "/acp");
46
50
  try {
47
51
  await this.attemptHandshake(acpUrl, session.session_id, params, ACP_CONNECT_TIMEOUT_MS);
@@ -49,9 +53,8 @@ var RequesterFlows = class {
49
53
  if (!(err instanceof TransportMissError)) throw err;
50
54
  await this.attemptHandshake(relayUrl, session.session_id, params, SESSION_ACCEPT_TIMEOUT_MS);
51
55
  }
52
- } else {
53
- await this.attemptHandshake(relayUrl, session.session_id, params, SESSION_ACCEPT_TIMEOUT_MS);
54
56
  }
57
+ await this.client.activateSession(session.session_id);
55
58
  } catch (err) {
56
59
  await this.client.endSession(session.session_id, {}).catch(() => {
57
60
  });
@@ -62,7 +65,14 @@ var RequesterFlows = class {
62
65
  }
63
66
  return { session, activated: true };
64
67
  }
68
+ // tryAcp:true path only. Default `hire()` no longer calls this — see the
69
+ // method comment on `hire`. Kept for OpenClaw sub-agent integration.
65
70
  async attemptHandshake(url, sessionId, params, connectTimeoutMs) {
71
+ if (!params.agentId) {
72
+ throw new Error(
73
+ "attemptHandshake (tryAcp:true) requires `agentId` in HireParams \u2014 the WS IDENTIFY frame validates listing ownership. Use the default HTTP path (omit tryAcp) if you don't have a registered agent listing."
74
+ );
75
+ }
66
76
  const ws = new WebSocket(url);
67
77
  try {
68
78
  await new Promise((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linkedclaw/consumer-runtime",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Runtime helpers (RequesterFlows, ACP) for LinkedClaw consumer agents",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  "dependencies": {
24
24
  "ws": "^8.18.0",
25
25
  "zod": "^3.23.0",
26
- "@linkedclaw/consumer": "^0.9.1",
26
+ "@linkedclaw/consumer": "^0.9.2",
27
27
  "@linkedclaw/provider": "^0.9.1"
28
28
  },
29
29
  "devDependencies": {