@clawling/clawchat-plugin-openclaw 2026.7.25-1 → 2026.7.26-1
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/src/login.runtime.js +38 -3
- package/package.json +1 -1
- package/src/login.runtime.ts +37 -3
|
@@ -14,6 +14,13 @@ export const AGENTS_CONNECT_PLATFORM = "openclaw";
|
|
|
14
14
|
* always a bot; humans don't log in through this flow.
|
|
15
15
|
*/
|
|
16
16
|
export const AGENTS_CONNECT_TYPE = "clawbot";
|
|
17
|
+
/**
|
|
18
|
+
* `/v1/agents/connect` envelope code for "the supplied user_id matches no
|
|
19
|
+
* agent". Servers that predate the server-side stale-user_id fallback return
|
|
20
|
+
* this instead of degrading to a fresh pairing, so the client sheds the id and
|
|
21
|
+
* retries once.
|
|
22
|
+
*/
|
|
23
|
+
export const AGENT_NOT_FOUND_CODE = 16001;
|
|
17
24
|
/**
|
|
18
25
|
* Prompt the operator for an invite code.
|
|
19
26
|
*
|
|
@@ -140,8 +147,8 @@ export async function runOpenclawClawlingLogin(params) {
|
|
|
140
147
|
});
|
|
141
148
|
runtime.log("Verifying invite code …");
|
|
142
149
|
let result;
|
|
150
|
+
const existingUserId = account.userId.trim();
|
|
143
151
|
try {
|
|
144
|
-
const existingUserId = account.userId.trim();
|
|
145
152
|
result = await apiClient.agentsConnect({
|
|
146
153
|
code: inviteCode,
|
|
147
154
|
platform: AGENTS_CONNECT_PLATFORM,
|
|
@@ -151,9 +158,37 @@ export async function runOpenclawClawlingLogin(params) {
|
|
|
151
158
|
}
|
|
152
159
|
catch (err) {
|
|
153
160
|
if (err instanceof ClawlingApiError) {
|
|
154
|
-
|
|
161
|
+
// The stored userId is a re-pair hint, not a credential — the invite
|
|
162
|
+
// code alone decides ownership. AGENT_NOT_FOUND means it names an agent
|
|
163
|
+
// this server has never had (owner account deleted, or the config was
|
|
164
|
+
// repointed at another deployment), so replaying it would fail
|
|
165
|
+
// identically for every future invite code. A 16001 leaves the code
|
|
166
|
+
// `pending` server-side, so shedding the id and retrying once cannot
|
|
167
|
+
// double-spend it. Nothing else is retried: an owner mismatch is a real
|
|
168
|
+
// rejection, and a request that sent no id has no stale state to shed.
|
|
169
|
+
if (existingUserId && err.meta?.code === AGENT_NOT_FOUND_CODE) {
|
|
170
|
+
runtime.log(`Stored userId ${existingUserId} no longer exists on this server — retrying as a fresh pairing …`);
|
|
171
|
+
try {
|
|
172
|
+
result = await apiClient.agentsConnect({
|
|
173
|
+
code: inviteCode,
|
|
174
|
+
platform: AGENTS_CONNECT_PLATFORM,
|
|
175
|
+
type: AGENTS_CONNECT_TYPE,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch (retryErr) {
|
|
179
|
+
if (retryErr instanceof ClawlingApiError) {
|
|
180
|
+
throw new Error(`agents/connect failed (${retryErr.kind}): ${retryErr.message}`);
|
|
181
|
+
}
|
|
182
|
+
throw retryErr;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
throw new Error(`agents/connect failed (${err.kind}): ${err.message}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
throw err;
|
|
155
191
|
}
|
|
156
|
-
throw err;
|
|
157
192
|
}
|
|
158
193
|
const accessToken = requireConnectString(result?.access_token, "access_token");
|
|
159
194
|
const agentUserId = requireConnectString(result?.agent?.user_id, "agent.user_id");
|
package/package.json
CHANGED
package/src/login.runtime.ts
CHANGED
|
@@ -21,6 +21,13 @@ export const AGENTS_CONNECT_PLATFORM = "openclaw" as const;
|
|
|
21
21
|
* always a bot; humans don't log in through this flow.
|
|
22
22
|
*/
|
|
23
23
|
export const AGENTS_CONNECT_TYPE = "clawbot" as const;
|
|
24
|
+
/**
|
|
25
|
+
* `/v1/agents/connect` envelope code for "the supplied user_id matches no
|
|
26
|
+
* agent". Servers that predate the server-side stale-user_id fallback return
|
|
27
|
+
* this instead of degrading to a fresh pairing, so the client sheds the id and
|
|
28
|
+
* retries once.
|
|
29
|
+
*/
|
|
30
|
+
export const AGENT_NOT_FOUND_CODE = 16001 as const;
|
|
24
31
|
|
|
25
32
|
export type OpenclawClawchatMutateConfigFile = <T = void>(params: {
|
|
26
33
|
afterWrite: { mode: "auto" } | { mode: "none" | "restart"; reason: string };
|
|
@@ -203,8 +210,8 @@ export async function runOpenclawClawlingLogin(params: LoginParams): Promise<voi
|
|
|
203
210
|
|
|
204
211
|
runtime.log("Verifying invite code …");
|
|
205
212
|
let result;
|
|
213
|
+
const existingUserId = account.userId.trim();
|
|
206
214
|
try {
|
|
207
|
-
const existingUserId = account.userId.trim();
|
|
208
215
|
result = await apiClient.agentsConnect({
|
|
209
216
|
code: inviteCode,
|
|
210
217
|
platform: AGENTS_CONNECT_PLATFORM,
|
|
@@ -213,9 +220,36 @@ export async function runOpenclawClawlingLogin(params: LoginParams): Promise<voi
|
|
|
213
220
|
});
|
|
214
221
|
} catch (err) {
|
|
215
222
|
if (err instanceof ClawlingApiError) {
|
|
216
|
-
|
|
223
|
+
// The stored userId is a re-pair hint, not a credential — the invite
|
|
224
|
+
// code alone decides ownership. AGENT_NOT_FOUND means it names an agent
|
|
225
|
+
// this server has never had (owner account deleted, or the config was
|
|
226
|
+
// repointed at another deployment), so replaying it would fail
|
|
227
|
+
// identically for every future invite code. A 16001 leaves the code
|
|
228
|
+
// `pending` server-side, so shedding the id and retrying once cannot
|
|
229
|
+
// double-spend it. Nothing else is retried: an owner mismatch is a real
|
|
230
|
+
// rejection, and a request that sent no id has no stale state to shed.
|
|
231
|
+
if (existingUserId && err.meta?.code === AGENT_NOT_FOUND_CODE) {
|
|
232
|
+
runtime.log(
|
|
233
|
+
`Stored userId ${existingUserId} no longer exists on this server — retrying as a fresh pairing …`,
|
|
234
|
+
);
|
|
235
|
+
try {
|
|
236
|
+
result = await apiClient.agentsConnect({
|
|
237
|
+
code: inviteCode,
|
|
238
|
+
platform: AGENTS_CONNECT_PLATFORM,
|
|
239
|
+
type: AGENTS_CONNECT_TYPE,
|
|
240
|
+
});
|
|
241
|
+
} catch (retryErr) {
|
|
242
|
+
if (retryErr instanceof ClawlingApiError) {
|
|
243
|
+
throw new Error(`agents/connect failed (${retryErr.kind}): ${retryErr.message}`);
|
|
244
|
+
}
|
|
245
|
+
throw retryErr;
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
throw new Error(`agents/connect failed (${err.kind}): ${err.message}`);
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
throw err;
|
|
217
252
|
}
|
|
218
|
-
throw err;
|
|
219
253
|
}
|
|
220
254
|
|
|
221
255
|
const accessToken = requireConnectString(result?.access_token, "access_token");
|