@openclaw/copilot 2026.5.31-beta.3 → 2026.5.31-beta.4

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.
@@ -1,8 +1,26 @@
1
- import { n as createInfiniteSessionConfig, r as resolveCopilotAuth } from "./harness-CsSU8FFW.js";
1
+ import { n as resolveCopilotAuth } from "./harness-CGzfTXDg.js";
2
+ import { acquireSessionWriteLock, appendSessionTranscriptMessage, applyEmbeddedAttemptToolsAllow, buildEmbeddedAttemptToolRunContext, detectAndLoadAgentHarnessPromptImages, emitSessionTranscriptUpdate, getPluginToolMeta, isSubagentSessionKey, resolveAttemptFsWorkspaceOnly, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveEmbeddedAttemptToolConstructionPlan, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockAcquireTimeoutMs, resolveUserPath, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
2
3
  import { createHash } from "node:crypto";
3
4
  import path from "node:path";
4
5
  import fsp from "node:fs/promises";
5
- import { acquireSessionWriteLock, appendSessionTranscriptMessage, applyEmbeddedAttemptToolsAllow, buildEmbeddedAttemptToolRunContext, detectAndLoadAgentHarnessPromptImages, emitSessionTranscriptUpdate, getPluginToolMeta, isSubagentSessionKey, resolveAttemptFsWorkspaceOnly, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveEmbeddedAttemptToolConstructionPlan, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockAcquireTimeoutMs, resolveUserPath, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
6
+ //#region extensions/copilot/src/compaction-bridge.ts
7
+ /**
8
+ * Shape an `InfiniteSessionConfig` for `SessionConfig.infiniteSessions`.
9
+ * Returns `undefined` when no fields were supplied so callers can
10
+ * spread conditionally and let the SDK apply its own defaults
11
+ * (`enabled: true`, background 0.80, buffer 0.95). Any explicitly-set
12
+ * value (including `enabled: false` to disable infinite sessions) is
13
+ * preserved.
14
+ */
15
+ function createInfiniteSessionConfig(options) {
16
+ if (!options) return;
17
+ const result = {};
18
+ if (options.enabled !== void 0) result.enabled = options.enabled;
19
+ if (options.backgroundCompactionThreshold !== void 0) result.backgroundCompactionThreshold = options.backgroundCompactionThreshold;
20
+ if (options.bufferExhaustionThreshold !== void 0) result.bufferExhaustionThreshold = options.bufferExhaustionThreshold;
21
+ return Object.keys(result).length > 0 ? result : void 0;
22
+ }
23
+ //#endregion
6
24
  //#region extensions/copilot/src/dual-write-transcripts.ts
7
25
  /**
8
26
  * Mirrors the AgentMessages produced by the copilot agent runtime into the
@@ -230,7 +248,7 @@ function attachEventBridge(session, options) {
230
248
  firstDeltaError ??= error;
231
249
  });
232
250
  deltaChain = deltaQueue.then(() => {
233
- if (firstDeltaError !== void 0) throw firstDeltaError;
251
+ if (firstDeltaError !== void 0) throw toLintErrorObject(firstDeltaError, "Non-Error thrown");
234
252
  });
235
253
  deltaChain.catch(() => void 0);
236
254
  });
@@ -394,6 +412,13 @@ function registerListener(session, unsubscribeFns, eventType, handler) {
394
412
  session.off?.(eventType, handler);
395
413
  });
396
414
  }
415
+ function toLintErrorObject(value, fallbackMessage) {
416
+ if (value instanceof Error) return value;
417
+ if (typeof value === "string") return new Error(value);
418
+ const error = new Error(fallbackMessage, { cause: value });
419
+ if (typeof value === "object" && value !== null || typeof value === "function") Object.assign(error, value);
420
+ return error;
421
+ }
397
422
  //#endregion
398
423
  //#region extensions/copilot/src/hooks-bridge.ts
399
424
  const DEFAULT_HOOK_ERROR_HANDLER = ({ hookName, error }) => {
@@ -846,7 +871,7 @@ function convertOpenClawToolToSdkTool(sourceTool, ctx) {
846
871
  } catch (error) {
847
872
  return createFailureResult(`[copilot-tool-bridge] beforeExecute failed for tool '${sourceTool.name}': ${toError$1(error).message}`, error);
848
873
  }
849
- let preparedArgs = args;
874
+ let preparedArgs;
850
875
  try {
851
876
  preparedArgs = sourceTool.prepareArguments ? sourceTool.prepareArguments(args) : args;
852
877
  } catch (error) {
@@ -1318,7 +1343,8 @@ async function runCopilotAttempt(params, deps) {
1318
1343
  if (sdkSessionId && deps.onSessionEstablished) try {
1319
1344
  deps.onSessionEstablished({
1320
1345
  sdkSessionId,
1321
- pooledClient: handle
1346
+ pooledClient: handle,
1347
+ sessionConfig
1322
1348
  });
1323
1349
  } catch {}
1324
1350
  bridge = attachEventBridge(session, {
@@ -1663,4 +1689,4 @@ function isSdkSendAndWaitTimeoutError(error) {
1663
1689
  return /^Timeout after \d+ms waiting for session\.idle$/.test(message);
1664
1690
  }
1665
1691
  //#endregion
1666
- export { runCopilotAttempt };
1692
+ export { resolvePoolAcquire, runCopilotAttempt };
@@ -1,7 +1,7 @@
1
+ import { compactWithSafetyTimeout, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
1
2
  import { createHash } from "node:crypto";
2
3
  import { homedir } from "node:os";
3
4
  import { join, resolve } from "node:path";
4
- import { mkdir, writeFile } from "node:fs/promises";
5
5
  //#region extensions/copilot/src/auth-bridge.ts
6
6
  /**
7
7
  * Pure functional auth resolver for the copilot agent runtime.
@@ -184,84 +184,48 @@ function readString(value) {
184
184
  return typeof value === "string" && value.length > 0 ? value : void 0;
185
185
  }
186
186
  //#endregion
187
- //#region extensions/copilot/src/compaction-bridge.ts
188
- /**
189
- * Shape an `InfiniteSessionConfig` for `SessionConfig.infiniteSessions`.
190
- * Returns `undefined` when no fields were supplied so callers can
191
- * spread conditionally and let the SDK apply its own defaults
192
- * (`enabled: true`, background 0.80, buffer 0.95). Any explicitly-set
193
- * value (including `enabled: false` to disable infinite sessions) is
194
- * preserved.
195
- */
196
- function createInfiniteSessionConfig(options) {
197
- if (!options) return;
198
- const result = {};
199
- if (options.enabled !== void 0) result.enabled = options.enabled;
200
- if (options.backgroundCompactionThreshold !== void 0) result.backgroundCompactionThreshold = options.backgroundCompactionThreshold;
201
- if (options.bufferExhaustionThreshold !== void 0) result.bufferExhaustionThreshold = options.bufferExhaustionThreshold;
202
- return Object.keys(result).length > 0 ? result : void 0;
203
- }
204
- function compactJsonValue(input) {
205
- const out = {};
206
- for (const [key, value] of Object.entries(input)) if (value !== void 0) out[key] = value;
207
- return out;
208
- }
209
- /**
210
- * Write an OpenClaw-shaped compaction marker JSON file under
211
- * `<workspaceDir>/<subdir>/openclaw-compaction-<sessionId>-<ts>.json`.
212
- *
213
- * Returns the resolved file path and the marker payload that was
214
- * written. Throws if the workspaceDir or sessionId is missing/empty
215
- * (the caller should not invoke this without those — the harness
216
- * `compact()` must validate first).
217
- */
218
- async function writeOpenClawCompactionMarker(input, options = {}) {
219
- if (!input.workspaceDir || typeof input.workspaceDir !== "string") throw new Error("[copilot:compaction-bridge] workspaceDir is required to write a marker");
220
- if (!input.sessionId || typeof input.sessionId !== "string") throw new Error("[copilot:compaction-bridge] sessionId is required to write a marker");
221
- const now = options.now ?? Date.now;
222
- const fs = options.fs ?? {
223
- mkdir,
224
- writeFile
225
- };
226
- const subdir = options.subdir ?? "files";
227
- const ts = now();
228
- const filename = `openclaw-compaction-${ts}-${input.sessionId.replace(/[^a-zA-Z0-9._-]/g, "_")}.json`;
229
- const dirPath = join(input.workspaceDir, subdir);
230
- const filePath = join(dirPath, filename);
231
- const marker = compactJsonValue({
232
- version: 1,
233
- source: "copilot-harness",
234
- sessionId: input.sessionId,
235
- ts,
236
- compacted: false,
237
- trigger: input.trigger,
238
- force: input.force,
239
- sdkSessionId: input.sdkSessionId,
240
- currentTokenCount: input.currentTokenCount,
241
- reason: input.reason
242
- });
243
- await fs.mkdir(dirPath, { recursive: true });
244
- await fs.writeFile(filePath, `${JSON.stringify(marker, null, 2)}\n`, "utf8");
245
- return {
246
- path: filePath,
247
- marker
248
- };
249
- }
250
- //#endregion
251
187
  //#region extensions/copilot/harness.ts
252
188
  const COPILOT_PROVIDER_IDS = new Set(["github-copilot"]);
189
+ function sessionAuthFields(auth) {
190
+ return auth.authMode === "gitHubToken" ? {
191
+ authMode: "gitHubToken",
192
+ authProfileId: auth.authProfileId,
193
+ authProfileVersion: auth.authProfileVersion
194
+ } : { authMode: "useLoggedInUser" };
195
+ }
196
+ function sessionAuthMatches(stored, current) {
197
+ if (stored.authMode !== current.authMode) return false;
198
+ if (stored.authMode === "useLoggedInUser") return true;
199
+ return current.authMode === "gitHubToken" && stored.authProfileId === current.authProfileId && stored.authProfileVersion === current.authProfileVersion;
200
+ }
253
201
  function normalizeBinding(value) {
254
- if (!value || value.schemaVersion !== 1 || typeof value.sdkSessionId !== "string" || value.sdkSessionId.trim() === "" || typeof value.compatKey !== "string" || value.compatKey.trim() === "" || typeof value.updatedAt !== "number" || !Number.isFinite(value.updatedAt)) return;
202
+ if (!value || value.schemaVersion !== 2 || typeof value.sdkSessionId !== "string" || value.sdkSessionId.trim() === "" || typeof value.compatKey !== "string" || value.compatKey.trim() === "" || typeof value.compactKey !== "string" || value.compactKey.trim() === "" || value.authMode !== "gitHubToken" && value.authMode !== "useLoggedInUser" || value.authMode === "gitHubToken" && (typeof value.authProfileId !== "string" || value.authProfileId.trim() === "" || typeof value.authProfileVersion !== "string" || value.authProfileVersion.trim() === "") || typeof value.updatedAt !== "number" || !Number.isFinite(value.updatedAt)) return;
255
203
  return {
256
- schemaVersion: 1,
204
+ schemaVersion: 2,
257
205
  sdkSessionId: value.sdkSessionId.trim(),
258
206
  compatKey: value.compatKey,
207
+ compactKey: value.compactKey,
208
+ authMode: value.authMode,
209
+ ...value.authMode === "gitHubToken" ? {
210
+ authProfileId: value.authProfileId,
211
+ authProfileVersion: value.authProfileVersion
212
+ } : {},
259
213
  updatedAt: value.updatedAt
260
214
  };
261
215
  }
216
+ function normalizeAttemptBinding(value) {
217
+ const current = normalizeBinding(value);
218
+ if (current) return current;
219
+ const legacy = value;
220
+ if (!legacy || legacy.schemaVersion !== 1 || typeof legacy.sdkSessionId !== "string" || legacy.sdkSessionId.trim() === "" || typeof legacy.compatKey !== "string" || legacy.compatKey.trim() === "" || typeof legacy.updatedAt !== "number" || !Number.isFinite(legacy.updatedAt)) return;
221
+ return {
222
+ sdkSessionId: legacy.sdkSessionId.trim(),
223
+ compatKey: legacy.compatKey
224
+ };
225
+ }
262
226
  function lookupStoredBinding(store, key) {
263
227
  try {
264
- return normalizeBinding(store?.lookup(key));
228
+ return normalizeAttemptBinding(store?.lookup(key));
265
229
  } catch {
266
230
  try {
267
231
  store?.delete(key);
@@ -288,15 +252,53 @@ function deleteStoredBinding(store, key) {
288
252
  return false;
289
253
  }
290
254
  }
291
- function computeSessionCompatKey(params) {
255
+ function throwIfAborted(signal) {
256
+ if (!signal?.aborted) return;
257
+ const reason = "reason" in signal ? signal.reason : void 0;
258
+ if (reason instanceof Error) throw reason;
259
+ const error = reason ? new Error("aborted", { cause: reason }) : /* @__PURE__ */ new Error("aborted");
260
+ error.name = "AbortError";
261
+ throw error;
262
+ }
263
+ function isStaleSdkSessionError(error) {
264
+ const message = error instanceof Error ? error.message : String(error);
265
+ return /\b(404|not found|no such session|unknown session|stale|deleted|does not exist)\b/i.test(message);
266
+ }
267
+ async function compactTrackedSdkSession(params) {
268
+ throwIfAborted(params.abortSignal);
269
+ const session = await params.client.resumeSession(params.sdkSessionId, {
270
+ ...params.sessionConfig,
271
+ continuePendingWork: false,
272
+ ...params.gitHubToken ? { gitHubToken: params.gitHubToken } : {},
273
+ suppressResumeEvent: true
274
+ });
275
+ params.onSession?.(session);
276
+ const request = params.customInstructions?.trim() ? { customInstructions: params.customInstructions } : void 0;
277
+ try {
278
+ throwIfAborted(params.abortSignal);
279
+ return await session.rpc.history.compact(request);
280
+ } finally {
281
+ try {
282
+ await session.disconnect();
283
+ } catch {}
284
+ }
285
+ }
286
+ function readAgentIdFromSessionKey(sessionKey) {
287
+ if (typeof sessionKey !== "string") return;
288
+ const parts = sessionKey.trim().split(":");
289
+ return parts[0] === "agent" && parts[1]?.trim() ? parts[1].trim() : void 0;
290
+ }
291
+ function computeSessionKey(params, options) {
292
292
  const p = params;
293
293
  const modelObj = p.model && typeof p.model === "object" ? p.model : { id: typeof p.model === "string" ? p.model : void 0 };
294
+ const provider = modelObj.provider ?? (typeof p.provider === "string" ? p.provider : "");
295
+ const modelId = modelObj.id ?? (typeof p.modelId === "string" ? p.modelId : void 0) ?? (typeof p.model === "string" ? p.model : "");
294
296
  let authParts;
295
297
  let resolvedAgentId = "";
296
298
  let resolvedCopilotHome = "";
297
299
  try {
298
300
  const resolved = resolveCopilotAuth({
299
- agentId: typeof p.agentId === "string" ? p.agentId : void 0,
301
+ agentId: typeof p.agentId === "string" ? p.agentId : readAgentIdFromSessionKey(p.sessionKey),
300
302
  agentDir: typeof p.agentDir === "string" ? p.agentDir : void 0,
301
303
  workspaceDir: typeof p.workspaceDir === "string" ? p.workspaceDir : void 0,
302
304
  copilotHome: typeof p.copilotHome === "string" ? p.copilotHome : void 0,
@@ -316,17 +318,29 @@ function computeSessionCompatKey(params) {
316
318
  authParts = ["auth=unresolvable"];
317
319
  }
318
320
  return [
319
- `provider=${modelObj.provider ?? ""}`,
320
- `model=${modelObj.id ?? ""}`,
321
- `api=${modelObj.api ?? ""}`,
321
+ `provider=${provider}`,
322
+ `model=${modelId}`,
323
+ ...options.includeApi ? [`api=${modelObj.api ?? ""}`] : [],
322
324
  `cwd=${p.cwd ?? p.workspaceDir ?? ""}`,
323
325
  `agentId=${resolvedAgentId}`,
324
326
  `agentDir=${p.agentDir ?? ""}`,
325
327
  `copilotHome=${p.copilotHome ?? ""}`,
326
328
  `resolvedCopilotHome=${resolvedCopilotHome}`,
327
- ...authParts
329
+ ...options.includeAuth ? authParts : []
328
330
  ].join("|");
329
331
  }
332
+ function computeSessionCompatKey(params) {
333
+ return computeSessionKey(params, {
334
+ includeApi: true,
335
+ includeAuth: true
336
+ });
337
+ }
338
+ function computeSessionCompactKey(params) {
339
+ return computeSessionKey(params, {
340
+ includeApi: false,
341
+ includeAuth: false
342
+ });
343
+ }
330
344
  function createCopilotAgentHarness(options) {
331
345
  let poolPromise;
332
346
  let createdPool;
@@ -338,7 +352,7 @@ function createCopilotAgentHarness(options) {
338
352
  async function getPool() {
339
353
  if (options?.pool) return options.pool;
340
354
  if (!poolPromise) poolPromise = (async () => {
341
- const { createCopilotClientPool } = await import("./runtime-CO3w12zM.js");
355
+ const { createCopilotClientPool } = await import("./runtime-BUOrFPqD.js");
342
356
  createdPool = createCopilotClientPool(options?.poolOptions);
343
357
  return createdPool;
344
358
  })();
@@ -365,12 +379,14 @@ function createCopilotAgentHarness(options) {
365
379
  async runAttempt(params) {
366
380
  const attemptPromise = (async () => {
367
381
  if (disposed) throw new Error("[copilot] harness has been disposed; cannot start new attempts");
368
- const { runCopilotAttempt } = await import("./attempt-BzAGGBBx.js");
382
+ const { resolvePoolAcquire, runCopilotAttempt } = await import("./attempt-BXsiHr57.js");
369
383
  if (disposed) throw new Error("[copilot] harness was disposed while starting an attempt");
384
+ const poolAcquire = resolvePoolAcquire(params);
370
385
  const pool = await getPool();
371
386
  if (disposed) throw new Error("[copilot] harness was disposed while starting an attempt");
372
387
  const openclawSessionId = typeof params.sessionId === "string" ? params.sessionId : void 0;
373
388
  const currentCompatKey = computeSessionCompatKey(params);
389
+ const currentCompactKey = computeSessionCompactKey(params);
374
390
  const tracked = openclawSessionId ? trackedSessions.get(openclawSessionId) : void 0;
375
391
  const stored = openclawSessionId ? resetBlockedStoredSessions.has(openclawSessionId) ? void 0 : lookupStoredBinding(options?.sessionStore, openclawSessionId) : void 0;
376
392
  const resumableSessionId = tracked && tracked.compatKey === currentCompatKey ? tracked.sdkSessionId : !tracked && stored && stored.compatKey === currentCompatKey ? stored.sdkSessionId : void 0;
@@ -382,16 +398,23 @@ function createCopilotAgentHarness(options) {
382
398
  }
383
399
  } : params, {
384
400
  pool,
385
- onSessionEstablished: openclawSessionId ? ({ sdkSessionId, pooledClient }) => {
401
+ onSessionEstablished: openclawSessionId ? ({ sdkSessionId, pooledClient, sessionConfig }) => {
386
402
  trackedSessions.set(openclawSessionId, {
387
403
  sdkSessionId,
388
404
  client: pooledClient.client,
389
- compatKey: currentCompatKey
405
+ clientOptions: poolAcquire.options,
406
+ compatKey: currentCompatKey,
407
+ compactKey: currentCompactKey,
408
+ poolKey: pooledClient.key,
409
+ sessionConfig,
410
+ ...sessionAuthFields(poolAcquire.auth)
390
411
  });
391
412
  if (registerStoredBinding(options?.sessionStore, openclawSessionId, {
392
- schemaVersion: 1,
413
+ schemaVersion: 2,
393
414
  sdkSessionId,
394
415
  compatKey: currentCompatKey,
416
+ compactKey: currentCompactKey,
417
+ ...sessionAuthFields(poolAcquire.auth),
395
418
  updatedAt: Date.now()
396
419
  })) resetBlockedStoredSessions.delete(openclawSessionId);
397
420
  } : void 0
@@ -418,39 +441,90 @@ function createCopilotAgentHarness(options) {
418
441
  },
419
442
  async compact(params) {
420
443
  const openclawSessionId = typeof params.sessionId === "string" ? params.sessionId : void 0;
421
- const workspaceDir = typeof params.workspaceDir === "string" ? params.workspaceDir : void 0;
422
- if (!openclawSessionId || !workspaceDir) return {
444
+ if (!openclawSessionId) return {
423
445
  ok: false,
424
446
  compacted: false,
425
447
  reason: "missing-required-params"
426
448
  };
427
449
  const tracked = trackedSessions.get(openclawSessionId);
428
- const reason = params.force ? "force-requested-but-sdk-has-no-synchronous-compact-api" : "deferred-to-sdk-infinite-sessions";
450
+ const currentCompactKey = computeSessionCompactKey(params);
451
+ const { resolvePoolAcquire } = await import("./attempt-BXsiHr57.js");
452
+ const resolvedPoolAcquire = resolvePoolAcquire(params);
453
+ const currentAuth = sessionAuthFields(resolvedPoolAcquire.auth);
454
+ const compatibleTracked = tracked?.compactKey === currentCompactKey && sessionAuthMatches(tracked, currentAuth) ? tracked : void 0;
455
+ if (!compatibleTracked) return {
456
+ ok: false,
457
+ compacted: false,
458
+ reason: "missing_thread_binding",
459
+ failure: { reason: "missing_thread_binding" }
460
+ };
461
+ const poolAcquire = compatibleTracked ? {
462
+ key: compatibleTracked.poolKey,
463
+ options: compatibleTracked.clientOptions
464
+ } : resolvedPoolAcquire;
465
+ let compactResult;
466
+ let handle;
467
+ let pool;
468
+ let activeSdkSession;
429
469
  try {
430
- await writeOpenClawCompactionMarker({
431
- sessionId: openclawSessionId,
432
- workspaceDir,
433
- trigger: params.trigger,
434
- currentTokenCount: params.currentTokenCount,
435
- sdkSessionId: tracked?.sdkSessionId,
436
- force: params.force,
437
- reason
470
+ throwIfAborted(params.abortSignal);
471
+ pool = await getPool();
472
+ handle = await pool.acquire(poolAcquire.key, poolAcquire.options);
473
+ const client = handle.client;
474
+ compactResult = await compactWithSafetyTimeout((abortSignal) => compactTrackedSdkSession({
475
+ abortSignal,
476
+ client,
477
+ customInstructions: params.customInstructions,
478
+ gitHubToken: compatibleTracked?.clientOptions.gitHubToken ?? (resolvedPoolAcquire.auth.authMode === "gitHubToken" ? resolvedPoolAcquire.auth.gitHubToken : void 0),
479
+ onSession: (session) => {
480
+ activeSdkSession = session;
481
+ },
482
+ sessionConfig: compatibleTracked.sessionConfig,
483
+ sdkSessionId: compatibleTracked.sdkSessionId
484
+ }), resolveCompactionTimeoutMs(params.config), {
485
+ abortSignal: params.abortSignal,
486
+ onCancel: () => void activeSdkSession?.rpc.history.abortManualCompaction().catch(() => void 0)
438
487
  });
439
488
  } catch (err) {
489
+ const rawError = err instanceof Error ? err.message : String(err);
490
+ if (isStaleSdkSessionError(err)) {
491
+ trackedSessions.delete(openclawSessionId);
492
+ deleteStoredBinding(options?.sessionStore, openclawSessionId);
493
+ return {
494
+ ok: false,
495
+ compacted: false,
496
+ reason: "stale_thread_binding",
497
+ failure: {
498
+ reason: "stale_thread_binding",
499
+ rawError
500
+ }
501
+ };
502
+ }
440
503
  return {
441
504
  ok: false,
442
505
  compacted: false,
443
- reason: "marker-write-failed",
506
+ reason: "copilot-sdk-history-compact-failed",
444
507
  failure: {
445
- reason: "marker-write-failed",
446
- rawError: err instanceof Error ? err.message : String(err)
508
+ reason: "copilot-sdk-history-compact-failed",
509
+ rawError
447
510
  }
448
511
  };
512
+ } finally {
513
+ if (pool && handle) try {
514
+ await pool.release(handle);
515
+ } catch {}
449
516
  }
517
+ if (!compactResult.success) return {
518
+ ok: false,
519
+ compacted: false,
520
+ reason: "copilot-sdk-history-compact-failed",
521
+ failure: { reason: "copilot-sdk-history-compact-failed" }
522
+ };
523
+ const compacted = compactResult.tokensRemoved > 0 || compactResult.messagesRemoved > 0;
450
524
  return {
451
525
  ok: true,
452
- compacted: false,
453
- reason
526
+ compacted,
527
+ reason: compacted ? "copilot-sdk-history-compacted" : "already under target"
454
528
  };
455
529
  },
456
530
  async dispose() {
@@ -470,4 +544,4 @@ function createCopilotAgentHarness(options) {
470
544
  };
471
545
  }
472
546
  //#endregion
473
- export { createInfiniteSessionConfig as n, resolveCopilotAuth as r, createCopilotAgentHarness as t };
547
+ export { resolveCopilotAuth as n, createCopilotAgentHarness as t };
package/dist/harness.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createCopilotAgentHarness } from "./harness-CsSU8FFW.js";
1
+ import { t as createCopilotAgentHarness } from "./harness-CGzfTXDg.js";
2
2
  export { createCopilotAgentHarness };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as createCopilotAgentHarness } from "./harness-CsSU8FFW.js";
1
+ import { t as createCopilotAgentHarness } from "./harness-CGzfTXDg.js";
2
2
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
3
3
  //#region extensions/copilot/index.ts
4
4
  function isRecord(value) {
@@ -8,7 +8,7 @@ function resolveCopilotSdkFallbackDir(env = process.env) {
8
8
  return path.join(resolveStateDir(env), "npm-runtime", "copilot");
9
9
  }
10
10
  resolveCopilotSdkFallbackDir();
11
- const COPILOT_SDK_SPEC = "@github/copilot-sdk@1.0.0-beta.4";
11
+ const COPILOT_SDK_SPEC = "@github/copilot-sdk@1.0.0-beta.9";
12
12
  let cached;
13
13
  async function loadCopilotSdk(options = {}) {
14
14
  const useCache = options.cache !== false;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/copilot",
3
- "version": "2026.5.31-beta.3",
3
+ "version": "2026.5.31-beta.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/copilot",
9
- "version": "2026.5.31-beta.3",
9
+ "version": "2026.5.31-beta.4",
10
10
  "dependencies": {
11
11
  "@github/copilot-sdk": "1.0.0-beta.9"
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/copilot",
3
- "version": "2026.5.31-beta.3",
3
+ "version": "2026.5.31-beta.4",
4
4
  "description": "OpenClaw GitHub Copilot agent runtime plugin (registers a `github-copilot` AgentHarness backed by @github/copilot-sdk over JSON-RPC to the GitHub Copilot CLI)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,10 +25,10 @@
25
25
  "minHostVersion": ">=2026.5.28"
26
26
  },
27
27
  "compat": {
28
- "pluginApi": ">=2026.5.31-beta.3"
28
+ "pluginApi": ">=2026.5.31-beta.4"
29
29
  },
30
30
  "build": {
31
- "openclawVersion": "2026.5.31-beta.3",
31
+ "openclawVersion": "2026.5.31-beta.4",
32
32
  "bundledDist": false
33
33
  },
34
34
  "release": {
@@ -47,7 +47,7 @@
47
47
  "README.md"
48
48
  ],
49
49
  "peerDependencies": {
50
- "openclaw": ">=2026.5.31-beta.3"
50
+ "openclaw": ">=2026.5.31-beta.4"
51
51
  },
52
52
  "peerDependenciesMeta": {
53
53
  "openclaw": {