@openclaw/copilot 2026.7.1 → 2026.7.2-beta.2
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/README.md +1 -3
- package/dist/{attempt-D6MSc00N.js → attempt-Bwgye68K.js} +132 -116
- package/dist/doctor-contract-api.js +1 -2
- package/dist/{harness-BQhGzc1Z.js → harness-DeWR8_cC.js} +3 -3
- package/dist/harness.js +1 -1
- package/dist/index.js +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -14,13 +14,11 @@ The harness claims the canonical subscription `github-copilot` provider plus
|
|
|
14
14
|
custom BYOK provider entries that the Copilot SDK can represent. Manifest-owned
|
|
15
15
|
native provider ids stay with their owning runtimes. The harness is opt-in only:
|
|
16
16
|
selection requires explicit `agentRuntime.id: "copilot"` on a model or provider
|
|
17
|
-
entry; `auto` never picks it.
|
|
17
|
+
entry; `auto` never picks it. OpenClaw remains the default embedded runtime.
|
|
18
18
|
|
|
19
19
|
See [GitHub Copilot agent runtime](../../docs/plugins/copilot.md) for
|
|
20
20
|
configuration, the doctor contract, transcript mirroring, compaction, side
|
|
21
21
|
questions, replay, and the supported-surface contract.
|
|
22
|
-
See [qa/copilot-capabilities.md](../../qa/copilot-capabilities.md)
|
|
23
|
-
for the SDK capability inventory the harness is pinned to.
|
|
24
22
|
|
|
25
23
|
## Package
|
|
26
24
|
|
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
import { a as resolveCopilotAuth, i as createCopilotByokAuth, n as resolveCopilotProvider, r as createCopilotByokProxy } from "./harness-
|
|
2
|
-
import { applyEmbeddedAttemptToolsAllow, awaitAgentEndSideEffects, buildAgentHarnessUserInputAnswers, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, clearActiveEmbeddedRun, deliverAgentHarnessUserInputPrompt, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, extractToolErrorMessage, getModelProviderRequestTransport, getPluginToolMeta, isSubagentSessionKey, isToolResultError, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptFsWorkspaceOnly, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveCompactionTimeoutMs, resolveEmbeddedAttemptToolConstructionPlan, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveUserPath, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, sanitizeToolResult, setActiveEmbeddedRun } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
1
|
+
import { a as resolveCopilotAuth, i as createCopilotByokAuth, n as resolveCopilotProvider, r as createCopilotByokProxy } from "./harness-DeWR8_cC.js";
|
|
2
|
+
import { applyEmbeddedAttemptToolsAllow, awaitAgentEndSideEffects, buildAgentHarnessUserInputAnswers, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, clearActiveEmbeddedRun, deliverAgentHarnessUserInputPrompt, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, extractToolErrorMessage, getModelProviderRequestTransport, getPluginToolMeta, isHostScopedAgentToolActive, isSubagentSessionKey, isToolResultError, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptFsWorkspaceOnly, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveCompactionTimeoutMs, resolveEmbeddedAttemptToolConstructionPlan, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveUserPath, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, sanitizeToolResult, setActiveEmbeddedRun } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import fsp from "node:fs/promises";
|
|
6
|
-
import {
|
|
6
|
+
import { withSessionTranscriptWriteLock } from "openclaw/plugin-sdk/session-transcript-runtime";
|
|
7
7
|
import { createAgentHarnessTaskRuntime } from "openclaw/plugin-sdk/agent-harness-task-runtime";
|
|
8
|
+
import { convertMcpCallToolResult } from "@github/copilot-sdk";
|
|
8
9
|
import { createAgentHarnessToolSurfaceRuntime } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
|
|
9
|
-
//#region extensions/copilot/src/compaction-bridge.ts
|
|
10
|
-
/**
|
|
11
|
-
* Shape an `InfiniteSessionConfig` for `SessionConfig.infiniteSessions`.
|
|
12
|
-
* Returns `undefined` when no fields were supplied so callers can
|
|
13
|
-
* spread conditionally and let the SDK apply its own defaults
|
|
14
|
-
* (`enabled: true`, background 0.80, buffer 0.95). Any explicitly-set
|
|
15
|
-
* value (including `enabled: false` to disable infinite sessions) is
|
|
16
|
-
* preserved.
|
|
17
|
-
*/
|
|
18
|
-
function createInfiniteSessionConfig(options) {
|
|
19
|
-
if (!options) return;
|
|
20
|
-
const result = {};
|
|
21
|
-
if (options.enabled !== void 0) result.enabled = options.enabled;
|
|
22
|
-
if (options.backgroundCompactionThreshold !== void 0) result.backgroundCompactionThreshold = options.backgroundCompactionThreshold;
|
|
23
|
-
if (options.bufferExhaustionThreshold !== void 0) result.bufferExhaustionThreshold = options.bufferExhaustionThreshold;
|
|
24
|
-
return Object.keys(result).length > 0 ? result : void 0;
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
27
10
|
//#region extensions/copilot/src/dual-write-transcripts.ts
|
|
28
11
|
/**
|
|
29
12
|
* Mirrors the AgentMessages produced by the copilot agent runtime into the
|
|
@@ -98,9 +81,8 @@ function buildMirrorDedupeIdentity(message) {
|
|
|
98
81
|
async function mirrorCopilotTranscript(params) {
|
|
99
82
|
const messages = params.messages.filter((message) => message.role === "user" || message.role === "assistant" || message.role === "toolResult");
|
|
100
83
|
if (messages.length === 0) return;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
...transcriptTarget,
|
|
84
|
+
await withCopilotMirrorTranscriptWriteLock({
|
|
85
|
+
...resolveCopilotMirrorTranscriptTarget(params),
|
|
104
86
|
config: params.config
|
|
105
87
|
}, async (transcript) => {
|
|
106
88
|
let didAppendMessage = false;
|
|
@@ -130,22 +112,24 @@ async function mirrorCopilotTranscript(params) {
|
|
|
130
112
|
didAppendMessage = true;
|
|
131
113
|
if (idempotencyKey) existingIdempotencyKeys.add(idempotencyKey);
|
|
132
114
|
}
|
|
115
|
+
if (didAppendMessage) await transcript.publishUpdate(params.sessionKey ? { sessionKey: params.sessionKey } : void 0);
|
|
133
116
|
return didAppendMessage;
|
|
134
|
-
})) await publishSessionTranscriptUpdateByIdentity({
|
|
135
|
-
...transcriptTarget,
|
|
136
|
-
update: params.sessionKey ? { sessionKey: params.sessionKey } : void 0
|
|
137
117
|
});
|
|
138
118
|
}
|
|
139
119
|
function resolveCopilotMirrorTranscriptTarget(params) {
|
|
140
|
-
const
|
|
141
|
-
|
|
120
|
+
const sessionKey = params.sessionKey?.trim();
|
|
121
|
+
const storePath = params.storePath?.trim();
|
|
122
|
+
if (!sessionKey || !storePath) throw new Error("Copilot transcript mirror requires a runtime session identity");
|
|
142
123
|
return {
|
|
143
124
|
...params.agentId ? { agentId: params.agentId } : {},
|
|
144
|
-
sessionFile,
|
|
145
125
|
sessionId: params.sessionId,
|
|
146
|
-
sessionKey
|
|
126
|
+
sessionKey,
|
|
127
|
+
storePath
|
|
147
128
|
};
|
|
148
129
|
}
|
|
130
|
+
function withCopilotMirrorTranscriptWriteLock(params, run) {
|
|
131
|
+
return withSessionTranscriptWriteLock(params, run);
|
|
132
|
+
}
|
|
149
133
|
function readTranscriptIdempotencyKeys(events) {
|
|
150
134
|
const keys = /* @__PURE__ */ new Set();
|
|
151
135
|
for (const event of events) {
|
|
@@ -223,7 +207,7 @@ function attachEventBridge(session, options) {
|
|
|
223
207
|
let usage;
|
|
224
208
|
let streamError;
|
|
225
209
|
const toolMetas = [];
|
|
226
|
-
const
|
|
210
|
+
const toolMetaIndexByCallId = /* @__PURE__ */ new Map();
|
|
227
211
|
let startedCount = 0;
|
|
228
212
|
let completedCount = 0;
|
|
229
213
|
let activeCompactionCount = 0;
|
|
@@ -244,7 +228,7 @@ function attachEventBridge(session, options) {
|
|
|
244
228
|
const unsubscribeFns = [];
|
|
245
229
|
registerListener(session, unsubscribeFns, "assistant.message_delta", (event) => {
|
|
246
230
|
if (!isRootSessionEvent(event)) return;
|
|
247
|
-
const messageId = readString$
|
|
231
|
+
const messageId = readString$1(event.data.messageId) ?? "assistant-message";
|
|
248
232
|
const delta = event.data.deltaContent;
|
|
249
233
|
if (!delta) return;
|
|
250
234
|
const entry = ensureMessageAccumulator(messagesById, messageOrder, messageId);
|
|
@@ -267,7 +251,7 @@ function attachEventBridge(session, options) {
|
|
|
267
251
|
});
|
|
268
252
|
registerListener(session, unsubscribeFns, "assistant.reasoning_delta", (event) => {
|
|
269
253
|
if (!isRootSessionEvent(event)) return;
|
|
270
|
-
const reasoningId = readString$
|
|
254
|
+
const reasoningId = readString$1(event.data.reasoningId) ?? "assistant-reasoning";
|
|
271
255
|
const delta = event.data.deltaContent;
|
|
272
256
|
if (!delta) return;
|
|
273
257
|
if (!reasoningById.has(reasoningId)) {
|
|
@@ -288,17 +272,19 @@ function attachEventBridge(session, options) {
|
|
|
288
272
|
});
|
|
289
273
|
registerListener(session, unsubscribeFns, "tool.execution_start", (event) => {
|
|
290
274
|
if (isRootSessionEvent(event)) startedCount += 1;
|
|
291
|
-
|
|
275
|
+
toolMetaIndexByCallId.set(event.data.toolCallId, toolMetas.length);
|
|
292
276
|
toolMetas.push({ toolName: event.data.toolName });
|
|
293
277
|
});
|
|
294
278
|
registerListener(session, unsubscribeFns, "tool.execution_complete", (event) => {
|
|
295
279
|
if (isRootSessionEvent(event)) completedCount += 1;
|
|
296
|
-
const
|
|
280
|
+
const toolMetaIndex = toolMetaIndexByCallId.get(event.data.toolCallId);
|
|
281
|
+
const toolName = toolMetaIndex === void 0 ? void 0 : toolMetas[toolMetaIndex]?.toolName;
|
|
297
282
|
const meta = event.data.success ? event.data.result?.detailedContent ?? event.data.result?.content : event.data.error?.message;
|
|
298
|
-
if (toolName) toolMetas
|
|
299
|
-
meta,
|
|
300
|
-
toolName
|
|
301
|
-
|
|
283
|
+
if (toolName && toolMetaIndex !== void 0) toolMetas[toolMetaIndex] = {
|
|
284
|
+
...meta ? { meta } : {},
|
|
285
|
+
toolName,
|
|
286
|
+
...event.data.success ? {} : { isError: true }
|
|
287
|
+
};
|
|
302
288
|
});
|
|
303
289
|
registerListener(session, unsubscribeFns, "session.plan_changed", (event) => {
|
|
304
290
|
enqueueAgentEvent({
|
|
@@ -313,7 +299,10 @@ function attachEventBridge(session, options) {
|
|
|
313
299
|
});
|
|
314
300
|
});
|
|
315
301
|
registerListener(session, unsubscribeFns, "exit_plan_mode.requested", (event) => {
|
|
316
|
-
const steps = splitPlanText(event.data.planContent)
|
|
302
|
+
const steps = splitPlanText(event.data.planContent).map((step) => ({
|
|
303
|
+
step,
|
|
304
|
+
status: "pending"
|
|
305
|
+
}));
|
|
317
306
|
enqueueAgentEvent({
|
|
318
307
|
stream: "plan",
|
|
319
308
|
data: {
|
|
@@ -364,6 +353,9 @@ function attachEventBridge(session, options) {
|
|
|
364
353
|
enqueueCompactionCallback(options.onCompactionStart);
|
|
365
354
|
});
|
|
366
355
|
registerListener(session, unsubscribeFns, "session.compaction_complete", (event) => {
|
|
356
|
+
if (event.data.success) try {
|
|
357
|
+
options.onContextCompacted?.();
|
|
358
|
+
} catch {}
|
|
367
359
|
if (!isRootCompactionEvent(event)) return;
|
|
368
360
|
activeCompactionCount = Math.max(0, activeCompactionCount - 1);
|
|
369
361
|
enqueueCompactionCallback(() => options.onCompactionComplete?.({
|
|
@@ -553,7 +545,7 @@ function joinReasoning(order, reasoningById) {
|
|
|
553
545
|
function splitPlanText(text) {
|
|
554
546
|
return (text ?? "").split(/\r?\n/).map((line) => line.trim().replace(/^[-*]\s+/, "")).filter((line) => line.length > 0);
|
|
555
547
|
}
|
|
556
|
-
function readString$
|
|
548
|
+
function readString$1(value) {
|
|
557
549
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
558
550
|
}
|
|
559
551
|
function registerListener(session, unsubscribeFns, eventType, handler) {
|
|
@@ -1057,7 +1049,8 @@ async function createCopilotToolBridge(input) {
|
|
|
1057
1049
|
abortSignal: input.abortSignal,
|
|
1058
1050
|
beforeExecute: input.beforeExecute,
|
|
1059
1051
|
onAgentToolResult: input.attemptParams?.onAgentToolResult,
|
|
1060
|
-
onToolCompleted: input.onToolCompleted
|
|
1052
|
+
onToolCompleted: input.onToolCompleted,
|
|
1053
|
+
observeToolTerminal: input.attemptParams?.observeToolTerminal
|
|
1061
1054
|
})),
|
|
1062
1055
|
sourceTools: filteredTools
|
|
1063
1056
|
};
|
|
@@ -1113,9 +1106,12 @@ function buildOpenClawCodingToolsOptions(input, toolPlan, toolSurfaceRuntime) {
|
|
|
1113
1106
|
elevated: a.bashElevated
|
|
1114
1107
|
},
|
|
1115
1108
|
messageProvider: a.messageProvider ?? a.messageChannel,
|
|
1109
|
+
chatType: a.chatType,
|
|
1116
1110
|
agentAccountId: a.agentAccountId,
|
|
1117
1111
|
messageTo: a.messageTo,
|
|
1118
1112
|
messageThreadId: a.messageThreadId,
|
|
1113
|
+
nativeChannelId: a.chatId,
|
|
1114
|
+
messageActionTurnCapability: a.messageActionTurnCapability,
|
|
1119
1115
|
groupId: a.groupId,
|
|
1120
1116
|
groupChannel: a.groupChannel,
|
|
1121
1117
|
groupSpace: a.groupSpace,
|
|
@@ -1164,6 +1160,7 @@ function buildOpenClawCodingToolsOptions(input, toolPlan, toolSurfaceRuntime) {
|
|
|
1164
1160
|
enableHeartbeatTool: a.enableHeartbeatTool,
|
|
1165
1161
|
forceHeartbeatTool: a.forceHeartbeatTool,
|
|
1166
1162
|
authProfileStore: a.toolAuthProfileStore ?? a.authProfileStore,
|
|
1163
|
+
computerContextEpoch: input.computerContextEpoch,
|
|
1167
1164
|
onToolOutcome: a.onToolOutcome,
|
|
1168
1165
|
onYield: (message) => {
|
|
1169
1166
|
try {
|
|
@@ -1199,8 +1196,16 @@ function convertOpenClawToolToSdkTool(sourceTool, ctx) {
|
|
|
1199
1196
|
console.warn("[copilot-tool-bridge] onToolCompleted handler threw; continuing", error);
|
|
1200
1197
|
}
|
|
1201
1198
|
};
|
|
1202
|
-
const failureResult = (executedArgs, invocation, startedAt, message, error) => {
|
|
1199
|
+
const failureResult = (executedArgs, invocation, startedAt, message, error, executionStarted) => {
|
|
1203
1200
|
const errorMessage = toError$1(error).message;
|
|
1201
|
+
ctx.observeToolTerminal?.({
|
|
1202
|
+
toolCallId: invocation.toolCallId,
|
|
1203
|
+
toolName: sourceTool.name,
|
|
1204
|
+
arguments: executedArgs,
|
|
1205
|
+
executionStarted,
|
|
1206
|
+
outcome: "failure",
|
|
1207
|
+
failure: { error: errorMessage }
|
|
1208
|
+
});
|
|
1204
1209
|
notifyToolResult(sanitizeToolResult({
|
|
1205
1210
|
content: [{
|
|
1206
1211
|
type: "text",
|
|
@@ -1224,7 +1229,7 @@ function convertOpenClawToolToSdkTool(sourceTool, ctx) {
|
|
|
1224
1229
|
const startedAt = Date.now();
|
|
1225
1230
|
if (ctx.abortSignal?.aborted) {
|
|
1226
1231
|
const error = /* @__PURE__ */ new Error("[copilot-tool-bridge] aborted before execution");
|
|
1227
|
-
return failureResult(args, invocation, startedAt, error.message, error);
|
|
1232
|
+
return failureResult(args, invocation, startedAt, error.message, error, false);
|
|
1228
1233
|
}
|
|
1229
1234
|
try {
|
|
1230
1235
|
await ctx.beforeExecute?.({
|
|
@@ -1235,24 +1240,32 @@ function convertOpenClawToolToSdkTool(sourceTool, ctx) {
|
|
|
1235
1240
|
toolName: sourceTool.name
|
|
1236
1241
|
});
|
|
1237
1242
|
} catch (error) {
|
|
1238
|
-
return failureResult(args, invocation, startedAt, `[copilot-tool-bridge] beforeExecute failed for tool '${sourceTool.name}': ${toError$1(error).message}`, error);
|
|
1243
|
+
return failureResult(args, invocation, startedAt, `[copilot-tool-bridge] beforeExecute failed for tool '${sourceTool.name}': ${toError$1(error).message}`, error, false);
|
|
1239
1244
|
}
|
|
1240
1245
|
let preparedArgs;
|
|
1241
1246
|
try {
|
|
1242
1247
|
preparedArgs = sourceTool.prepareArguments ? sourceTool.prepareArguments(args) : args;
|
|
1243
1248
|
} catch (error) {
|
|
1244
|
-
return failureResult(args, invocation, startedAt, `[copilot-tool-bridge] prepareArguments failed for tool '${sourceTool.name}': ${toError$1(error).message}`, error);
|
|
1249
|
+
return failureResult(args, invocation, startedAt, `[copilot-tool-bridge] prepareArguments failed for tool '${sourceTool.name}': ${toError$1(error).message}`, error, false);
|
|
1245
1250
|
}
|
|
1246
1251
|
let result;
|
|
1247
1252
|
try {
|
|
1248
1253
|
result = await sourceTool.execute(invocation.toolCallId, preparedArgs, ctx.abortSignal, void 0);
|
|
1249
1254
|
} catch (error) {
|
|
1250
|
-
return failureResult(preparedArgs, invocation, startedAt, `[copilot-tool-bridge] tool '${sourceTool.name}' failed: ${toError$1(error).message}`, error);
|
|
1255
|
+
return failureResult(preparedArgs, invocation, startedAt, `[copilot-tool-bridge] tool '${sourceTool.name}' failed: ${toError$1(error).message}`, error, true);
|
|
1251
1256
|
}
|
|
1252
|
-
const sdkResult =
|
|
1257
|
+
const sdkResult = convertMcpCallToolResult({ content: result.content });
|
|
1253
1258
|
const sanitizedResult = sanitizeToolResult(result);
|
|
1254
1259
|
const resultIsError = sdkResult.resultType === "failure" || isToolResultError(sanitizedResult);
|
|
1255
1260
|
const resultError = resultIsError ? extractToolErrorMessage(sanitizedResult) : void 0;
|
|
1261
|
+
ctx.observeToolTerminal?.({
|
|
1262
|
+
toolCallId: invocation.toolCallId,
|
|
1263
|
+
toolName: sourceTool.name,
|
|
1264
|
+
arguments: preparedArgs,
|
|
1265
|
+
executionStarted: true,
|
|
1266
|
+
outcome: resultIsError ? "failure" : "success",
|
|
1267
|
+
...resultIsError ? { failure: { error: resultError ?? "tool returned an error" } } : {}
|
|
1268
|
+
});
|
|
1256
1269
|
notifyToolResult(sanitizedResult, resultIsError);
|
|
1257
1270
|
notifyToolCompleted({
|
|
1258
1271
|
toolName: sourceTool.name,
|
|
@@ -1282,11 +1295,24 @@ async function executeCatalogTool(input, params) {
|
|
|
1282
1295
|
const sourceTool = params.tool;
|
|
1283
1296
|
const startedAt = Date.now();
|
|
1284
1297
|
let preparedArgs = params.input;
|
|
1298
|
+
let executionStarted = false;
|
|
1299
|
+
let terminalObserved = false;
|
|
1285
1300
|
try {
|
|
1286
1301
|
preparedArgs = sourceTool.prepareArguments ? sourceTool.prepareArguments(params.input) : params.input;
|
|
1302
|
+
executionStarted = true;
|
|
1287
1303
|
const result = await sourceTool.execute(params.toolCallId, preparedArgs, params.signal ?? input.abortSignal, params.onUpdate);
|
|
1288
1304
|
const sanitizedResult = sanitizeToolResult(result);
|
|
1289
1305
|
const isError = isToolResultError(sanitizedResult);
|
|
1306
|
+
const error = isError ? extractToolErrorMessage(sanitizedResult) ?? "tool returned an error" : void 0;
|
|
1307
|
+
terminalObserved = true;
|
|
1308
|
+
input.attemptParams?.observeToolTerminal?.({
|
|
1309
|
+
toolCallId: params.toolCallId,
|
|
1310
|
+
toolName: params.toolName,
|
|
1311
|
+
arguments: preparedArgs,
|
|
1312
|
+
executionStarted,
|
|
1313
|
+
outcome: isError ? "failure" : "success",
|
|
1314
|
+
...error ? { failure: { error } } : {}
|
|
1315
|
+
});
|
|
1290
1316
|
input.attemptParams?.onAgentToolResult?.({
|
|
1291
1317
|
toolName: params.toolName,
|
|
1292
1318
|
result: sanitizedResult,
|
|
@@ -1297,12 +1323,20 @@ async function executeCatalogTool(input, params) {
|
|
|
1297
1323
|
toolCallId: params.toolCallId,
|
|
1298
1324
|
args: toToolStartArgs(preparedArgs),
|
|
1299
1325
|
result: sanitizedResult,
|
|
1300
|
-
...
|
|
1326
|
+
...error ? { error } : {},
|
|
1301
1327
|
startedAt
|
|
1302
1328
|
});
|
|
1303
1329
|
return result;
|
|
1304
1330
|
} catch (error) {
|
|
1305
1331
|
const message = toError$1(error).message;
|
|
1332
|
+
if (!terminalObserved) input.attemptParams?.observeToolTerminal?.({
|
|
1333
|
+
toolCallId: params.toolCallId,
|
|
1334
|
+
toolName: params.toolName,
|
|
1335
|
+
arguments: preparedArgs,
|
|
1336
|
+
executionStarted,
|
|
1337
|
+
outcome: "failure",
|
|
1338
|
+
failure: { error: message }
|
|
1339
|
+
});
|
|
1306
1340
|
const failure = sanitizeToolResult({
|
|
1307
1341
|
content: [{
|
|
1308
1342
|
type: "text",
|
|
@@ -1331,51 +1365,6 @@ async function executeCatalogTool(input, params) {
|
|
|
1331
1365
|
function toToolStartArgs(args) {
|
|
1332
1366
|
return args && typeof args === "object" && !Array.isArray(args) ? args : { value: args };
|
|
1333
1367
|
}
|
|
1334
|
-
function agentToolResultToSdk(result) {
|
|
1335
|
-
const content = result?.content;
|
|
1336
|
-
if (content == null) return createSuccessResult("");
|
|
1337
|
-
if (!Array.isArray(content)) return createUnsupportedContentFailure(typeof content);
|
|
1338
|
-
const textParts = [];
|
|
1339
|
-
const binaryResults = [];
|
|
1340
|
-
for (const block of content) {
|
|
1341
|
-
if (!block || typeof block !== "object") return createUnsupportedContentFailure(typeof block);
|
|
1342
|
-
const kind = readString$1(block.type);
|
|
1343
|
-
if (kind === "text") {
|
|
1344
|
-
const text = readString$1(block.text, { allowEmpty: true });
|
|
1345
|
-
if (text === void 0) return createUnsupportedContentFailure(kind);
|
|
1346
|
-
textParts.push(text);
|
|
1347
|
-
continue;
|
|
1348
|
-
}
|
|
1349
|
-
if (kind === "image") {
|
|
1350
|
-
const base64Data = readString$1(block.data);
|
|
1351
|
-
const mimeType = readString$1(block.mimeType);
|
|
1352
|
-
if (!base64Data || !mimeType) return createUnsupportedContentFailure(kind);
|
|
1353
|
-
binaryResults.push({
|
|
1354
|
-
base64Data,
|
|
1355
|
-
data: base64Data,
|
|
1356
|
-
mimeType,
|
|
1357
|
-
type: "image"
|
|
1358
|
-
});
|
|
1359
|
-
continue;
|
|
1360
|
-
}
|
|
1361
|
-
return createUnsupportedContentFailure(kind ?? typeof block);
|
|
1362
|
-
}
|
|
1363
|
-
return {
|
|
1364
|
-
...binaryResults.length > 0 ? { binaryResultsForLlm: binaryResults } : {},
|
|
1365
|
-
resultType: "success",
|
|
1366
|
-
textResultForLlm: textParts.join("\n")
|
|
1367
|
-
};
|
|
1368
|
-
}
|
|
1369
|
-
function createUnsupportedContentFailure(kind) {
|
|
1370
|
-
const message = `[copilot-tool-bridge] unsupported AgentToolResult content shape: ${kind}`;
|
|
1371
|
-
return createFailureResult(message, new Error(message));
|
|
1372
|
-
}
|
|
1373
|
-
function createSuccessResult(textResultForLlm) {
|
|
1374
|
-
return {
|
|
1375
|
-
resultType: "success",
|
|
1376
|
-
textResultForLlm
|
|
1377
|
-
};
|
|
1378
|
-
}
|
|
1379
1368
|
function createFailureResult(message, error) {
|
|
1380
1369
|
return {
|
|
1381
1370
|
error: toError$1(error).message,
|
|
@@ -1449,10 +1438,6 @@ function findDuplicateToolNames(sourceTools) {
|
|
|
1449
1438
|
}
|
|
1450
1439
|
return [...counts.entries()].filter(([, count]) => count > 1).map(([name]) => name).toSorted();
|
|
1451
1440
|
}
|
|
1452
|
-
function readString$1(value, options = {}) {
|
|
1453
|
-
if (typeof value !== "string") return;
|
|
1454
|
-
if (options.allowEmpty || value.length > 0) return value;
|
|
1455
|
-
}
|
|
1456
1441
|
function toError$1(error) {
|
|
1457
1442
|
return error instanceof Error ? error : new Error(String(error));
|
|
1458
1443
|
}
|
|
@@ -1622,9 +1607,9 @@ async function resolveCopilotWorkspaceBootstrapContext(params) {
|
|
|
1622
1607
|
* (`src/agents/pi-embedded-runner/run/attempt.ts:603`). Files whose
|
|
1623
1608
|
* resolved relative path escapes the source workspace (parent
|
|
1624
1609
|
* traversal or absolute) are left untouched so we never pretend a
|
|
1625
|
-
* file lives inside the sandbox when it does not.
|
|
1626
|
-
*
|
|
1627
|
-
*
|
|
1610
|
+
* file lives inside the sandbox when it does not. Intentionally local
|
|
1611
|
+
* to the Copilot extension (codex keeps similar helpers extension-local
|
|
1612
|
+
* rather than importing from PI).
|
|
1628
1613
|
*/
|
|
1629
1614
|
function remapCopilotBootstrapContextFiles(params) {
|
|
1630
1615
|
if (params.sourceWorkspaceDir === params.targetWorkspaceDir) return params.files;
|
|
@@ -1801,6 +1786,7 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1801
1786
|
const attemptStartedAt = now();
|
|
1802
1787
|
const input = params;
|
|
1803
1788
|
const createToolBridge = deps.createToolBridge ?? createCopilotToolBridge;
|
|
1789
|
+
const ringZeroSystemAgentRun = (deps.isHostScopedToolActive?.("openclaw") ?? isHostScopedAgentToolActive("openclaw")) && isSystemAgentOnlyToolAllowlist(input.toolsAllow);
|
|
1804
1790
|
const messages = getMessagesSnapshotInput(input);
|
|
1805
1791
|
const modelRef = resolveModelRef(input);
|
|
1806
1792
|
const resolvedWorkspaceForSandbox = readResolvedAttemptPath(input.workspaceDir) ?? readResolvedAttemptPath(input.cwd);
|
|
@@ -1880,6 +1866,13 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1880
1866
|
let downgradedFromResume = false;
|
|
1881
1867
|
let resumeFailureRecovered = false;
|
|
1882
1868
|
let yieldDetected = false;
|
|
1869
|
+
let lastToolError;
|
|
1870
|
+
const hostObserveToolTerminal = input.observeToolTerminal;
|
|
1871
|
+
const observeToolTerminal = hostObserveToolTerminal ? (observation) => {
|
|
1872
|
+
const terminal = hostObserveToolTerminal(observation);
|
|
1873
|
+
lastToolError = terminal.lastToolError;
|
|
1874
|
+
return terminal;
|
|
1875
|
+
} : void 0;
|
|
1883
1876
|
const markExternalAbort = () => {
|
|
1884
1877
|
abortRequested = true;
|
|
1885
1878
|
externalAbort = true;
|
|
@@ -1963,6 +1956,7 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1963
1956
|
const cleanupByokProxy = byokProxy?.close;
|
|
1964
1957
|
const sessionProvider = byokProxy?.provider ?? poolAcquire.provider;
|
|
1965
1958
|
const sessionRef = { current: void 0 };
|
|
1959
|
+
const computerContextEpoch = { value: 0 };
|
|
1966
1960
|
try {
|
|
1967
1961
|
let sdkTools;
|
|
1968
1962
|
try {
|
|
@@ -1979,7 +1973,11 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1979
1973
|
sandbox,
|
|
1980
1974
|
spawnWorkspaceDir: sandboxAwareSpawnWorkspaceDir,
|
|
1981
1975
|
abortSignal: params.abortSignal,
|
|
1982
|
-
attemptParams:
|
|
1976
|
+
attemptParams: observeToolTerminal ? {
|
|
1977
|
+
...input,
|
|
1978
|
+
observeToolTerminal
|
|
1979
|
+
} : input,
|
|
1980
|
+
computerContextEpoch,
|
|
1983
1981
|
sessionRef,
|
|
1984
1982
|
onYieldDetected: () => {
|
|
1985
1983
|
yieldDetected = true;
|
|
@@ -2054,8 +2052,14 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2054
2052
|
signal: params.abortSignal
|
|
2055
2053
|
});
|
|
2056
2054
|
userInputBridgeRef = userInputBridge;
|
|
2057
|
-
const sessionConfig = createSessionConfig(attemptInput, modelRef.id, sdkTools, poolAcquire.auth, sessionProvider, promptBuild.developerInstructions || void 0, effectiveWorkspaceDir, effectiveCwd, userInputBridge.onUserInputRequest,
|
|
2058
|
-
|
|
2055
|
+
const sessionConfig = createSessionConfig(attemptInput, modelRef.id, sdkTools, poolAcquire.auth, sessionProvider, promptBuild.developerInstructions || void 0, effectiveWorkspaceDir, effectiveCwd, userInputBridge.onUserInputRequest, {
|
|
2056
|
+
hooksBridgeOptions: hasNativePromptHook ? { onUserPromptSubmitted: ({ additionalContext, prompt }) => emitLlmInput(prompt, additionalContext) } : void 0,
|
|
2057
|
+
includeAskUser: !ringZeroSystemAgentRun
|
|
2058
|
+
});
|
|
2059
|
+
const compactionSessionConfig = byokProxy ? createSessionConfig(attemptInput, modelRef.id, sdkTools, poolAcquire.auth, poolAcquire.provider, promptBuild.developerInstructions || void 0, effectiveWorkspaceDir, effectiveCwd, userInputBridge.onUserInputRequest, {
|
|
2060
|
+
hooksBridgeOptions: hasNativePromptHook ? { onUserPromptSubmitted: ({ additionalContext, prompt }) => emitLlmInput(prompt, additionalContext) } : void 0,
|
|
2061
|
+
includeAskUser: !ringZeroSystemAgentRun
|
|
2062
|
+
}) : sessionConfig;
|
|
2059
2063
|
const replayDecision = decideReplayAction({
|
|
2060
2064
|
sdkSessionId: input.initialReplayState?.sdkSessionId,
|
|
2061
2065
|
replayInvalid: input.initialReplayState?.replayInvalid
|
|
@@ -2088,6 +2092,11 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2088
2092
|
onAssistantDelta: input.onAssistantDelta,
|
|
2089
2093
|
onAgentEvent: input.onAgentEvent,
|
|
2090
2094
|
onNativeSubagentEvent: (event) => nativeSubagentTaskMirror?.handleEvent(event),
|
|
2095
|
+
onContextCompacted: () => {
|
|
2096
|
+
computerContextEpoch.value += 1;
|
|
2097
|
+
delete computerContextEpoch.frameToolCallId;
|
|
2098
|
+
delete computerContextEpoch.frameImageIdentity;
|
|
2099
|
+
},
|
|
2091
2100
|
onCompactionStart: async () => {
|
|
2092
2101
|
const sessionFile = readString(input.sessionFile);
|
|
2093
2102
|
if (!sessionFile) return;
|
|
@@ -2245,20 +2254,21 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2245
2254
|
...syntheticUser ? [syntheticUser] : [],
|
|
2246
2255
|
...taggedLastAssistant ? [taggedLastAssistant] : []
|
|
2247
2256
|
];
|
|
2248
|
-
const sessionFileForMirror = readString(input.sessionFile);
|
|
2249
2257
|
const openClawSessionIdForMirror = readString(input.sessionId);
|
|
2258
|
+
const openClawSessionKeyForMirror = readString(input.sessionKey);
|
|
2259
|
+
const openClawStorePathForMirror = readString(input.sessionTarget?.storePath);
|
|
2250
2260
|
const mirrorScopeSessionId = sessionIdUsed ?? openClawSessionIdForMirror;
|
|
2251
|
-
if (
|
|
2261
|
+
if (openClawSessionIdForMirror && openClawSessionKeyForMirror && openClawStorePathForMirror && messagesSnapshot.length > 0) {
|
|
2252
2262
|
const taggedMessages = messagesSnapshot.map((message, index) => {
|
|
2253
2263
|
if (message.role !== "user" && message.role !== "assistant" && message.role !== "toolResult") return message;
|
|
2254
2264
|
if (hasMirrorIdentity(message)) return message;
|
|
2255
2265
|
return attachCopilotMirrorIdentity(message, `${sdkSessionId ?? mirrorScopeSessionId ?? "attempt"}:${message.role}:${index}`);
|
|
2256
2266
|
});
|
|
2257
2267
|
await dualWriteCopilotTranscriptBestEffort({
|
|
2258
|
-
sessionFile: sessionFileForMirror,
|
|
2259
2268
|
sessionId: openClawSessionIdForMirror,
|
|
2260
|
-
sessionKey:
|
|
2269
|
+
sessionKey: openClawSessionKeyForMirror,
|
|
2261
2270
|
agentId: readString(input.agentId),
|
|
2271
|
+
storePath: openClawStorePathForMirror,
|
|
2262
2272
|
messages: taggedMessages,
|
|
2263
2273
|
idempotencyScope: mirrorScopeSessionId ? `copilot:${mirrorScopeSessionId}` : void 0,
|
|
2264
2274
|
config: input.config
|
|
@@ -2278,6 +2288,7 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2278
2288
|
startedCount: snap?.startedCount ?? 0
|
|
2279
2289
|
},
|
|
2280
2290
|
lastAssistant,
|
|
2291
|
+
lastToolError,
|
|
2281
2292
|
messagesSnapshot,
|
|
2282
2293
|
now,
|
|
2283
2294
|
promptError,
|
|
@@ -2343,6 +2354,7 @@ function createResult(params, state) {
|
|
|
2343
2354
|
startedCount: 0
|
|
2344
2355
|
},
|
|
2345
2356
|
lastAssistant: state.lastAssistant,
|
|
2357
|
+
...state.lastToolError ? { lastToolError: state.lastToolError } : {},
|
|
2346
2358
|
messagesSnapshot: state.messagesSnapshot,
|
|
2347
2359
|
messagingToolSentMediaUrls: [],
|
|
2348
2360
|
messagingToolSentTargets: [],
|
|
@@ -2364,10 +2376,9 @@ function createPromptError(code, message, cause) {
|
|
|
2364
2376
|
if (cause !== void 0) error.cause = cause;
|
|
2365
2377
|
return error;
|
|
2366
2378
|
}
|
|
2367
|
-
function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolvedProvider, systemMessageContent, effectiveWorkspaceDir, effectiveCwd, onUserInputRequest,
|
|
2379
|
+
function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolvedProvider, systemMessageContent, effectiveWorkspaceDir, effectiveCwd, onUserInputRequest, options) {
|
|
2368
2380
|
const permissionPolicy = params.permissionPolicy ?? rejectAllPolicy;
|
|
2369
|
-
const hooks = createHooksBridge(params.hooksConfig, hooksBridgeOptions);
|
|
2370
|
-
const infiniteSessions = createInfiniteSessionConfig(params.infiniteSessionConfig);
|
|
2381
|
+
const hooks = createHooksBridge(params.hooksConfig, options.hooksBridgeOptions);
|
|
2371
2382
|
return {
|
|
2372
2383
|
model: sdkModelId,
|
|
2373
2384
|
onPermissionRequest: createPermissionBridge(permissionPolicy),
|
|
@@ -2375,10 +2386,10 @@ function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolve
|
|
|
2375
2386
|
...resolvedProvider.provider ? { provider: resolvedProvider.provider } : {},
|
|
2376
2387
|
...hooks ? { hooks } : {},
|
|
2377
2388
|
...typeof params.enableSessionTelemetry === "boolean" ? { enableSessionTelemetry: params.enableSessionTelemetry } : {},
|
|
2378
|
-
...
|
|
2389
|
+
...params.infiniteSessionConfig ? { infiniteSessions: params.infiniteSessionConfig } : {},
|
|
2379
2390
|
reasoningEffort: params.reasoningEffort,
|
|
2380
2391
|
tools: sdkTools,
|
|
2381
|
-
availableTools: buildCopilotAvailableTools(sdkTools),
|
|
2392
|
+
availableTools: buildCopilotAvailableTools(sdkTools, options.includeAskUser),
|
|
2382
2393
|
workingDirectory: effectiveCwd ?? effectiveWorkspaceDir ?? readResolvedAttemptPath(params.workspaceDir),
|
|
2383
2394
|
...effectiveWorkspaceDir && effectiveCwd && effectiveCwd !== effectiveWorkspaceDir ? { instructionDirectories: [effectiveWorkspaceDir] } : {},
|
|
2384
2395
|
...resolvedAuth.authMode === "gitHubToken" && resolvedAuth.gitHubToken ? { gitHubToken: resolvedAuth.gitHubToken } : {},
|
|
@@ -2388,8 +2399,13 @@ function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolve
|
|
|
2388
2399
|
} } : {}
|
|
2389
2400
|
};
|
|
2390
2401
|
}
|
|
2391
|
-
function buildCopilotAvailableTools(sdkTools) {
|
|
2392
|
-
|
|
2402
|
+
function buildCopilotAvailableTools(sdkTools, includeAskUser) {
|
|
2403
|
+
const availableTools = sdkTools.map((tool) => tool.name);
|
|
2404
|
+
if (includeAskUser) availableTools.push(...COPILOT_ASK_USER_AVAILABLE_TOOLS);
|
|
2405
|
+
return [...new Set(availableTools)];
|
|
2406
|
+
}
|
|
2407
|
+
function isSystemAgentOnlyToolAllowlist(toolsAllow) {
|
|
2408
|
+
return toolsAllow?.length === 1 && toolsAllow[0]?.trim().toLowerCase() === "openclaw";
|
|
2393
2409
|
}
|
|
2394
2410
|
async function createMessageOptions(params, context) {
|
|
2395
2411
|
const attachments = createPromptImageAttachments(await resolvePromptImages(params, context));
|
|
@@ -10,8 +10,7 @@ function normalizeCompatibilityConfig({ cfg }) {
|
|
|
10
10
|
* Session-state ownership claim for the copilot agent runtime.
|
|
11
11
|
*
|
|
12
12
|
* - id / label: Identify the extension in doctor output.
|
|
13
|
-
* - providerIds: The subscription Copilot providers
|
|
14
|
-
* with `SUPPORTED_PROVIDERS` in attempt.ts).
|
|
13
|
+
* - providerIds: The subscription Copilot providers.
|
|
15
14
|
* - runtimeIds: Our harness id (matches harness.ts `id` field).
|
|
16
15
|
* - cliSessionKeys: Session keys this harness writes; doctor uses
|
|
17
16
|
* this when pruning stale CLI session state.
|
|
@@ -481,7 +481,7 @@ function resolveCopilotProvider(params) {
|
|
|
481
481
|
};
|
|
482
482
|
}
|
|
483
483
|
function isCopilotByokUnsupportedProviderError(error) {
|
|
484
|
-
return error instanceof Error && (error.message ===
|
|
484
|
+
return error instanceof Error && (error.message === COPILOT_BYOK_PROVIDER_ERROR || error.message === COPILOT_BYOK_TRANSPORT_POLICY_ERROR || error.message === COPILOT_BYOK_ENDPOINT_POLICY_ERROR);
|
|
485
485
|
}
|
|
486
486
|
function supportsCopilotByokProviderShape(model) {
|
|
487
487
|
if (!readString(model.baseUrl) || hasUnsupportedTransportPolicy(model)) return false;
|
|
@@ -894,7 +894,7 @@ function createCopilotAgentHarness(options) {
|
|
|
894
894
|
async runAttempt(params) {
|
|
895
895
|
const attemptPromise = (async () => {
|
|
896
896
|
if (disposed) throw new Error("[copilot] harness has been disposed; cannot start new attempts");
|
|
897
|
-
const { resolvePoolAcquire, runCopilotAttempt } = await import("./attempt-
|
|
897
|
+
const { resolvePoolAcquire, runCopilotAttempt } = await import("./attempt-Bwgye68K.js");
|
|
898
898
|
if (disposed) throw new Error("[copilot] harness was disposed while starting an attempt");
|
|
899
899
|
const pool = await getPool();
|
|
900
900
|
if (disposed) throw new Error("[copilot] harness was disposed while starting an attempt");
|
|
@@ -1010,7 +1010,7 @@ function createCopilotAgentHarness(options) {
|
|
|
1010
1010
|
};
|
|
1011
1011
|
const tracked = trackedSessions.get(openclawSessionId);
|
|
1012
1012
|
const currentCompactKey = computeSessionCompactKey(params);
|
|
1013
|
-
const { resolvePoolAcquire } = await import("./attempt-
|
|
1013
|
+
const { resolvePoolAcquire } = await import("./attempt-Bwgye68K.js");
|
|
1014
1014
|
let resolvedPoolAcquire;
|
|
1015
1015
|
let currentAuth;
|
|
1016
1016
|
try {
|
package/dist/harness.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createCopilotAgentHarness } from "./harness-
|
|
1
|
+
import { t as createCopilotAgentHarness } from "./harness-DeWR8_cC.js";
|
|
2
2
|
export { createCopilotAgentHarness };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createCopilotAgentHarness } from "./harness-
|
|
1
|
+
import { t as createCopilotAgentHarness } from "./harness-DeWR8_cC.js";
|
|
2
2
|
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
3
3
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
//#region extensions/copilot/index.ts
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/copilot",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/copilot",
|
|
9
|
-
"version": "2026.7.
|
|
9
|
+
"version": "2026.7.2-beta.2",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@github/copilot-sdk": "1.0.5"
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/copilot",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.2",
|
|
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",
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
"@github/copilot-sdk": "1.0.5"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@github/copilot": "1.0.68",
|
|
15
14
|
"@openclaw/plugin-sdk": "workspace:*"
|
|
16
15
|
},
|
|
17
16
|
"openclaw": {
|
|
@@ -25,10 +24,10 @@
|
|
|
25
24
|
"minHostVersion": ">=2026.5.28"
|
|
26
25
|
},
|
|
27
26
|
"compat": {
|
|
28
|
-
"pluginApi": ">=2026.7.
|
|
27
|
+
"pluginApi": ">=2026.7.2-beta.2"
|
|
29
28
|
},
|
|
30
29
|
"build": {
|
|
31
|
-
"openclawVersion": "2026.7.
|
|
30
|
+
"openclawVersion": "2026.7.2-beta.2",
|
|
32
31
|
"bundledDist": false
|
|
33
32
|
},
|
|
34
33
|
"release": {
|
|
@@ -47,7 +46,7 @@
|
|
|
47
46
|
"README.md"
|
|
48
47
|
],
|
|
49
48
|
"peerDependencies": {
|
|
50
|
-
"openclaw": ">=2026.7.
|
|
49
|
+
"openclaw": ">=2026.7.2-beta.2"
|
|
51
50
|
},
|
|
52
51
|
"peerDependenciesMeta": {
|
|
53
52
|
"openclaw": {
|