@openclaw/copilot 2026.7.1 → 2026.7.2-beta.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/README.md +1 -3
- package/dist/{attempt-D6MSc00N.js → attempt-BxxMpQmE.js} +70 -107
- package/dist/doctor-contract-api.js +1 -2
- package/dist/{harness-BQhGzc1Z.js → harness-DnbBZBdi.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 -4
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-DnbBZBdi.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({
|
|
@@ -364,6 +350,9 @@ function attachEventBridge(session, options) {
|
|
|
364
350
|
enqueueCompactionCallback(options.onCompactionStart);
|
|
365
351
|
});
|
|
366
352
|
registerListener(session, unsubscribeFns, "session.compaction_complete", (event) => {
|
|
353
|
+
if (event.data.success) try {
|
|
354
|
+
options.onContextCompacted?.();
|
|
355
|
+
} catch {}
|
|
367
356
|
if (!isRootCompactionEvent(event)) return;
|
|
368
357
|
activeCompactionCount = Math.max(0, activeCompactionCount - 1);
|
|
369
358
|
enqueueCompactionCallback(() => options.onCompactionComplete?.({
|
|
@@ -553,7 +542,7 @@ function joinReasoning(order, reasoningById) {
|
|
|
553
542
|
function splitPlanText(text) {
|
|
554
543
|
return (text ?? "").split(/\r?\n/).map((line) => line.trim().replace(/^[-*]\s+/, "")).filter((line) => line.length > 0);
|
|
555
544
|
}
|
|
556
|
-
function readString$
|
|
545
|
+
function readString$1(value) {
|
|
557
546
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
558
547
|
}
|
|
559
548
|
function registerListener(session, unsubscribeFns, eventType, handler) {
|
|
@@ -1113,9 +1102,12 @@ function buildOpenClawCodingToolsOptions(input, toolPlan, toolSurfaceRuntime) {
|
|
|
1113
1102
|
elevated: a.bashElevated
|
|
1114
1103
|
},
|
|
1115
1104
|
messageProvider: a.messageProvider ?? a.messageChannel,
|
|
1105
|
+
chatType: a.chatType,
|
|
1116
1106
|
agentAccountId: a.agentAccountId,
|
|
1117
1107
|
messageTo: a.messageTo,
|
|
1118
1108
|
messageThreadId: a.messageThreadId,
|
|
1109
|
+
nativeChannelId: a.chatId,
|
|
1110
|
+
messageActionTurnCapability: a.messageActionTurnCapability,
|
|
1119
1111
|
groupId: a.groupId,
|
|
1120
1112
|
groupChannel: a.groupChannel,
|
|
1121
1113
|
groupSpace: a.groupSpace,
|
|
@@ -1164,6 +1156,7 @@ function buildOpenClawCodingToolsOptions(input, toolPlan, toolSurfaceRuntime) {
|
|
|
1164
1156
|
enableHeartbeatTool: a.enableHeartbeatTool,
|
|
1165
1157
|
forceHeartbeatTool: a.forceHeartbeatTool,
|
|
1166
1158
|
authProfileStore: a.toolAuthProfileStore ?? a.authProfileStore,
|
|
1159
|
+
computerContextEpoch: input.computerContextEpoch,
|
|
1167
1160
|
onToolOutcome: a.onToolOutcome,
|
|
1168
1161
|
onYield: (message) => {
|
|
1169
1162
|
try {
|
|
@@ -1249,7 +1242,7 @@ function convertOpenClawToolToSdkTool(sourceTool, ctx) {
|
|
|
1249
1242
|
} catch (error) {
|
|
1250
1243
|
return failureResult(preparedArgs, invocation, startedAt, `[copilot-tool-bridge] tool '${sourceTool.name}' failed: ${toError$1(error).message}`, error);
|
|
1251
1244
|
}
|
|
1252
|
-
const sdkResult =
|
|
1245
|
+
const sdkResult = convertMcpCallToolResult({ content: result.content });
|
|
1253
1246
|
const sanitizedResult = sanitizeToolResult(result);
|
|
1254
1247
|
const resultIsError = sdkResult.resultType === "failure" || isToolResultError(sanitizedResult);
|
|
1255
1248
|
const resultError = resultIsError ? extractToolErrorMessage(sanitizedResult) : void 0;
|
|
@@ -1331,51 +1324,6 @@ async function executeCatalogTool(input, params) {
|
|
|
1331
1324
|
function toToolStartArgs(args) {
|
|
1332
1325
|
return args && typeof args === "object" && !Array.isArray(args) ? args : { value: args };
|
|
1333
1326
|
}
|
|
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
1327
|
function createFailureResult(message, error) {
|
|
1380
1328
|
return {
|
|
1381
1329
|
error: toError$1(error).message,
|
|
@@ -1449,10 +1397,6 @@ function findDuplicateToolNames(sourceTools) {
|
|
|
1449
1397
|
}
|
|
1450
1398
|
return [...counts.entries()].filter(([, count]) => count > 1).map(([name]) => name).toSorted();
|
|
1451
1399
|
}
|
|
1452
|
-
function readString$1(value, options = {}) {
|
|
1453
|
-
if (typeof value !== "string") return;
|
|
1454
|
-
if (options.allowEmpty || value.length > 0) return value;
|
|
1455
|
-
}
|
|
1456
1400
|
function toError$1(error) {
|
|
1457
1401
|
return error instanceof Error ? error : new Error(String(error));
|
|
1458
1402
|
}
|
|
@@ -1622,9 +1566,9 @@ async function resolveCopilotWorkspaceBootstrapContext(params) {
|
|
|
1622
1566
|
* (`src/agents/pi-embedded-runner/run/attempt.ts:603`). Files whose
|
|
1623
1567
|
* resolved relative path escapes the source workspace (parent
|
|
1624
1568
|
* traversal or absolute) are left untouched so we never pretend a
|
|
1625
|
-
* file lives inside the sandbox when it does not.
|
|
1626
|
-
*
|
|
1627
|
-
*
|
|
1569
|
+
* file lives inside the sandbox when it does not. Intentionally local
|
|
1570
|
+
* to the Copilot extension (codex keeps similar helpers extension-local
|
|
1571
|
+
* rather than importing from PI).
|
|
1628
1572
|
*/
|
|
1629
1573
|
function remapCopilotBootstrapContextFiles(params) {
|
|
1630
1574
|
if (params.sourceWorkspaceDir === params.targetWorkspaceDir) return params.files;
|
|
@@ -1801,6 +1745,7 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1801
1745
|
const attemptStartedAt = now();
|
|
1802
1746
|
const input = params;
|
|
1803
1747
|
const createToolBridge = deps.createToolBridge ?? createCopilotToolBridge;
|
|
1748
|
+
const ringZeroSystemAgentRun = (deps.isHostScopedToolActive?.("openclaw") ?? isHostScopedAgentToolActive("openclaw")) && isSystemAgentOnlyToolAllowlist(input.toolsAllow);
|
|
1804
1749
|
const messages = getMessagesSnapshotInput(input);
|
|
1805
1750
|
const modelRef = resolveModelRef(input);
|
|
1806
1751
|
const resolvedWorkspaceForSandbox = readResolvedAttemptPath(input.workspaceDir) ?? readResolvedAttemptPath(input.cwd);
|
|
@@ -1963,6 +1908,7 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1963
1908
|
const cleanupByokProxy = byokProxy?.close;
|
|
1964
1909
|
const sessionProvider = byokProxy?.provider ?? poolAcquire.provider;
|
|
1965
1910
|
const sessionRef = { current: void 0 };
|
|
1911
|
+
const computerContextEpoch = { value: 0 };
|
|
1966
1912
|
try {
|
|
1967
1913
|
let sdkTools;
|
|
1968
1914
|
try {
|
|
@@ -1980,6 +1926,7 @@ async function runCopilotAttempt(params, deps) {
|
|
|
1980
1926
|
spawnWorkspaceDir: sandboxAwareSpawnWorkspaceDir,
|
|
1981
1927
|
abortSignal: params.abortSignal,
|
|
1982
1928
|
attemptParams: input,
|
|
1929
|
+
computerContextEpoch,
|
|
1983
1930
|
sessionRef,
|
|
1984
1931
|
onYieldDetected: () => {
|
|
1985
1932
|
yieldDetected = true;
|
|
@@ -2054,8 +2001,14 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2054
2001
|
signal: params.abortSignal
|
|
2055
2002
|
});
|
|
2056
2003
|
userInputBridgeRef = userInputBridge;
|
|
2057
|
-
const sessionConfig = createSessionConfig(attemptInput, modelRef.id, sdkTools, poolAcquire.auth, sessionProvider, promptBuild.developerInstructions || void 0, effectiveWorkspaceDir, effectiveCwd, userInputBridge.onUserInputRequest,
|
|
2058
|
-
|
|
2004
|
+
const sessionConfig = createSessionConfig(attemptInput, modelRef.id, sdkTools, poolAcquire.auth, sessionProvider, promptBuild.developerInstructions || void 0, effectiveWorkspaceDir, effectiveCwd, userInputBridge.onUserInputRequest, {
|
|
2005
|
+
hooksBridgeOptions: hasNativePromptHook ? { onUserPromptSubmitted: ({ additionalContext, prompt }) => emitLlmInput(prompt, additionalContext) } : void 0,
|
|
2006
|
+
includeAskUser: !ringZeroSystemAgentRun
|
|
2007
|
+
});
|
|
2008
|
+
const compactionSessionConfig = byokProxy ? createSessionConfig(attemptInput, modelRef.id, sdkTools, poolAcquire.auth, poolAcquire.provider, promptBuild.developerInstructions || void 0, effectiveWorkspaceDir, effectiveCwd, userInputBridge.onUserInputRequest, {
|
|
2009
|
+
hooksBridgeOptions: hasNativePromptHook ? { onUserPromptSubmitted: ({ additionalContext, prompt }) => emitLlmInput(prompt, additionalContext) } : void 0,
|
|
2010
|
+
includeAskUser: !ringZeroSystemAgentRun
|
|
2011
|
+
}) : sessionConfig;
|
|
2059
2012
|
const replayDecision = decideReplayAction({
|
|
2060
2013
|
sdkSessionId: input.initialReplayState?.sdkSessionId,
|
|
2061
2014
|
replayInvalid: input.initialReplayState?.replayInvalid
|
|
@@ -2088,6 +2041,11 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2088
2041
|
onAssistantDelta: input.onAssistantDelta,
|
|
2089
2042
|
onAgentEvent: input.onAgentEvent,
|
|
2090
2043
|
onNativeSubagentEvent: (event) => nativeSubagentTaskMirror?.handleEvent(event),
|
|
2044
|
+
onContextCompacted: () => {
|
|
2045
|
+
computerContextEpoch.value += 1;
|
|
2046
|
+
delete computerContextEpoch.frameToolCallId;
|
|
2047
|
+
delete computerContextEpoch.frameImageIdentity;
|
|
2048
|
+
},
|
|
2091
2049
|
onCompactionStart: async () => {
|
|
2092
2050
|
const sessionFile = readString(input.sessionFile);
|
|
2093
2051
|
if (!sessionFile) return;
|
|
@@ -2245,20 +2203,21 @@ async function runCopilotAttempt(params, deps) {
|
|
|
2245
2203
|
...syntheticUser ? [syntheticUser] : [],
|
|
2246
2204
|
...taggedLastAssistant ? [taggedLastAssistant] : []
|
|
2247
2205
|
];
|
|
2248
|
-
const sessionFileForMirror = readString(input.sessionFile);
|
|
2249
2206
|
const openClawSessionIdForMirror = readString(input.sessionId);
|
|
2207
|
+
const openClawSessionKeyForMirror = readString(input.sessionKey);
|
|
2208
|
+
const openClawStorePathForMirror = readString(input.sessionTarget?.storePath);
|
|
2250
2209
|
const mirrorScopeSessionId = sessionIdUsed ?? openClawSessionIdForMirror;
|
|
2251
|
-
if (
|
|
2210
|
+
if (openClawSessionIdForMirror && openClawSessionKeyForMirror && openClawStorePathForMirror && messagesSnapshot.length > 0) {
|
|
2252
2211
|
const taggedMessages = messagesSnapshot.map((message, index) => {
|
|
2253
2212
|
if (message.role !== "user" && message.role !== "assistant" && message.role !== "toolResult") return message;
|
|
2254
2213
|
if (hasMirrorIdentity(message)) return message;
|
|
2255
2214
|
return attachCopilotMirrorIdentity(message, `${sdkSessionId ?? mirrorScopeSessionId ?? "attempt"}:${message.role}:${index}`);
|
|
2256
2215
|
});
|
|
2257
2216
|
await dualWriteCopilotTranscriptBestEffort({
|
|
2258
|
-
sessionFile: sessionFileForMirror,
|
|
2259
2217
|
sessionId: openClawSessionIdForMirror,
|
|
2260
|
-
sessionKey:
|
|
2218
|
+
sessionKey: openClawSessionKeyForMirror,
|
|
2261
2219
|
agentId: readString(input.agentId),
|
|
2220
|
+
storePath: openClawStorePathForMirror,
|
|
2262
2221
|
messages: taggedMessages,
|
|
2263
2222
|
idempotencyScope: mirrorScopeSessionId ? `copilot:${mirrorScopeSessionId}` : void 0,
|
|
2264
2223
|
config: input.config
|
|
@@ -2364,10 +2323,9 @@ function createPromptError(code, message, cause) {
|
|
|
2364
2323
|
if (cause !== void 0) error.cause = cause;
|
|
2365
2324
|
return error;
|
|
2366
2325
|
}
|
|
2367
|
-
function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolvedProvider, systemMessageContent, effectiveWorkspaceDir, effectiveCwd, onUserInputRequest,
|
|
2326
|
+
function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolvedProvider, systemMessageContent, effectiveWorkspaceDir, effectiveCwd, onUserInputRequest, options) {
|
|
2368
2327
|
const permissionPolicy = params.permissionPolicy ?? rejectAllPolicy;
|
|
2369
|
-
const hooks = createHooksBridge(params.hooksConfig, hooksBridgeOptions);
|
|
2370
|
-
const infiniteSessions = createInfiniteSessionConfig(params.infiniteSessionConfig);
|
|
2328
|
+
const hooks = createHooksBridge(params.hooksConfig, options.hooksBridgeOptions);
|
|
2371
2329
|
return {
|
|
2372
2330
|
model: sdkModelId,
|
|
2373
2331
|
onPermissionRequest: createPermissionBridge(permissionPolicy),
|
|
@@ -2375,10 +2333,10 @@ function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolve
|
|
|
2375
2333
|
...resolvedProvider.provider ? { provider: resolvedProvider.provider } : {},
|
|
2376
2334
|
...hooks ? { hooks } : {},
|
|
2377
2335
|
...typeof params.enableSessionTelemetry === "boolean" ? { enableSessionTelemetry: params.enableSessionTelemetry } : {},
|
|
2378
|
-
...
|
|
2336
|
+
...params.infiniteSessionConfig ? { infiniteSessions: params.infiniteSessionConfig } : {},
|
|
2379
2337
|
reasoningEffort: params.reasoningEffort,
|
|
2380
2338
|
tools: sdkTools,
|
|
2381
|
-
availableTools: buildCopilotAvailableTools(sdkTools),
|
|
2339
|
+
availableTools: buildCopilotAvailableTools(sdkTools, options.includeAskUser),
|
|
2382
2340
|
workingDirectory: effectiveCwd ?? effectiveWorkspaceDir ?? readResolvedAttemptPath(params.workspaceDir),
|
|
2383
2341
|
...effectiveWorkspaceDir && effectiveCwd && effectiveCwd !== effectiveWorkspaceDir ? { instructionDirectories: [effectiveWorkspaceDir] } : {},
|
|
2384
2342
|
...resolvedAuth.authMode === "gitHubToken" && resolvedAuth.gitHubToken ? { gitHubToken: resolvedAuth.gitHubToken } : {},
|
|
@@ -2388,8 +2346,13 @@ function createSessionConfig(params, sdkModelId, sdkTools, resolvedAuth, resolve
|
|
|
2388
2346
|
} } : {}
|
|
2389
2347
|
};
|
|
2390
2348
|
}
|
|
2391
|
-
function buildCopilotAvailableTools(sdkTools) {
|
|
2392
|
-
|
|
2349
|
+
function buildCopilotAvailableTools(sdkTools, includeAskUser) {
|
|
2350
|
+
const availableTools = sdkTools.map((tool) => tool.name);
|
|
2351
|
+
if (includeAskUser) availableTools.push(...COPILOT_ASK_USER_AVAILABLE_TOOLS);
|
|
2352
|
+
return [...new Set(availableTools)];
|
|
2353
|
+
}
|
|
2354
|
+
function isSystemAgentOnlyToolAllowlist(toolsAllow) {
|
|
2355
|
+
return toolsAllow?.length === 1 && toolsAllow[0]?.trim().toLowerCase() === "openclaw";
|
|
2393
2356
|
}
|
|
2394
2357
|
async function createMessageOptions(params, context) {
|
|
2395
2358
|
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-BxxMpQmE.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-BxxMpQmE.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-DnbBZBdi.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-DnbBZBdi.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.1",
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/copilot",
|
|
9
|
-
"version": "2026.7.1",
|
|
9
|
+
"version": "2026.7.2-beta.1",
|
|
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.1",
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
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.7.1"
|
|
28
|
+
"pluginApi": ">=2026.7.2-beta.1"
|
|
29
29
|
},
|
|
30
30
|
"build": {
|
|
31
|
-
"openclawVersion": "2026.7.1",
|
|
31
|
+
"openclawVersion": "2026.7.2-beta.1",
|
|
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.7.1"
|
|
50
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependenciesMeta": {
|
|
53
53
|
"openclaw": {
|