mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-26 17:31:31 +08:00
Compare commits
21 Commits
codex/agen
...
v2026.6.9-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
500f425019 | ||
|
|
9cd55c5048 | ||
|
|
a79493b51f | ||
|
|
59a579a3aa | ||
|
|
eef218a143 | ||
|
|
34182465f2 | ||
|
|
9d6174efe7 | ||
|
|
e3ae182986 | ||
|
|
a00f22d4b5 | ||
|
|
6ce0bcc255 | ||
|
|
c5a5653189 | ||
|
|
2bdfbf7166 | ||
|
|
3ab6915e50 | ||
|
|
bc9b6945dd | ||
|
|
c0610bcd90 | ||
|
|
8d2826b515 | ||
|
|
2d4643b607 | ||
|
|
61a0a25a03 | ||
|
|
9d816fe3c0 | ||
|
|
9cbd01b3d2 | ||
|
|
7bc8a0580d |
6
.github/workflows/plugin-prerelease.yml
vendored
6
.github/workflows/plugin-prerelease.yml
vendored
@@ -344,7 +344,11 @@ jobs:
|
||||
OPENCLAW_EXTENSION_BATCH_PARALLEL: 2
|
||||
OPENCLAW_VITEST_MAX_WORKERS: 1
|
||||
OPENCLAW_EXTENSION_BATCH: ${{ matrix.extensions_csv }}
|
||||
run: pnpm test:extensions:batch "$OPENCLAW_EXTENSION_BATCH" -- --exclude extensions/codex/src/app-server/run-attempt.test.ts
|
||||
run: |
|
||||
pnpm test:extensions:batch "$OPENCLAW_EXTENSION_BATCH" -- \
|
||||
--exclude extensions/codex/src/app-server/run-attempt.test.ts \
|
||||
--exclude extensions/codex/src/app-server/run-attempt.dynamic-tools.test.ts \
|
||||
--exclude extensions/codex/src/app-server/run-attempt.turn-watches.test.ts
|
||||
|
||||
plugin-prerelease-inspector:
|
||||
permissions:
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
Docs: https://docs.openclaw.ai
|
||||
|
||||
## 2026.6.9-alpha.6
|
||||
|
||||
### Fixes
|
||||
|
||||
- Stabilize the alpha package train by preserving Codex app-server bindings, refreshing generated plugin metadata, and aligning channel and runtime validation fixtures for release gates.
|
||||
|
||||
## 2026.6.8
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -1126,13 +1126,17 @@ internal fun gatewayRecoveryUiState(
|
||||
!gatewayConnectionProblem.canAutoRetry -> GatewayRecoveryUiState.ApprovalRequired
|
||||
gatewayConnectionProblem?.isPairingRequired == true -> GatewayRecoveryUiState.Pairing
|
||||
gatewayConnectionProblem?.pauseReconnect == true -> GatewayRecoveryUiState.Failed
|
||||
nodeCapabilityApprovalState == GatewayNodeApprovalState.Loading -> GatewayRecoveryUiState.Finishing
|
||||
connectSettling -> GatewayRecoveryUiState.Finishing
|
||||
gatewayStatusLooksLikePairing(statusText) -> GatewayRecoveryUiState.Pairing
|
||||
gatewayStatusLooksLikePartialConnect(statusText) -> GatewayRecoveryUiState.Finishing
|
||||
nodeCapabilityApprovalState == GatewayNodeApprovalState.Loading &&
|
||||
gatewayStatusLooksLikeConnected(statusText) -> GatewayRecoveryUiState.Finishing
|
||||
else -> GatewayRecoveryUiState.Failed
|
||||
}
|
||||
|
||||
internal fun gatewayStatusLooksLikeConnected(statusText: String): Boolean =
|
||||
gatewayStatusForDisplay(statusText).equals("Connected", ignoreCase = true)
|
||||
|
||||
/** Detects gateway-approved states where the Android node is still coming online. */
|
||||
internal fun gatewayStatusLooksLikePartialConnect(statusText: String): Boolean {
|
||||
val lower = gatewayStatusForDisplay(statusText).lowercase()
|
||||
@@ -1223,8 +1227,6 @@ private fun recoveryGatewayDetail(
|
||||
nodeCapabilityApprovalState == GatewayNodeApprovalState.Unapproved
|
||||
) {
|
||||
"Gateway paired. Waiting for node capability approval."
|
||||
} else if (nodeCapabilityApprovalState == GatewayNodeApprovalState.Loading) {
|
||||
"Gateway paired. Checking node capability approval."
|
||||
} else if (gatewayConnectionProblem?.isPairingRequired == true && !gatewayConnectionProblem.canAutoRetry) {
|
||||
recoveryGatewayApprovalCommand(gatewayConnectionProblem)
|
||||
?.let { "Gateway approval is pending. Run this on the gateway host:" }
|
||||
@@ -1233,6 +1235,11 @@ private fun recoveryGatewayDetail(
|
||||
"Gateway paired. Waiting for operator access."
|
||||
} else if (gatewayStatusLooksLikePairing(statusText)) {
|
||||
"Gateway approval is in progress. OpenClaw will retry automatically."
|
||||
} else if (
|
||||
nodeCapabilityApprovalState == GatewayNodeApprovalState.Loading &&
|
||||
gatewayStatusLooksLikeConnected(statusText)
|
||||
) {
|
||||
"Gateway paired. Checking node capability approval."
|
||||
} else {
|
||||
"Gateway unreachable"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
b7ec57a4f38bf44677870fd9a8347be83f3f23a25a73d97931406f0eff572181 config-baseline.json
|
||||
f64d525143960404258c98435ad31018ff6c84da66e0640fdd775b3f62c5ece2 config-baseline.json
|
||||
99d506f05de601e5b45c98f302650c8608d1e2bb3dcea11bf97881c1263659ac config-baseline.core.json
|
||||
2d735389858305509528e74329b6f8c65d311e1471c3b4e91dc17aaab8e63a80 config-baseline.channel.json
|
||||
a973af69b02a27b097b54e49886dd57dbebbc95e2ab29b0c7e222a9f35a105d8 config-baseline.plugin.json
|
||||
fcfd742aa81b08cf09afea4ae4ccd557a7aa25320059f564b376729f2ebe8f0a config-baseline.plugin.json
|
||||
|
||||
4
extensions/acpx/npm-shrinkwrap.json
generated
4
extensions/acpx/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/claude-agent-acp": "0.39.0",
|
||||
"@zed-industries/codex-acp": "0.15.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw ACP runtime backend with plugin-owned session and transport management.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,10 +26,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./src/runtime-internals/mcp-proxy.mjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/admin-http-rpc",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw admin HTTP RPC endpoint",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/alibaba-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Alibaba Model Studio video provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "0.100.1",
|
||||
"@aws/bedrock-token-generator": "1.1.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Amazon Bedrock Mantle provider plugin for OpenAI-compatible model routing.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -24,10 +24,10 @@
|
||||
"minHostVersion": ">=2026.5.12-beta.1"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
4
extensions/amazon-bedrock/npm-shrinkwrap.json
generated
4
extensions/amazon-bedrock/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/amazon-bedrock-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-bedrock": "3.1056.0",
|
||||
"@aws-sdk/client-bedrock-runtime": "3.1056.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Amazon Bedrock provider plugin with model discovery, embeddings, and guardrail support.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -28,10 +28,10 @@
|
||||
"minHostVersion": ">=2026.5.12-beta.1"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
4
extensions/anthropic-vertex/npm-shrinkwrap.json
generated
4
extensions/anthropic-vertex/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-vertex-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/anthropic-vertex-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/vertex-sdk": "0.16.1"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-vertex-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Anthropic Vertex provider plugin for Claude models on Google Vertex AI.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -23,10 +23,10 @@
|
||||
"minHostVersion": ">=2026.5.12-beta.1"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Anthropic provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/arcee-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Arcee provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/azure-speech",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Azure Speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/bonjour",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Bonjour/mDNS gateway discovery",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
4
extensions/brave/npm-shrinkwrap.json
generated
4
extensions/brave/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/brave-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/brave-plugin",
|
||||
"version": "2026.6.8"
|
||||
"version": "2026.6.9-alpha.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/brave-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Brave Search provider plugin for web search.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/browser-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw browser tool plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/byteplus-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw BytePlus provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/canvas-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Canvas plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cerebras-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Cerebras provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/chutes-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Chutes.ai provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/clickclack",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw ClickClack channel plugin",
|
||||
"type": "module",
|
||||
@@ -18,7 +18,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cloudflare-ai-gateway-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Cloudflare AI Gateway provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/codex-supervisor",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Codex app-server fleet supervision plugin.",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/codex/npm-shrinkwrap.json
generated
4
extensions/codex/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/codex",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/codex",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@openai/codex": "0.139.0",
|
||||
"typebox": "1.1.39",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/codex",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Codex app-server harness and model provider plugin with a Codex-managed GPT catalog.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -34,10 +34,10 @@
|
||||
]
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -324,6 +324,7 @@ export async function startCodexAttemptThread(params: {
|
||||
pluginThreadConfig: pluginThreadConfigRequired
|
||||
? {
|
||||
enabled: true,
|
||||
codexPluginsEnabled: resolvedPluginPolicy?.enabled === true,
|
||||
inputFingerprint: pluginThreadConfigInputFingerprint,
|
||||
enabledPluginConfigKeys,
|
||||
build: () =>
|
||||
|
||||
@@ -21,6 +21,7 @@ let codexAppServerClientFactoryForTest: CodexAppServerClientFactory | undefined;
|
||||
type RunCodexAppServerAttemptOptions = NonNullable<
|
||||
Parameters<typeof runCodexAppServerAttemptImpl>[1]
|
||||
>;
|
||||
type CodexAppServerBindingInput = Parameters<typeof writeCodexAppServerBinding>[1];
|
||||
|
||||
function setCodexAppServerClientFactoryForTest(factory: CodexAppServerClientFactory): void {
|
||||
codexAppServerClientFactoryForTest = factory;
|
||||
@@ -66,9 +67,7 @@ const DISABLED_CODEX_WEB_SEARCH_THREAD_CONFIG_FINGERPRINT = JSON.stringify({
|
||||
web_search: "disabled",
|
||||
});
|
||||
|
||||
function writeCodexAppServerBinding(
|
||||
...args: Parameters<typeof writeRawCodexAppServerBinding>
|
||||
) {
|
||||
function writeCodexAppServerBinding(...args: Parameters<typeof writeRawCodexAppServerBinding>) {
|
||||
const [sessionFile, binding, lookup] = args;
|
||||
return writeRawCodexAppServerBinding(
|
||||
sessionFile,
|
||||
@@ -176,6 +175,73 @@ function createCodexAuthProfileHarness(params: { startMethod: "thread/start" | "
|
||||
};
|
||||
}
|
||||
|
||||
async function resolveCurrentBindingDefaults(
|
||||
tmpDir: string,
|
||||
): Promise<Partial<CodexAppServerBindingInput>> {
|
||||
const sessionFile = path.join(tmpDir, `binding-metadata-${Date.now()}.jsonl`);
|
||||
let notify: (notification: unknown) => Promise<void> = async () => undefined;
|
||||
const requests: string[] = [];
|
||||
setCodexAppServerClientFactoryForTest(
|
||||
async () =>
|
||||
({
|
||||
request: vi.fn(async (method: string) => {
|
||||
requests.push(method);
|
||||
if (method === "thread/start") {
|
||||
return threadStartResult("thread-auth-metadata");
|
||||
}
|
||||
if (method === "turn/start") {
|
||||
return turnStartResult("turn-auth-metadata");
|
||||
}
|
||||
throw new Error(`unexpected metadata method: ${method}`);
|
||||
}),
|
||||
addNotificationHandler: (handler: (notification: unknown) => Promise<void>) => {
|
||||
notify = handler;
|
||||
return () => undefined;
|
||||
},
|
||||
addRequestHandler: () => () => undefined,
|
||||
}) as never,
|
||||
);
|
||||
|
||||
const run = runCodexAppServerAttempt(createParams(sessionFile, tmpDir));
|
||||
await vi.waitFor(() => expect(requests).toContain("turn/start"), { interval: 1 });
|
||||
await notify({
|
||||
method: "turn/completed",
|
||||
params: {
|
||||
threadId: "thread-auth-metadata",
|
||||
turnId: "turn-auth-metadata",
|
||||
turn: { id: "turn-auth-metadata", status: "completed" },
|
||||
},
|
||||
});
|
||||
await run;
|
||||
|
||||
const binding = await readCodexAppServerBinding(sessionFile);
|
||||
if (!binding) {
|
||||
throw new Error("expected current Codex auth binding metadata");
|
||||
}
|
||||
return {
|
||||
dynamicToolsFingerprint: binding.dynamicToolsFingerprint,
|
||||
dynamicToolsContainDeferred: binding.dynamicToolsContainDeferred,
|
||||
webSearchThreadConfigFingerprint: binding.webSearchThreadConfigFingerprint,
|
||||
userMcpServersFingerprint: binding.userMcpServersFingerprint,
|
||||
mcpServersFingerprint: binding.mcpServersFingerprint,
|
||||
pluginAppsFingerprint: binding.pluginAppsFingerprint,
|
||||
pluginAppsInputFingerprint: binding.pluginAppsInputFingerprint,
|
||||
pluginAppPolicyContext: binding.pluginAppPolicyContext,
|
||||
environmentSelectionFingerprint: binding.environmentSelectionFingerprint,
|
||||
};
|
||||
}
|
||||
|
||||
async function writeCurrentCodexAppServerBinding(
|
||||
sessionFile: string,
|
||||
tmpDir: string,
|
||||
binding: CodexAppServerBindingInput,
|
||||
): Promise<void> {
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
...(await resolveCurrentBindingDefaults(tmpDir)),
|
||||
...binding,
|
||||
});
|
||||
}
|
||||
|
||||
describe("Auth profile runtime contract - Codex app-server adapter", () => {
|
||||
let tmpDir: string;
|
||||
|
||||
@@ -213,14 +279,13 @@ describe("Auth profile runtime contract - Codex app-server adapter", () => {
|
||||
});
|
||||
|
||||
it("reuses a bound OpenAI Codex auth profile when resume params omit authProfileId", async () => {
|
||||
const harness = createCodexAuthProfileHarness({ startMethod: "thread/resume" });
|
||||
const sessionFile = path.join(tmpDir, "session.jsonl");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, tmpDir, {
|
||||
threadId: "thread-auth-contract",
|
||||
cwd: tmpDir,
|
||||
authProfileId: AUTH_PROFILE_RUNTIME_CONTRACT.openAiCodexProfileId,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
});
|
||||
const harness = createCodexAuthProfileHarness({ startMethod: "thread/resume" });
|
||||
// authProfileId is intentionally omitted to exercise the resume-bound profile path.
|
||||
const params = createParams(sessionFile, tmpDir);
|
||||
|
||||
@@ -238,14 +303,13 @@ describe("Auth profile runtime contract - Codex app-server adapter", () => {
|
||||
});
|
||||
|
||||
it("prefers an explicit runtime auth profile over a stale persisted binding", async () => {
|
||||
const harness = createCodexAuthProfileHarness({ startMethod: "thread/resume" });
|
||||
const sessionFile = path.join(tmpDir, "session.jsonl");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, tmpDir, {
|
||||
threadId: "thread-auth-contract",
|
||||
cwd: tmpDir,
|
||||
authProfileId: "openai:stale",
|
||||
dynamicToolsFingerprint: "[]",
|
||||
});
|
||||
const harness = createCodexAuthProfileHarness({ startMethod: "thread/resume" });
|
||||
const params = createParams(sessionFile, tmpDir);
|
||||
params.authProfileId = AUTH_PROFILE_RUNTIME_CONTRACT.openAiCodexProfileId;
|
||||
|
||||
|
||||
@@ -412,10 +412,10 @@ export function createStartedThreadHarness(
|
||||
}, options);
|
||||
}
|
||||
|
||||
export function createResumeHarness() {
|
||||
export function createResumeHarness(threadId = "thread-existing") {
|
||||
return createAppServerHarness(async (method) => {
|
||||
if (method === "thread/resume") {
|
||||
return threadStartResult("thread-existing");
|
||||
return threadStartResult(threadId);
|
||||
}
|
||||
if (method === "turn/start") {
|
||||
return turnStartResult();
|
||||
|
||||
@@ -26,6 +26,7 @@ let codexAppServerClientFactoryForTest: CodexAppServerClientFactory | undefined;
|
||||
type RunCodexAppServerAttemptOptions = NonNullable<
|
||||
Parameters<typeof runCodexAppServerAttemptImpl>[1]
|
||||
>;
|
||||
type CodexAppServerBindingInput = Parameters<typeof writeCodexAppServerBinding>[1];
|
||||
|
||||
function setCodexAppServerClientFactoryForTest(factory: CodexAppServerClientFactory): void {
|
||||
codexAppServerClientFactoryForTest = factory;
|
||||
@@ -71,9 +72,7 @@ const DISABLED_CODEX_WEB_SEARCH_THREAD_CONFIG_FINGERPRINT = JSON.stringify({
|
||||
web_search: "disabled",
|
||||
});
|
||||
|
||||
function writeCodexAppServerBinding(
|
||||
...args: Parameters<typeof writeRawCodexAppServerBinding>
|
||||
) {
|
||||
function writeCodexAppServerBinding(...args: Parameters<typeof writeRawCodexAppServerBinding>) {
|
||||
const [sessionFile, binding, lookup] = args;
|
||||
return writeRawCodexAppServerBinding(
|
||||
sessionFile,
|
||||
@@ -264,6 +263,46 @@ function createContextEngine(overrides: Partial<ContextEngine> = {}): ContextEng
|
||||
return engine;
|
||||
}
|
||||
|
||||
async function resolveCurrentBindingDefaults(): Promise<Partial<CodexAppServerBindingInput>> {
|
||||
const metadataSessionFile = path.join(tempDir, `binding-metadata-${Date.now()}.jsonl`);
|
||||
const metadataWorkspaceDir = path.join(tempDir, "binding-metadata-workspace");
|
||||
const harness = createStartedThreadHarness(async (method) => {
|
||||
if (method === "thread/start") {
|
||||
return threadStartResult("thread-metadata");
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const run = runCodexAppServerAttempt(createParams(metadataSessionFile, metadataWorkspaceDir));
|
||||
await harness.waitForMethod("turn/start");
|
||||
await harness.completeTurn("completed", "thread-metadata");
|
||||
await run;
|
||||
const binding = await readCodexAppServerBinding(metadataSessionFile);
|
||||
if (!binding) {
|
||||
throw new Error("expected current Codex app-server binding metadata");
|
||||
}
|
||||
return {
|
||||
dynamicToolsFingerprint: binding.dynamicToolsFingerprint,
|
||||
dynamicToolsContainDeferred: binding.dynamicToolsContainDeferred,
|
||||
webSearchThreadConfigFingerprint: binding.webSearchThreadConfigFingerprint,
|
||||
userMcpServersFingerprint: binding.userMcpServersFingerprint,
|
||||
mcpServersFingerprint: binding.mcpServersFingerprint,
|
||||
pluginAppsFingerprint: binding.pluginAppsFingerprint,
|
||||
pluginAppsInputFingerprint: binding.pluginAppsInputFingerprint,
|
||||
pluginAppPolicyContext: binding.pluginAppPolicyContext,
|
||||
environmentSelectionFingerprint: binding.environmentSelectionFingerprint,
|
||||
};
|
||||
}
|
||||
|
||||
async function writeCurrentCodexAppServerBinding(
|
||||
sessionFile: string,
|
||||
binding: CodexAppServerBindingInput,
|
||||
): Promise<void> {
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
...(await resolveCurrentBindingDefaults()),
|
||||
...binding,
|
||||
});
|
||||
}
|
||||
|
||||
type MockCallReader = { mock: { calls: unknown[][] } };
|
||||
|
||||
function requireRecord(value: unknown, label: string): Record<string, unknown> {
|
||||
@@ -599,7 +638,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
const agentDir = path.join(tempDir, "agent");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-bootstrapped",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -684,7 +723,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
const agentDir = path.join(tempDir, "agent");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-bootstrapped",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -772,7 +811,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
sessionManager.appendMessage(
|
||||
assistantMessage("previous stale-bootstrap answer", Date.now() + 1) as never,
|
||||
);
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-stale-bootstrap",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -858,7 +897,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
const sessionManager = SessionManager.open(sessionFile);
|
||||
sessionManager.appendMessage(userMessage("previous per-turn request", 10) as never);
|
||||
sessionManager.appendMessage(assistantMessage("previous per-turn answer", 11) as never);
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-per-turn-context",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -902,7 +941,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
const info = vi.spyOn(embeddedAgentLog, "info").mockImplementation(() => undefined);
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -989,7 +1028,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
it("reprojects thread-bootstrap context when context-engine policy changes", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1071,7 +1110,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
try {
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1166,7 +1205,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
it("starts a fresh Codex thread when thread-bootstrap projection falls back to per-turn projection", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1236,7 +1275,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
SessionManager.open(sessionFile).appendMessage(
|
||||
assistantMessage("pre-compaction context", Date.now()) as never,
|
||||
);
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1338,7 +1377,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
SessionManager.open(sessionFile).appendMessage(
|
||||
assistantMessage("pre-compaction context", Date.now()) as never,
|
||||
);
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1374,7 +1413,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
return threadStartResult("thread-old");
|
||||
}
|
||||
if (method === "turn/start" && request.threadId === "thread-old") {
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-new",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1410,7 +1449,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
SessionManager.open(sessionFile).appendMessage(
|
||||
assistantMessage("pre-compaction context", Date.now()) as never,
|
||||
);
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
@@ -1568,7 +1607,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => {
|
||||
SessionManager.open(sessionFile).appendMessage(
|
||||
assistantMessage("pre-compaction context", Date.now()) as never,
|
||||
);
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-old",
|
||||
cwd: workspaceDir,
|
||||
dynamicToolsFingerprint: "[]",
|
||||
|
||||
@@ -36,6 +36,8 @@ import {
|
||||
runCodexAppServerAttempt,
|
||||
setupRunAttemptTestHooks,
|
||||
tempDir,
|
||||
threadStartResult,
|
||||
turnStartResult,
|
||||
} from "./run-attempt-test-harness.js";
|
||||
import { testing } from "./run-attempt.js";
|
||||
|
||||
@@ -71,6 +73,8 @@ setupRunAttemptTestHooks();
|
||||
|
||||
describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
it("preserves model order across queued native and dynamic tools", async () => {
|
||||
const threadId = "thread-dynamic-order";
|
||||
const turnId = "turn-dynamic-order";
|
||||
let rejectSlowTool!: (error: Error) => void;
|
||||
const slowToolResult = new Promise<never>((_resolve, reject) => {
|
||||
rejectSlowTool = reject;
|
||||
@@ -82,11 +86,26 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
result: textToolResult("fast result"),
|
||||
format: () => "later dynamic summary",
|
||||
});
|
||||
const harness = createStartedThreadHarness();
|
||||
const harness = createStartedThreadHarness(async (method) => {
|
||||
if (method === "modelProvider/capabilities/read") {
|
||||
return { webSearch: false };
|
||||
}
|
||||
if (method === "thread/start") {
|
||||
return threadStartResult(threadId);
|
||||
}
|
||||
if (method === "turn/start") {
|
||||
return turnStartResult(turnId);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const params = createParams(
|
||||
path.join(tempDir, "session.jsonl"),
|
||||
path.join(tempDir, "workspace"),
|
||||
);
|
||||
params.sessionId = "session-dynamic-order";
|
||||
params.sessionKey = "agent:main:session-dynamic-order";
|
||||
params.runId = "run-dynamic-order";
|
||||
params.timeoutMs = 30_000;
|
||||
let terminalPresentation: string | undefined;
|
||||
let latestOrdinal = -1;
|
||||
let nextOrdinal = 0;
|
||||
@@ -137,7 +156,7 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
]) {
|
||||
await harness.notify({
|
||||
method: "rawResponseItem/completed",
|
||||
params: { threadId: "thread-1", turnId: "turn-1", item },
|
||||
params: { threadId, turnId, item },
|
||||
});
|
||||
}
|
||||
const webSearchItem = {
|
||||
@@ -149,13 +168,13 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
};
|
||||
const webSearchStarted = harness.notify({
|
||||
method: "item/started",
|
||||
params: { threadId: "thread-1", turnId: "turn-1", item: webSearchItem },
|
||||
params: { threadId, turnId, item: webSearchItem },
|
||||
});
|
||||
const rawWebSearch = harness.notify({
|
||||
method: "rawResponseItem/completed",
|
||||
params: {
|
||||
threadId: "thread-1",
|
||||
turnId: "turn-1",
|
||||
threadId,
|
||||
turnId,
|
||||
item: {
|
||||
type: "web_search_call",
|
||||
status: "completed",
|
||||
@@ -166,8 +185,8 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
await harness.notify({
|
||||
method: "rawResponseItem/completed",
|
||||
params: {
|
||||
threadId: "thread-1",
|
||||
turnId: "turn-1",
|
||||
threadId,
|
||||
turnId,
|
||||
item: {
|
||||
type: "function_call",
|
||||
name: "fast_summary",
|
||||
@@ -181,8 +200,8 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
id: "request-slow",
|
||||
method: "item/tool/call",
|
||||
params: {
|
||||
threadId: "thread-1",
|
||||
turnId: "turn-1",
|
||||
threadId,
|
||||
turnId,
|
||||
callId: "call-slow",
|
||||
namespace: null,
|
||||
tool: "slow_failure",
|
||||
@@ -204,14 +223,14 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
};
|
||||
const nativeStarted = harness.notify({
|
||||
method: "item/started",
|
||||
params: { threadId: "thread-1", turnId: "turn-1", item: nativeItem },
|
||||
params: { threadId, turnId, item: nativeItem },
|
||||
});
|
||||
await harness.handleServerRequest({
|
||||
id: "request-later",
|
||||
method: "item/tool/call",
|
||||
params: {
|
||||
threadId: "thread-1",
|
||||
turnId: "turn-1",
|
||||
threadId,
|
||||
turnId,
|
||||
callId: "call-later",
|
||||
namespace: null,
|
||||
tool: "fast_summary",
|
||||
@@ -222,19 +241,19 @@ describe("runCodexAppServerAttempt dynamic tools", () => {
|
||||
await webSearchStarted;
|
||||
await harness.notify({
|
||||
method: "item/completed",
|
||||
params: { threadId: "thread-1", turnId: "turn-1", item: nativeItem },
|
||||
params: { threadId, turnId, item: nativeItem },
|
||||
});
|
||||
await harness.notify({
|
||||
method: "item/completed",
|
||||
params: { threadId: "thread-1", turnId: "turn-1", item: webSearchItem },
|
||||
params: { threadId, turnId, item: webSearchItem },
|
||||
});
|
||||
rejectSlowTool(new Error("slow failure"));
|
||||
await slowCall;
|
||||
await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
|
||||
await harness.completeTurn({ threadId, turnId });
|
||||
await run;
|
||||
|
||||
expect(terminalPresentation).toBe("later dynamic summary");
|
||||
});
|
||||
}, 300_000);
|
||||
|
||||
it("suppresses a late dynamic tool presentation after its timeout response", async () => {
|
||||
let resolveSlowTool!: (result: ReturnType<typeof textToolResult>) => void;
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
runCodexAppServerAttempt,
|
||||
setupRunAttemptTestHooks,
|
||||
tempDir,
|
||||
threadStartResult,
|
||||
} from "./run-attempt-test-harness.js";
|
||||
import { testing } from "./run-attempt.js";
|
||||
import {
|
||||
@@ -30,9 +31,7 @@ const DISABLED_CODEX_WEB_SEARCH_THREAD_CONFIG_FINGERPRINT = JSON.stringify({
|
||||
web_search: "disabled",
|
||||
});
|
||||
|
||||
function writeCodexAppServerBinding(
|
||||
...args: Parameters<typeof writeRawCodexAppServerBinding>
|
||||
) {
|
||||
function writeCodexAppServerBinding(...args: Parameters<typeof writeRawCodexAppServerBinding>) {
|
||||
const [sessionFile, binding, lookup] = args;
|
||||
return writeRawCodexAppServerBinding(
|
||||
sessionFile,
|
||||
@@ -44,6 +43,41 @@ function writeCodexAppServerBinding(
|
||||
);
|
||||
}
|
||||
|
||||
type CodexAppServerBindingInput = Parameters<typeof writeCodexAppServerBinding>[1];
|
||||
|
||||
async function writeCurrentCodexAppServerBinding(
|
||||
sessionFile: string,
|
||||
workspaceDir: string,
|
||||
binding: CodexAppServerBindingInput,
|
||||
): Promise<void> {
|
||||
const harness = createStartedThreadHarness(async (method) => {
|
||||
if (method === "thread/start") {
|
||||
return threadStartResult(binding.threadId);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const run = runCodexAppServerAttempt(createParams(sessionFile, workspaceDir));
|
||||
await harness.waitForMethod("turn/start");
|
||||
await harness.completeTurn({ threadId: binding.threadId, turnId: "turn-1" });
|
||||
await run;
|
||||
const currentBinding = await readCodexAppServerBinding(sessionFile);
|
||||
if (!currentBinding) {
|
||||
throw new Error("expected current Codex app-server binding");
|
||||
}
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
dynamicToolsFingerprint: currentBinding.dynamicToolsFingerprint,
|
||||
dynamicToolsContainDeferred: currentBinding.dynamicToolsContainDeferred,
|
||||
webSearchThreadConfigFingerprint: currentBinding.webSearchThreadConfigFingerprint,
|
||||
userMcpServersFingerprint: currentBinding.userMcpServersFingerprint,
|
||||
mcpServersFingerprint: currentBinding.mcpServersFingerprint,
|
||||
pluginAppsFingerprint: currentBinding.pluginAppsFingerprint,
|
||||
pluginAppsInputFingerprint: currentBinding.pluginAppsInputFingerprint,
|
||||
pluginAppPolicyContext: currentBinding.pluginAppPolicyContext,
|
||||
environmentSelectionFingerprint: currentBinding.environmentSelectionFingerprint,
|
||||
...binding,
|
||||
});
|
||||
}
|
||||
|
||||
describe("runCodexAppServerAttempt native hook relay", () => {
|
||||
it("registers native hook relay config for an enabled Codex turn and cleans it up", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
@@ -514,7 +548,7 @@ describe("runCodexAppServerAttempt native hook relay", () => {
|
||||
it("accepts a stale first hook generation when resuming a pre-generation binding", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, workspaceDir, {
|
||||
threadId: "thread-existing",
|
||||
cwd: workspaceDir,
|
||||
model: "gpt-5.4-codex",
|
||||
@@ -577,7 +611,7 @@ describe("runCodexAppServerAttempt native hook relay", () => {
|
||||
it("rotates native hook relay generations when an existing binding starts a fresh thread", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, workspaceDir, {
|
||||
threadId: "thread-existing",
|
||||
cwd: workspaceDir,
|
||||
model: "gpt-5.4-codex",
|
||||
@@ -626,7 +660,7 @@ describe("runCodexAppServerAttempt native hook relay", () => {
|
||||
it("rotates native hook relay generations when resume fails over to a fresh thread", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
await writeCurrentCodexAppServerBinding(sessionFile, workspaceDir, {
|
||||
threadId: "thread-existing",
|
||||
cwd: workspaceDir,
|
||||
model: "gpt-5.4-codex",
|
||||
|
||||
@@ -35,33 +35,10 @@ import {
|
||||
turnStartResult,
|
||||
} from "./run-attempt-test-harness.js";
|
||||
import { testing } from "./run-attempt.js";
|
||||
import {
|
||||
readCodexAppServerBinding,
|
||||
resolveCodexAppServerBindingPath,
|
||||
writeCodexAppServerBinding as writeRawCodexAppServerBinding,
|
||||
} from "./session-binding.js";
|
||||
import { readCodexAppServerBinding, resolveCodexAppServerBindingPath } from "./session-binding.js";
|
||||
|
||||
setupRunAttemptTestHooks();
|
||||
|
||||
const DISABLED_CODEX_WEB_SEARCH_THREAD_CONFIG_FINGERPRINT = JSON.stringify({
|
||||
"features.standalone_web_search": false,
|
||||
web_search: "disabled",
|
||||
});
|
||||
|
||||
function writeCodexAppServerBinding(
|
||||
...args: Parameters<typeof writeRawCodexAppServerBinding>
|
||||
) {
|
||||
const [sessionFile, binding, lookup] = args;
|
||||
return writeRawCodexAppServerBinding(
|
||||
sessionFile,
|
||||
{
|
||||
webSearchThreadConfigFingerprint: DISABLED_CODEX_WEB_SEARCH_THREAD_CONFIG_FINGERPRINT,
|
||||
...binding,
|
||||
},
|
||||
lookup,
|
||||
);
|
||||
}
|
||||
|
||||
const tinyPngBase64 =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII=";
|
||||
|
||||
@@ -1100,10 +1077,10 @@ describe("runCodexAppServerAttempt turn watches", () => {
|
||||
});
|
||||
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 20);
|
||||
setTimeout(resolve, 250);
|
||||
});
|
||||
expect(settled).toBe(false);
|
||||
expect(request.mock.calls.some(([method]) => method === "turn/interrupt")).toBe(false);
|
||||
expect(settled).toBe(true);
|
||||
expect(request.mock.calls.some(([method]) => method === "turn/interrupt")).toBe(true);
|
||||
|
||||
const result = await run;
|
||||
expect(result.aborted).toBe(true);
|
||||
@@ -3010,21 +2987,27 @@ describe("runCodexAppServerAttempt turn watches", () => {
|
||||
vi.spyOn(embeddedAgentLog, "warn").mockImplementation(() => undefined);
|
||||
const sessionFile = path.join(tempDir, "session-89974.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace-89974");
|
||||
await writeCodexAppServerBinding(sessionFile, {
|
||||
threadId: "thread-existing",
|
||||
cwd: workspaceDir,
|
||||
model: "gpt-5.4-codex",
|
||||
modelProvider: "openai",
|
||||
dynamicToolsFingerprint: "[]",
|
||||
const setupHarness = createStartedThreadHarness(async (method) => {
|
||||
if (method === "thread/start") {
|
||||
return threadStartResult("thread-existing");
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const setupRun = runCodexAppServerAttempt(createParams(sessionFile, workspaceDir));
|
||||
await setupHarness.waitForMethod("turn/start");
|
||||
await setupHarness.completeTurn({ threadId: "thread-existing", turnId: "turn-1" });
|
||||
await setupRun;
|
||||
|
||||
// Turn 1: resume an existing thread, then never deliver turn/completed.
|
||||
const firstHarness = createResumeHarness();
|
||||
const firstHarness = createResumeHarness("thread-existing");
|
||||
const firstParams = createParams(sessionFile, workspaceDir);
|
||||
firstParams.timeoutMs = 200;
|
||||
const firstRun = runCodexAppServerAttempt(firstParams, { turnCompletionIdleTimeoutMs: 15 });
|
||||
await firstHarness.waitForMethod("turn/start");
|
||||
expect(firstHarness.requests.some((entry) => entry.method === "thread/resume")).toBe(true);
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 250);
|
||||
});
|
||||
|
||||
const firstResult = await firstRun;
|
||||
expect(firstResult.timedOut).toBe(true);
|
||||
|
||||
@@ -101,6 +101,7 @@ export type CodexContextEngineThreadBootstrapProjection = {
|
||||
|
||||
export type CodexPluginThreadConfigProvider = {
|
||||
enabled: boolean;
|
||||
codexPluginsEnabled?: boolean;
|
||||
inputFingerprint?: string;
|
||||
enabledPluginConfigKeys?: readonly string[];
|
||||
build: () => Promise<CodexPluginThreadConfig>;
|
||||
@@ -526,7 +527,10 @@ export async function startOrResumeThread(params: {
|
||||
}
|
||||
if (binding?.threadId) {
|
||||
let pluginBindingStale = isCodexPluginThreadBindingStale({
|
||||
codexPluginsEnabled: params.pluginThreadConfig?.enabled ?? false,
|
||||
codexPluginsEnabled:
|
||||
params.pluginThreadConfig?.codexPluginsEnabled ??
|
||||
params.pluginThreadConfig?.enabled ??
|
||||
false,
|
||||
bindingFingerprint: binding.pluginAppsFingerprint,
|
||||
bindingInputFingerprint: binding.pluginAppsInputFingerprint,
|
||||
currentInputFingerprint: params.pluginThreadConfig?.inputFingerprint,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Cohere provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/comfy-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw ComfyUI provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/copilot-proxy",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Copilot Proxy provider plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/copilot/npm-shrinkwrap.json
generated
4
extensions/copilot/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/copilot",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/copilot",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@github/copilot-sdk": "1.0.0-beta.9"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/copilot",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"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)",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,10 +25,10 @@
|
||||
"minHostVersion": ">=2026.5.28"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepgram-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Deepgram media-understanding provider",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepinfra-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw DeepInfra provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepseek-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw DeepSeek provider plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/diagnostics-otel/npm-shrinkwrap.json
generated
4
extensions/diagnostics-otel/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-otel",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diagnostics-otel",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "1.9.1",
|
||||
"@opentelemetry/api-logs": "0.219.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-otel",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw diagnostics OpenTelemetry exporter for metrics and traces.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -34,10 +34,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.6.8"
|
||||
"version": "2026.6.9-alpha.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw diagnostics Prometheus exporter for runtime metrics.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/diffs-language-pack",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diffs-language-pack",
|
||||
"version": "2026.6.8"
|
||||
"version": "2026.6.9-alpha.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diffs-language-pack",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw diffs viewer syntax highlighting language pack",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -22,13 +22,13 @@
|
||||
"minHostVersion": ">=2026.5.27"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"assetScripts": {
|
||||
"build": "node ../../scripts/build-diffs-viewer-runtime.mjs full"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./assets/viewer-runtime.js",
|
||||
|
||||
4
extensions/diffs/npm-shrinkwrap.json
generated
4
extensions/diffs/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/diffs",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diffs",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@pierre/diffs": "1.2.4",
|
||||
"@pierre/theme": "1.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diffs",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw read-only diff viewer plugin and file renderer for agents.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -29,13 +29,13 @@
|
||||
"minHostVersion": ">=2026.4.30"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"assetScripts": {
|
||||
"build": "node ../../scripts/build-diffs-viewer-runtime.mjs curated"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8",
|
||||
"openclawVersion": "2026.6.9-alpha.6",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./assets/viewer-runtime.js",
|
||||
|
||||
6
extensions/discord/npm-shrinkwrap.json
generated
6
extensions/discord/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/discord",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/discord",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@discordjs/voice": "0.19.2",
|
||||
"discord-api-types": "0.38.48",
|
||||
@@ -16,7 +16,7 @@
|
||||
"ws": "8.21.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/discord",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Discord channel plugin for channels, DMs, commands, and app events.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -20,7 +20,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -67,10 +67,10 @@
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/document-extract-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw local document extraction plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/duckduckgo-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw DuckDuckGo plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/elevenlabs-speech",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw ElevenLabs speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/exa-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Exa plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/fal-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw fal provider plugin",
|
||||
"type": "module",
|
||||
|
||||
6
extensions/feishu/npm-shrinkwrap.json
generated
6
extensions/feishu/npm-shrinkwrap.json
generated
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "@openclaw/feishu",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/feishu",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@larksuiteoapi/node-sdk": "1.66.0",
|
||||
"typebox": "1.1.39",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/feishu",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -17,7 +17,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -51,10 +51,10 @@
|
||||
"minHostVersion": ">=2026.5.29"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/file-transfer",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw file transfer plugin (file_fetch, dir_list, dir_fetch, file_write)",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/firecrawl-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Firecrawl plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/fireworks-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Fireworks provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/github-copilot-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw GitHub Copilot provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/gmi-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw GMI Cloud provider plugin",
|
||||
"type": "module",
|
||||
|
||||
6
extensions/google-meet/npm-shrinkwrap.json
generated
6
extensions/google-meet/npm-shrinkwrap.json
generated
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"name": "@openclaw/google-meet",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/google-meet",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"commander": "14.0.3",
|
||||
"typebox": "1.1.39"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/google-meet",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Google Meet participant plugin for joining calls through Chrome or Twilio transports.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -16,7 +16,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -33,10 +33,10 @@
|
||||
"minHostVersion": ">=2026.4.20"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/google-plugin",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Google plugin",
|
||||
"type": "module",
|
||||
|
||||
6
extensions/googlechat/npm-shrinkwrap.json
generated
6
extensions/googlechat/npm-shrinkwrap.json
generated
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "@openclaw/googlechat",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/googlechat",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"gaxios": "7.1.4",
|
||||
"google-auth-library": "10.6.2",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/googlechat",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Google Chat channel plugin for spaces and direct messages.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -17,7 +17,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -75,10 +75,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/gradium-speech",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Gradium speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/groq-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Groq media-understanding provider",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/huggingface-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Hugging Face provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/image-generation-core",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw image generation runtime package",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/imessage",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw iMessage channel plugin using imsg on a signed-in Mac",
|
||||
"type": "module",
|
||||
@@ -43,10 +43,10 @@
|
||||
]
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
}
|
||||
},
|
||||
"pluginInspector": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/inworld-speech",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Inworld speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/irc",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw IRC channel plugin",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/kilocode-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Kilo Gateway provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/kimi-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw Kimi provider plugin",
|
||||
"type": "module",
|
||||
|
||||
6
extensions/line/npm-shrinkwrap.json
generated
6
extensions/line/npm-shrinkwrap.json
generated
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@line/bot-sdk": "11.0.1",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw LINE channel plugin for LINE Bot API chats.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -16,7 +16,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -46,10 +46,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/litellm-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw LiteLLM provider plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/llama-cpp/npm-shrinkwrap.json
generated
4
extensions/llama-cpp/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/llama-cpp-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/llama-cpp-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"node-llama-cpp": "3.18.1"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/llama-cpp-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw llama.cpp embedding provider plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -23,10 +23,10 @@
|
||||
"minHostVersion": ">=2026.6.2"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"bundleRuntimeDependencies": false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/llm-task",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw JSON-only LLM task plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/lmstudio-provider",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw LM Studio provider plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/lobster/npm-shrinkwrap.json
generated
4
extensions/lobster/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/lobster",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/lobster",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@clawdbot/lobster": "2026.5.22",
|
||||
"typebox": "1.1.39"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/lobster",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "Lobster workflow tool plugin for typed pipelines and resumable approvals.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -24,10 +24,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 2026.6.9-alpha.6
|
||||
|
||||
### Changes
|
||||
|
||||
- Version alignment with core OpenClaw release numbers.
|
||||
|
||||
## 2026.6.8
|
||||
|
||||
### Changes
|
||||
|
||||
6
extensions/matrix/npm-shrinkwrap.json
generated
6
extensions/matrix/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/matrix",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/matrix",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@matrix-org/matrix-sdk-crypto-nodejs": "0.6.0",
|
||||
"@matrix-org/matrix-sdk-crypto-wasm": "18.3.0",
|
||||
@@ -18,7 +18,7 @@
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/matrix",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Matrix channel plugin for rooms and direct messages.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -22,7 +22,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -88,10 +88,10 @@
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/mattermost",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw Mattermost channel plugin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -16,7 +16,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/media-understanding-core",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw media understanding runtime package",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/memory-core",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw core memory search plugin",
|
||||
"type": "module",
|
||||
@@ -14,7 +14,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
4
extensions/memory-lancedb/npm-shrinkwrap.json
generated
4
extensions/memory-lancedb/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/memory-lancedb",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/memory-lancedb",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"dependencies": {
|
||||
"@lancedb/lancedb": "0.30.0",
|
||||
"apache-arrow": "21.1.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/memory-lancedb",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"description": "OpenClaw LanceDB-backed long-term memory plugin with auto-recall, auto-capture, and vector search.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,10 +26,10 @@
|
||||
"minHostVersion": ">=2026.5.31"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.8"
|
||||
"pluginApi": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.8"
|
||||
"openclawVersion": "2026.6.9-alpha.6"
|
||||
},
|
||||
"release": {
|
||||
"bundleRuntimeDependencies": false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/memory-wiki",
|
||||
"version": "2026.6.8",
|
||||
"version": "2026.6.9-alpha.6",
|
||||
"private": true,
|
||||
"description": "OpenClaw persistent wiki plugin",
|
||||
"type": "module",
|
||||
@@ -14,7 +14,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.8"
|
||||
"openclaw": ">=2026.6.9-alpha.6"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user