mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-19 12:52:06 +08:00
Compare commits
94 Commits
release/20
...
qa-fold-ht
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
369f2885d2 | ||
|
|
ab8db1c6b6 | ||
|
|
0ccc78b68d | ||
|
|
68da7fea24 | ||
|
|
33bf13a6e4 | ||
|
|
ae73322774 | ||
|
|
e12cf72b17 | ||
|
|
e9e44bf83c | ||
|
|
843b1d6fbb | ||
|
|
09b56592d2 | ||
|
|
701687efa3 | ||
|
|
d8cc16a3e2 | ||
|
|
7f894ba2be | ||
|
|
e5de09f96a | ||
|
|
2a0e63d12b | ||
|
|
e3bab80bda | ||
|
|
7207072436 | ||
|
|
49e6f5a524 | ||
|
|
95c87e31e2 | ||
|
|
0d2102d247 | ||
|
|
55323103b9 | ||
|
|
239b4de6af | ||
|
|
a7b52ecad9 | ||
|
|
bb44c5326e | ||
|
|
4764258b3f | ||
|
|
6af1b97b1d | ||
|
|
4ca0e52d0e | ||
|
|
37eea55afa | ||
|
|
ea76a45917 | ||
|
|
84bcdaa983 | ||
|
|
4ac192deef | ||
|
|
3c9cf2d583 | ||
|
|
c4ae2be947 | ||
|
|
27310bfa34 | ||
|
|
fbc12e0879 | ||
|
|
73cdb78a1e | ||
|
|
0df60ad306 | ||
|
|
9928516a78 | ||
|
|
7845182410 | ||
|
|
aba6f7ad21 | ||
|
|
5570a10bf4 | ||
|
|
98857235d5 | ||
|
|
39e9336d40 | ||
|
|
392f5b75bf | ||
|
|
a98bfdb2b7 | ||
|
|
34d402f53c | ||
|
|
1faf8175e4 | ||
|
|
fdb042b9ce | ||
|
|
d5a27b0b96 | ||
|
|
9328f4a675 | ||
|
|
75df29c215 | ||
|
|
bf8ac0d96d | ||
|
|
bfb47a03b3 | ||
|
|
a93fc87e2c | ||
|
|
cc3d346c15 | ||
|
|
a8d60d352e | ||
|
|
1bfa2787b5 | ||
|
|
e385f6663a | ||
|
|
76bdb025d6 | ||
|
|
d2e36a176d | ||
|
|
b637414871 | ||
|
|
aa39600793 | ||
|
|
61b116d597 | ||
|
|
033162f209 | ||
|
|
dfd8a2220b | ||
|
|
74ad4f592a | ||
|
|
a14b1e05e5 | ||
|
|
8b63a3d551 | ||
|
|
f4e9a6e047 | ||
|
|
2ae84f75ef | ||
|
|
dca17477dc | ||
|
|
7f1fa65399 | ||
|
|
b6a06f0e49 | ||
|
|
9501d4dec2 | ||
|
|
d9397e5b9b | ||
|
|
d9d7766a41 | ||
|
|
0771ac8563 | ||
|
|
906174bff1 | ||
|
|
c677424edb | ||
|
|
ea4ddb2eb5 | ||
|
|
f19c5f6b2f | ||
|
|
1e83f42a64 | ||
|
|
4c9b4c32ef | ||
|
|
4fc5cf4579 | ||
|
|
8f8162704d | ||
|
|
f381dca15b | ||
|
|
9ab9469d04 | ||
|
|
a2f5ac82d5 | ||
|
|
7b7e40cb0e | ||
|
|
e1c2926628 | ||
|
|
cebe5cb94a | ||
|
|
0b14724c87 | ||
|
|
e879a67bf7 | ||
|
|
53bb55e023 |
@@ -1,44 +1,34 @@
|
||||
---
|
||||
name: channel-message-flows
|
||||
description: "Use when previewing local channel message flow fixtures."
|
||||
description: "Use when running QA Lab channel message flow evidence."
|
||||
---
|
||||
|
||||
# Channel Message Flows
|
||||
|
||||
Use this from the OpenClaw repo root to send canned channel preview flows while iterating on message UX. These are real sends/edits/deletes against the configured channel target.
|
||||
Use this from the OpenClaw repo root to run the QA Lab evidence for Telegram
|
||||
draft/final delivery sequencing. This skill no longer launches a standalone
|
||||
script; the behavior is owned by the QA scenario and its Vitest-backed e2e test.
|
||||
|
||||
## Telegram
|
||||
## QA Scenario
|
||||
|
||||
Native Telegram `sendMessageDraft` tool progress, then a final answer:
|
||||
Run the scenario through QA Lab:
|
||||
|
||||
```bash
|
||||
node --import tsx scripts/dev/channel-message-flows.ts \
|
||||
--channel telegram \
|
||||
--target <telegram-chat-id> \
|
||||
--flow working-final \
|
||||
--duration-ms 20000
|
||||
pnpm openclaw qa suite --scenario channel-message-flows
|
||||
```
|
||||
|
||||
Thinking preview, then a final answer:
|
||||
Run the focused e2e test directly in a Codex worktree:
|
||||
|
||||
```bash
|
||||
node --import tsx scripts/dev/channel-message-flows.ts \
|
||||
--channel telegram \
|
||||
--target <telegram-chat-id> \
|
||||
--flow thinking-final
|
||||
node scripts/run-vitest.mjs extensions/telegram/src/channel-message-flows.qa.e2e.test.ts
|
||||
```
|
||||
|
||||
## Options
|
||||
## References
|
||||
|
||||
- `--account <accountId>`: Telegram account id when not using the default.
|
||||
- `--thread-id <id>`: Telegram forum topic/message thread id.
|
||||
- `--delay-ms <ms>`: Override preview update cadence.
|
||||
- `--duration-ms <ms>`: Simulated working duration for `working-final`.
|
||||
- `--final-text <text>`: Override the durable final message.
|
||||
- `qa/scenarios/channels/channel-message-flows.yaml`
|
||||
- `extensions/telegram/src/channel-message-flows.qa.e2e.test.ts`
|
||||
- `extensions/telegram/src/test-support/channel-message-flows.ts`
|
||||
|
||||
## Notes
|
||||
|
||||
- `--target` is the numeric Telegram chat id.
|
||||
- `working-final` exercises native Telegram `sendMessageDraft` with static `Working` status and sample tool progress.
|
||||
- `thinking-final` exercises formatted `Thinking` reasoning preview clearing before the final answer.
|
||||
- Only `--channel telegram` is implemented for now.
|
||||
The scenario covers `channels.streaming` as primary evidence and records
|
||||
secondary coverage for thread preservation, delivery ordering, and reasoning
|
||||
preview visibility.
|
||||
|
||||
@@ -16,11 +16,8 @@ This skill owns the operational workflow for:
|
||||
|
||||
- `taxonomy.yaml`
|
||||
- `docs/maturity-scores.yaml`
|
||||
- `docs/maturity-scorecard.md`
|
||||
- `docs/taxonomy.md`
|
||||
- `docs/taxonomy-outline.md`
|
||||
- `scripts/render-maturity-docs.mjs`
|
||||
- `.github/workflows/maturity-scorecard.yml`
|
||||
- `docs/concepts/qa-e2e-automation.md`
|
||||
- `qa/scenarios/index.yaml`
|
||||
|
||||
Keep person-specific, maintainer-private, Discord archive, and discrawl facts
|
||||
out of this repo. If a score needs private evidence, use the redacted
|
||||
@@ -31,12 +28,21 @@ out of this repo. If a score needs private evidence, use the redacted
|
||||
- `taxonomy.yaml` is the hand-edited source of truth for surfaces, levels,
|
||||
QA profiles, categories, feature coverage IDs, docs refs, LTS overrides, and
|
||||
completeness-instruction paths.
|
||||
- Feature `coverageIds` are ANDed proof targets, not aliases. A feature may
|
||||
list multiple IDs when each ID proves part of one capability.
|
||||
- Coverage IDs use dotted `namespace.behavior` form, with lowercase
|
||||
alphanumeric/dash segments. Profile, surface, and category IDs may remain
|
||||
dashed or dotted.
|
||||
- Keep categories and feature names unique, product-shaped, and broader than raw
|
||||
coverage IDs. Do not promote generic IDs into standalone feature names.
|
||||
- Avoid duplicate coverage-ID bundles under different feature names in one
|
||||
category.
|
||||
- `docs/maturity-scores.yaml` is the aggregate score source committed in this
|
||||
repo. It is the only committed score data; do not add generated inventory
|
||||
directories.
|
||||
- `docs/maturity-scorecard.md`, `docs/taxonomy.md`, and
|
||||
`docs/taxonomy-outline.md` are deterministic docs generated from the root
|
||||
taxonomy and aggregate score source.
|
||||
- There is no committed maturity-doc renderer or `pnpm maturity:*` script in
|
||||
this repo. Do not invent generated scorecard files; update the source YAML
|
||||
and current docs directly.
|
||||
- `qa-evidence.json` artifacts provide per-run QA scorecard evidence. They can
|
||||
enrich generated artifact docs, but they are not committed as inventory.
|
||||
|
||||
@@ -44,22 +50,28 @@ out of this repo. If a score needs private evidence, use the redacted
|
||||
|
||||
Run from the openclaw repo root.
|
||||
|
||||
Render committed docs:
|
||||
Validate YAML structure after source edits:
|
||||
|
||||
```bash
|
||||
pnpm maturity:render
|
||||
node <<'NODE'
|
||||
const fs = require("node:fs");
|
||||
const YAML = require("yaml");
|
||||
for (const file of ["taxonomy.yaml", "docs/maturity-scores.yaml", "qa/scenarios/index.yaml"]) {
|
||||
YAML.parse(fs.readFileSync(file, "utf8"));
|
||||
}
|
||||
NODE
|
||||
```
|
||||
|
||||
Check generated docs are current:
|
||||
Check docs when touching docs prose:
|
||||
|
||||
```bash
|
||||
pnpm maturity:check
|
||||
pnpm check:docs
|
||||
```
|
||||
|
||||
Render an evidence-enriched docs artifact from downloaded QA artifacts:
|
||||
Run focused QA/profile checks when changing coverage IDs or profile membership:
|
||||
|
||||
```bash
|
||||
pnpm maturity:render -- --evidence-dir .artifacts/maturity-evidence --output-dir .artifacts/maturity-docs
|
||||
pnpm openclaw qa coverage --json
|
||||
```
|
||||
|
||||
## Scoring Workflow
|
||||
@@ -75,13 +87,13 @@ When asked to score or refresh a surface:
|
||||
discrawl or unredacted private archives.
|
||||
5. Update `docs/maturity-scores.yaml` only when the score change is backed by
|
||||
public or redacted artifact evidence.
|
||||
6. Run `pnpm maturity:render`.
|
||||
7. Run `pnpm maturity:check`.
|
||||
6. Run the YAML validation command from this skill.
|
||||
7. Run `pnpm check:docs` if docs prose changed, and focused QA coverage checks
|
||||
if coverage IDs or profile membership changed.
|
||||
|
||||
For subjective score changes, make the smallest defensible edit and leave the
|
||||
evidence path in the PR or task summary. The deterministic renderer owns
|
||||
Markdown structure; manual prose tweaks belong in taxonomy, score source, or
|
||||
the renderer rather than in generated docs.
|
||||
evidence path in the PR or task summary. Keep manual prose in current docs and
|
||||
keep score data in `docs/maturity-scores.yaml`.
|
||||
|
||||
## Default Completeness Process
|
||||
|
||||
@@ -158,13 +170,9 @@ Bands:
|
||||
- `Alpha`: 50-70
|
||||
- `Experimental`: 0-50
|
||||
|
||||
## GitHub Action
|
||||
|
||||
The `Maturity scorecard` workflow verifies committed generated docs on PRs and
|
||||
pushes. Manual dispatch can also download QA artifacts from another workflow run
|
||||
with `source_run_id` and `artifact_pattern`, render evidence-enriched docs into
|
||||
`.artifacts/maturity-docs`, and upload them as a GitHub artifact.
|
||||
## Artifacts
|
||||
|
||||
Do not add the maintainer repo's `docs/kevinslin/maturity-scorecard/inventory/`
|
||||
tree to openclaw. Those generated reports are intentionally replaced here by
|
||||
short-lived artifact docs and the committed aggregate scorecard pages.
|
||||
tree to openclaw. Evidence-enriched scorecard outputs belong in short-lived
|
||||
artifacts, not committed generated docs, unless this repo adds an explicit
|
||||
renderer/check workflow first.
|
||||
|
||||
@@ -2000,7 +2000,7 @@ jobs:
|
||||
profiles: stable full
|
||||
- suite_id: native-live-src-gateway-profiles-minimax
|
||||
label: Native live gateway profiles MiniMax
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M2.7,minimax-portal/MiniMax-M2.7 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M3,minimax-portal/MiniMax-M3 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 node .release-harness/scripts/test-live-shard.mjs native-live-src-gateway-profiles
|
||||
timeout_minutes: 60
|
||||
profile_env_only: false
|
||||
profiles: stable full
|
||||
@@ -2303,7 +2303,7 @@ jobs:
|
||||
profiles: stable full
|
||||
- suite_id: live-gateway-minimax-docker
|
||||
label: Docker live gateway MiniMax
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M2.7,minimax-portal/MiniMax-M2.7 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=2 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
command: OPENCLAW_LIVE_GATEWAY_PROVIDERS=minimax,minimax-portal OPENCLAW_LIVE_GATEWAY_MODELS=minimax/MiniMax-M3,minimax-portal/MiniMax-M3 OPENCLAW_LIVE_GATEWAY_MAX_MODELS=1 OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=90000 OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=180000 OPENCLAW_LIVE_DOCKER_REPO_ROOT="$GITHUB_WORKSPACE" timeout --foreground --kill-after=30s 35m bash .release-harness/scripts/test-live-gateway-models-docker.sh
|
||||
timeout_minutes: 40
|
||||
profile_env_only: false
|
||||
profiles: stable full
|
||||
|
||||
4
.github/workflows/openclaw-performance.yml
vendored
4
.github/workflows/openclaw-performance.yml
vendored
@@ -45,7 +45,7 @@ on:
|
||||
kova_ref:
|
||||
description: openclaw/Kova Git ref to install
|
||||
required: false
|
||||
default: 4f146016583018bad9e24f8e64a6af5f963bb7ee
|
||||
default: b63b6f9e20efb23641df00487e982230d81a90ac
|
||||
type: string
|
||||
dispatch_id:
|
||||
description: Optional parent workflow dispatch identifier
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
live: "true"
|
||||
include_filters: "scenario:agent-cold-warm-message"
|
||||
env:
|
||||
KOVA_REF: ${{ inputs.kova_ref || '4f146016583018bad9e24f8e64a6af5f963bb7ee' }}
|
||||
KOVA_REF: ${{ inputs.kova_ref || 'b63b6f9e20efb23641df00487e982230d81a90ac' }}
|
||||
KOVA_HOME: ${{ github.workspace }}/.artifacts/kova/home/${{ matrix.lane }}
|
||||
PERFORMANCE_HELPER_DIR: ${{ github.workspace }}/.artifacts/performance-workflow
|
||||
REPORT_DIR: ${{ github.workspace }}/.artifacts/kova/reports/${{ matrix.lane }}
|
||||
|
||||
15
.github/workflows/windows-testbox-probe.yml
vendored
15
.github/workflows/windows-testbox-probe.yml
vendored
@@ -85,12 +85,22 @@ jobs:
|
||||
env:
|
||||
ENABLE_WSL2_FEATURES: ${{ inputs.enable_wsl2_features }}
|
||||
IMPORT_UBUNTU_WSL2: ${{ inputs.import_ubuntu_wsl2 }}
|
||||
UBUNTU_WSL_ROOTFS_URL: https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-amd64-wsl.rootfs.tar.gz
|
||||
run: |
|
||||
$ErrorActionPreference = "Continue"
|
||||
$ok = $false
|
||||
$restartRequired = $false
|
||||
|
||||
function Resolve-UbuntuWslRootfsUrl {
|
||||
$osArch = ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture).ToString().ToLowerInvariant()
|
||||
switch ($osArch) {
|
||||
"x64" { $wslArch = "amd64" }
|
||||
"arm64" { $wslArch = "arm64" }
|
||||
default { throw "Unsupported Windows architecture for Ubuntu WSL rootfs: $osArch" }
|
||||
}
|
||||
Write-Host "ubuntu_wsl_rootfs_arch=$wslArch"
|
||||
"https://cloud-images.ubuntu.com/wsl/releases/24.04/current/ubuntu-noble-wsl-$wslArch-wsl.rootfs.tar.gz"
|
||||
}
|
||||
|
||||
function Invoke-WslText {
|
||||
param([string[]] $Arguments)
|
||||
$output = & wsl.exe @Arguments 2>&1
|
||||
@@ -143,8 +153,9 @@ jobs:
|
||||
Write-Host "import_ubuntu_wsl2=true"
|
||||
$wslRoot = "C:\wsl\UbuntuProbe"
|
||||
$rootfs = "C:\wsl\ubuntu-noble-wsl.rootfs.tar.gz"
|
||||
$rootfsUrl = Resolve-UbuntuWslRootfsUrl
|
||||
New-Item -ItemType Directory -Force -Path @((Split-Path -Parent $rootfs), $wslRoot) | Out-Null
|
||||
Invoke-WebRequest -Uri $env:UBUNTU_WSL_ROOTFS_URL -OutFile $rootfs -UseBasicParsing
|
||||
Invoke-WebRequest -Uri $rootfsUrl -OutFile $rootfs -UseBasicParsing
|
||||
$import = Invoke-WslText -Arguments @("--import", "UbuntuProbe", $wslRoot, $rootfs, "--version", "2")
|
||||
Write-Host $import.Text
|
||||
Write-Host "wsl_import_exit=$($import.Code)"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
dd892e0085aa61eb8b85f3e6591039accc9a051af923874499f196ee621c5545 plugin-sdk-api-baseline.json
|
||||
2ea01cb391f2adc0e1d59400bf245e8e9f110a37d961546e0c7d6685c4054400 plugin-sdk-api-baseline.jsonl
|
||||
f24065e760a9fafbd2a50962beba4d752b2d6166043170d37cdd6137640e7eef plugin-sdk-api-baseline.json
|
||||
89a332c206f639d5faef730bac2d23f75751b306419e5dfeae1b731166bbc41c plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -57,6 +57,11 @@ the resolved scenarios through `qa suite`. `--surface` and
|
||||
The resulting `qa-evidence.json` includes a profile scorecard summary with
|
||||
selected-category counts and missing coverage IDs; the individual evidence
|
||||
entries remain the source of truth for the tests, coverage roles, and results.
|
||||
Taxonomy feature coverage IDs are exact proof targets, not aliases. Primary
|
||||
scenario coverage fulfills matching IDs; secondary coverage stays advisory.
|
||||
Coverage IDs use dotted `namespace.behavior` form with lowercase
|
||||
alphanumeric/dash segments; profile, surface, and category IDs may still use
|
||||
the existing dashed or dotted taxonomy IDs.
|
||||
Slim evidence omits per-entry `execution` and sets `evidenceMode: "slim"`;
|
||||
`smoke-ci` defaults to slim, and `--evidence-mode full` restores full entries:
|
||||
|
||||
|
||||
4
extensions/acpx/npm-shrinkwrap.json
generated
4
extensions/acpx/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./src/runtime-internals/mcp-proxy.mjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/admin-http-rpc",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw admin HTTP RPC endpoint",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/alibaba-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/amazon-bedrock-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/anthropic-vertex-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/vertex-sdk": "0.16.1"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-vertex-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/anthropic-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw Anthropic provider plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/arcee/npm-shrinkwrap.json
generated
4
extensions/arcee/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/arcee-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/arcee-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/arcee-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Arcee provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/azure-speech",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw Azure Speech plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/bonjour",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/brave-plugin",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/brave-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Brave Search provider plugin for web search.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/browser-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw browser tool plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/byteplus-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw BytePlus provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/canvas-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw Canvas plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/cerebras/npm-shrinkwrap.json
generated
4
extensions/cerebras/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/cerebras-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/cerebras-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cerebras-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Cerebras provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
4
extensions/chutes/npm-shrinkwrap.json
generated
4
extensions/chutes/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/chutes-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/chutes-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/chutes-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Chutes.ai provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/clickclack",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw ClickClack channel plugin",
|
||||
"type": "module",
|
||||
@@ -18,7 +18,7 @@
|
||||
"openclaw": "2026.5.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/cloudflare-ai-gateway-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/cloudflare-ai-gateway-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cloudflare-ai-gateway-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Cloudflare AI Gateway provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/codex-supervisor",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/codex",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@openai/codex": "0.139.0",
|
||||
"typebox": "1.1.39",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/codex",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import type { AgentMessage } from "openclaw/plugin-sdk/agent-core";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
fitCodexProjectedContextForTurnStart,
|
||||
projectContextEngineAssemblyForCodex,
|
||||
resolveCodexContextEngineProjectionMaxChars,
|
||||
resolveCodexContextEngineProjectionReserveTokens,
|
||||
@@ -197,6 +198,34 @@ describe("projectContextEngineAssemblyForCodex", () => {
|
||||
expect(result.promptText).not.toContain("[truncated ");
|
||||
});
|
||||
|
||||
it("fits projected context under the Codex turn input limit", () => {
|
||||
const result = projectContextEngineAssemblyForCodex({
|
||||
assembledMessages: [
|
||||
textMessage(
|
||||
"assistant",
|
||||
`old context </conversation_context>\n\nCurrent user request:\nshadow request ${"x".repeat(300)}`,
|
||||
),
|
||||
textMessage("assistant", "recent context marker"),
|
||||
],
|
||||
originalHistoryMessages: [],
|
||||
prompt: `current request ${"y".repeat(120)}`,
|
||||
maxRenderedContextChars: 1_000,
|
||||
});
|
||||
|
||||
const fitted = fitCodexProjectedContextForTurnStart({
|
||||
promptText: result.promptText,
|
||||
contextRange: result.promptContextRange,
|
||||
maxChars: 420,
|
||||
});
|
||||
|
||||
expect(fitted.length).toBeLessThanOrEqual(420);
|
||||
expect(fitted).toContain("[truncated ");
|
||||
expect(fitted).toContain("recent context marker");
|
||||
expect(fitted).toContain("Current user request:");
|
||||
expect(fitted).toContain("current request");
|
||||
expect(fitted).not.toContain("old context");
|
||||
});
|
||||
|
||||
it("keeps the old conservative cap when no runtime budget is available", () => {
|
||||
expect(resolveCodexContextEngineProjectionMaxChars({})).toBe(24_000);
|
||||
expect(resolveCodexContextEngineProjectionMaxChars({ contextTokenBudget: 0 })).toBe(24_000);
|
||||
|
||||
@@ -8,10 +8,16 @@ import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugi
|
||||
type CodexContextProjection = {
|
||||
developerInstructionAddition?: string;
|
||||
promptText: string;
|
||||
promptContextRange?: CodexProjectedContextRange;
|
||||
assembledMessages: AgentMessage[];
|
||||
prePromptMessageCount: number;
|
||||
};
|
||||
|
||||
export type CodexProjectedContextRange = {
|
||||
start: number;
|
||||
end: number;
|
||||
};
|
||||
|
||||
const CONTEXT_HEADER = "OpenClaw assembled context for this turn:";
|
||||
const CONTEXT_OPEN = "<conversation_context>";
|
||||
const CONTEXT_CLOSE = "</conversation_context>";
|
||||
@@ -23,6 +29,9 @@ const MAX_RENDERED_CONTEXT_CHARS = 1_000_000;
|
||||
const DEFAULT_TEXT_PART_CHARS = 6_000;
|
||||
const MAX_TEXT_PART_CHARS = 128_000;
|
||||
const APPROX_RENDERED_CHARS_PER_TOKEN = 4;
|
||||
// Codex app-server validates the summed v2 turn/start text input against
|
||||
// codex-rs/protocol/src/user_input.rs::MAX_USER_INPUT_TEXT_CHARS.
|
||||
export const CODEX_TURN_START_TEXT_INPUT_MAX_CHARS = 1 << 20;
|
||||
/** Default token reserve kept out of rendered context-engine prompt text. */
|
||||
export const DEFAULT_CODEX_PROJECTION_RESERVE_TOKENS = 20_000;
|
||||
const MIN_PROMPT_BUDGET_RATIO = 0.5;
|
||||
@@ -44,25 +53,25 @@ export function projectContextEngineAssemblyForCodex(params: {
|
||||
maxTextPartChars: resolveTextPartMaxChars(maxRenderedContextChars),
|
||||
toolPayloadMode: params.toolPayloadMode ?? "elide",
|
||||
});
|
||||
const promptText = renderedContext
|
||||
? [
|
||||
CONTEXT_HEADER,
|
||||
CONTEXT_SAFETY_NOTE,
|
||||
"",
|
||||
CONTEXT_OPEN,
|
||||
truncateOlderContext(renderedContext, maxRenderedContextChars),
|
||||
CONTEXT_CLOSE,
|
||||
"",
|
||||
REQUEST_HEADER,
|
||||
prompt,
|
||||
].join("\n")
|
||||
: prompt;
|
||||
const boundedContext = renderedContext
|
||||
? truncateOlderContext(renderedContext, maxRenderedContextChars)
|
||||
: undefined;
|
||||
const promptPrefix = boundedContext
|
||||
? [CONTEXT_HEADER, CONTEXT_SAFETY_NOTE, "", CONTEXT_OPEN].join("\n") + "\n"
|
||||
: undefined;
|
||||
const promptSuffix = boundedContext ? `\n${CONTEXT_CLOSE}\n\n${REQUEST_HEADER}\n${prompt}` : "";
|
||||
const promptText = boundedContext ? `${promptPrefix}${boundedContext}${promptSuffix}` : prompt;
|
||||
const promptContextRange =
|
||||
promptPrefix && boundedContext
|
||||
? { start: promptPrefix.length, end: promptPrefix.length + boundedContext.length }
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
...(params.systemPromptAddition?.trim()
|
||||
? { developerInstructionAddition: params.systemPromptAddition.trim() }
|
||||
: {}),
|
||||
promptText,
|
||||
...(promptContextRange ? { promptContextRange } : {}),
|
||||
assembledMessages: params.assembledMessages,
|
||||
prePromptMessageCount: params.originalHistoryMessages.length,
|
||||
};
|
||||
@@ -108,6 +117,50 @@ export function resolveCodexContextEngineProjectionReserveTokens(params: {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Fits projected context prompts under Codex app-server turn/start text limits. */
|
||||
export function fitCodexProjectedContextForTurnStart(params: {
|
||||
promptText: string;
|
||||
contextRange?: CodexProjectedContextRange;
|
||||
maxChars?: number;
|
||||
}): string {
|
||||
const maxChars =
|
||||
typeof params.maxChars === "number" && Number.isFinite(params.maxChars)
|
||||
? Math.max(0, Math.floor(params.maxChars))
|
||||
: CODEX_TURN_START_TEXT_INPUT_MAX_CHARS;
|
||||
if (params.promptText.length <= maxChars) {
|
||||
return params.promptText;
|
||||
}
|
||||
const range = normalizeProjectedContextRange(params.contextRange, params.promptText.length);
|
||||
if (!range) {
|
||||
return params.promptText;
|
||||
}
|
||||
|
||||
const beforeContext = params.promptText.slice(0, range.start);
|
||||
const context = params.promptText.slice(range.start, range.end);
|
||||
const afterContext = params.promptText.slice(range.end);
|
||||
const contextBudget = maxChars - beforeContext.length - afterContext.length;
|
||||
const fittedContext = truncateOlderContext(context, contextBudget);
|
||||
return `${beforeContext}${fittedContext}${afterContext}`;
|
||||
}
|
||||
|
||||
function normalizeProjectedContextRange(
|
||||
range: CodexProjectedContextRange | undefined,
|
||||
textLength: number,
|
||||
): CodexProjectedContextRange | undefined {
|
||||
if (!range) {
|
||||
return undefined;
|
||||
}
|
||||
const start = Math.floor(range.start);
|
||||
const end = Math.floor(range.end);
|
||||
if (!Number.isFinite(start) || !Number.isFinite(end) || start < 0 || end < start) {
|
||||
return undefined;
|
||||
}
|
||||
if (end > textLength) {
|
||||
return undefined;
|
||||
}
|
||||
return { start, end };
|
||||
}
|
||||
|
||||
function resolveProjectionPromptBudgetTokens(params: {
|
||||
contextTokenBudget: number;
|
||||
reserveTokens?: number;
|
||||
|
||||
@@ -158,22 +158,6 @@ function nativeCompletionNotification(params: {
|
||||
};
|
||||
}
|
||||
|
||||
function childTurnCompletedNotification(params: {
|
||||
status: "completed" | "failed" | "interrupted";
|
||||
error?: string;
|
||||
}): CodexServerNotification {
|
||||
return {
|
||||
method: "turn/completed",
|
||||
params: {
|
||||
threadId: "child-thread",
|
||||
turn: {
|
||||
status: params.status,
|
||||
...(params.error ? { error: { message: params.error } } : {}),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("CodexNativeSubagentMonitor", () => {
|
||||
it("keeps native subagent task mirroring alive on the shared client", async () => {
|
||||
const client = createClient();
|
||||
@@ -330,10 +314,12 @@ describe("CodexNativeSubagentMonitor", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("delivers a completed child turn with its final agent message", async () => {
|
||||
it("delivers child agent-message completion when a native subagent becomes idle", async () => {
|
||||
const client = createClient();
|
||||
const runtime = createRuntime();
|
||||
const monitor = new CodexNativeSubagentMonitor(client, runtime);
|
||||
const monitor = new CodexNativeSubagentMonitor(client, runtime, {
|
||||
codexHome: "/tmp/codex-home",
|
||||
});
|
||||
monitor.registerParent({
|
||||
parentThreadId: "parent-thread",
|
||||
requesterSessionKey: "agent:main:discord:channel:C123",
|
||||
@@ -348,10 +334,15 @@ describe("CodexNativeSubagentMonitor", () => {
|
||||
threadId: "child-thread",
|
||||
item: {
|
||||
type: "agentMessage",
|
||||
text: "child in-band final result",
|
||||
id: "msg-child-final",
|
||||
phase: "final_answer",
|
||||
text: "child final result",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(runtime.deliverAgentHarnessTaskCompletion).not.toHaveBeenCalled();
|
||||
|
||||
await client.notify({
|
||||
method: "thread/status/changed",
|
||||
params: {
|
||||
@@ -360,32 +351,31 @@ describe("CodexNativeSubagentMonitor", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(runtime.deliverAgentHarnessTaskCompletion).not.toHaveBeenCalled();
|
||||
await client.notify(childTurnCompletedNotification({ status: "completed" }));
|
||||
|
||||
expect(runtime.finalizeTaskRunByRunId).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
runId: "codex-thread:child-thread",
|
||||
status: "succeeded",
|
||||
terminalSummary: "child in-band final result",
|
||||
terminalSummary: "child final result",
|
||||
}),
|
||||
);
|
||||
expect(runtime.deliverAgentHarnessTaskCompletion).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
childSessionId: "child-thread",
|
||||
status: "succeeded",
|
||||
statusLabel: "turn_completed",
|
||||
result: "child in-band final result",
|
||||
statusLabel: "agent_message",
|
||||
result: "child final result",
|
||||
}),
|
||||
);
|
||||
|
||||
client.close();
|
||||
});
|
||||
|
||||
it("does not turn an interrupted child after a message into success", async () => {
|
||||
it("does not deliver commentary-only child messages as native subagent completion", async () => {
|
||||
const client = createClient();
|
||||
const runtime = createRuntime();
|
||||
const monitor = new CodexNativeSubagentMonitor(client, runtime);
|
||||
const monitor = new CodexNativeSubagentMonitor(client, runtime, {
|
||||
codexHome: "/tmp/codex-home",
|
||||
});
|
||||
monitor.registerParent({
|
||||
parentThreadId: "parent-thread",
|
||||
requesterSessionKey: "agent:main:discord:channel:C123",
|
||||
@@ -400,7 +390,9 @@ describe("CodexNativeSubagentMonitor", () => {
|
||||
threadId: "child-thread",
|
||||
item: {
|
||||
type: "agentMessage",
|
||||
text: "partial child result",
|
||||
id: "msg-child-commentary",
|
||||
phase: "commentary",
|
||||
text: "checking now",
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -411,16 +403,9 @@ describe("CodexNativeSubagentMonitor", () => {
|
||||
status: { type: "idle" },
|
||||
},
|
||||
});
|
||||
await client.notify(childTurnCompletedNotification({ status: "interrupted" }));
|
||||
|
||||
expect(runtime.deliverAgentHarnessTaskCompletion).toHaveBeenCalledTimes(1);
|
||||
expect(runtime.deliverAgentHarnessTaskCompletion).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
childSessionId: "child-thread",
|
||||
status: "cancelled",
|
||||
result: "Codex native subagent was interrupted.",
|
||||
}),
|
||||
);
|
||||
expect(runtime.finalizeTaskRunByRunId).not.toHaveBeenCalled();
|
||||
expect(runtime.deliverAgentHarnessTaskCompletion).not.toHaveBeenCalled();
|
||||
|
||||
client.close();
|
||||
});
|
||||
|
||||
@@ -51,11 +51,14 @@ type ParentState = {
|
||||
type ChildState = {
|
||||
childThreadId: string;
|
||||
parentThreadId: string;
|
||||
lastAssistantMessage?: string;
|
||||
transcriptPath?: string;
|
||||
transcriptPollAttempt: number;
|
||||
transcriptPollTimer?: ReturnType<typeof setTimeout>;
|
||||
transcriptTerminal: boolean;
|
||||
idle: boolean;
|
||||
lastAgentMessage?: string;
|
||||
lastAgentMessageAt?: number;
|
||||
agentMessageCompletionDelivered: boolean;
|
||||
pendingCompletion?: CodexNativeSubagentCompletion;
|
||||
pendingCompletionEventAt?: number;
|
||||
completionDeliveryAttempt: number;
|
||||
@@ -212,9 +215,10 @@ export class CodexNativeSubagentMonitor {
|
||||
});
|
||||
}
|
||||
}
|
||||
this.captureChildAssistantMessage(notification);
|
||||
await this.handleChildTurnCompletion(notification);
|
||||
const childThreadId = this.recordChildAgentMessage(notification);
|
||||
const idleChildThreadId = this.recordChildIdle(notification);
|
||||
await this.handleCompletionNotification(notification);
|
||||
await this.processChildAgentMessageCompletion(childThreadId ?? idleChildThreadId);
|
||||
}
|
||||
|
||||
private ensureParentTaskRuntime(state: ParentState): void {
|
||||
@@ -295,11 +299,7 @@ export class CodexNativeSubagentMonitor {
|
||||
nativeCompletion.agentPath,
|
||||
);
|
||||
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
|
||||
if (
|
||||
!childState ||
|
||||
childState.parentThreadId !== state.parentThreadId ||
|
||||
childState.transcriptTerminal
|
||||
) {
|
||||
if (!childState || childState.parentThreadId !== state.parentThreadId) {
|
||||
embeddedAgentLog.warn(
|
||||
"Ignoring Codex native subagent completion for unknown child thread",
|
||||
{
|
||||
@@ -325,39 +325,6 @@ export class CodexNativeSubagentMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
private captureChildAssistantMessage(notification: CodexServerNotification): void {
|
||||
if (notification.method !== "item/completed") {
|
||||
return;
|
||||
}
|
||||
const params = isJsonObject(notification.params) ? notification.params : undefined;
|
||||
const childThreadId = readString(params, "threadId")?.trim();
|
||||
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
|
||||
const item = isJsonObject(params?.item) ? params.item : undefined;
|
||||
const text =
|
||||
readString(item, "type") === "agentMessage"
|
||||
? normalizeOptionalString(readString(item, "text"))
|
||||
: undefined;
|
||||
if (childState && text) {
|
||||
childState.lastAssistantMessage = text;
|
||||
}
|
||||
}
|
||||
|
||||
private async handleChildTurnCompletion(notification: CodexServerNotification): Promise<void> {
|
||||
if (notification.method !== "turn/completed") {
|
||||
return;
|
||||
}
|
||||
const params = isJsonObject(notification.params) ? notification.params : undefined;
|
||||
const childThreadId = readString(params, "threadId")?.trim();
|
||||
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
|
||||
const state = childState ? this.parentStates.get(childState.parentThreadId) : undefined;
|
||||
const turn = isJsonObject(params?.turn) ? params.turn : undefined;
|
||||
const completion = childState && turn ? toChildTurnCompletion(childState, turn) : undefined;
|
||||
if (!state || !childState || childState.transcriptTerminal || !completion) {
|
||||
return;
|
||||
}
|
||||
await this.processCompletion(state, completion);
|
||||
}
|
||||
|
||||
async reconcileChildTranscript(
|
||||
childThreadId: string,
|
||||
options: { allowTreeScan?: boolean } = {},
|
||||
@@ -592,6 +559,8 @@ export class CodexNativeSubagentMonitor {
|
||||
parentThreadId: normalizedParentThreadId,
|
||||
transcriptPollAttempt: 0,
|
||||
transcriptTerminal: false,
|
||||
idle: false,
|
||||
agentMessageCompletionDelivered: false,
|
||||
completionDeliveryAttempt: 0,
|
||||
};
|
||||
this.childStates.set(normalizedChildThreadId, childState);
|
||||
@@ -601,6 +570,83 @@ export class CodexNativeSubagentMonitor {
|
||||
}
|
||||
}
|
||||
|
||||
private recordChildAgentMessage(notification: CodexServerNotification): string | undefined {
|
||||
if (notification.method !== "item/completed") {
|
||||
return undefined;
|
||||
}
|
||||
const params = isJsonObject(notification.params) ? notification.params : undefined;
|
||||
const item = isJsonObject(params?.item) ? params.item : undefined;
|
||||
if (!params || !item || readString(item, "type") !== "agentMessage") {
|
||||
return undefined;
|
||||
}
|
||||
const childThreadId = readString(params, "threadId")?.trim();
|
||||
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
|
||||
if (!childState || childState.transcriptTerminal) {
|
||||
return undefined;
|
||||
}
|
||||
// Codex app-server can report the child final answer as the child thread's
|
||||
// own agentMessage without also emitting a parent subagent notification.
|
||||
// Pair it with idle below so commentary does not become a false terminal.
|
||||
const phase = readString(item, "phase");
|
||||
if (phase === "commentary") {
|
||||
return undefined;
|
||||
}
|
||||
const text = readString(item, "text")?.trim();
|
||||
if (!text) {
|
||||
return undefined;
|
||||
}
|
||||
childState.lastAgentMessage = text;
|
||||
childState.lastAgentMessageAt = Date.now();
|
||||
return childState.childThreadId;
|
||||
}
|
||||
|
||||
private recordChildIdle(notification: CodexServerNotification): string | undefined {
|
||||
if (notification.method !== "thread/status/changed") {
|
||||
return undefined;
|
||||
}
|
||||
const params = isJsonObject(notification.params) ? notification.params : undefined;
|
||||
if (!params || !isJsonObject(params.status) || readString(params.status, "type") !== "idle") {
|
||||
return undefined;
|
||||
}
|
||||
const childThreadId = readString(params, "threadId")?.trim();
|
||||
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
|
||||
if (!childState || childState.transcriptTerminal) {
|
||||
return undefined;
|
||||
}
|
||||
childState.idle = true;
|
||||
return childState.childThreadId;
|
||||
}
|
||||
|
||||
private async processChildAgentMessageCompletion(
|
||||
childThreadId: string | undefined,
|
||||
): Promise<void> {
|
||||
const childState = childThreadId ? this.childStates.get(childThreadId) : undefined;
|
||||
if (
|
||||
!childState ||
|
||||
!childState.idle ||
|
||||
childState.transcriptTerminal ||
|
||||
childState.agentMessageCompletionDelivered ||
|
||||
!childState.lastAgentMessage
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const state = this.parentStates.get(childState.parentThreadId);
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
childState.agentMessageCompletionDelivered = true;
|
||||
await this.processCompletion(
|
||||
state,
|
||||
{
|
||||
childThreadId: childState.childThreadId,
|
||||
status: "succeeded",
|
||||
statusLabel: "agent_message",
|
||||
result: childState.lastAgentMessage,
|
||||
},
|
||||
childState.lastAgentMessageAt,
|
||||
);
|
||||
}
|
||||
|
||||
private ensureChildState(parentThreadId: string, childThreadId: string): ChildState {
|
||||
this.registerChildThread(parentThreadId, childThreadId);
|
||||
return this.childStates.get(childThreadId.trim())!;
|
||||
@@ -924,50 +970,6 @@ function buildCompletionDedupeKey(
|
||||
return `${parentThreadId}:${completion.childThreadId}:${completion.status}:${hash}`;
|
||||
}
|
||||
|
||||
function toChildTurnCompletion(
|
||||
childState: ChildState,
|
||||
turn: JsonObject,
|
||||
): CodexNativeSubagentCompletion | undefined {
|
||||
const status = readString(turn, "status");
|
||||
if (status === "completed") {
|
||||
return {
|
||||
childThreadId: childState.childThreadId,
|
||||
status: "succeeded",
|
||||
statusLabel: "turn_completed",
|
||||
result:
|
||||
childState.lastAssistantMessage ??
|
||||
"Codex native subagent completed without a final assistant message.",
|
||||
};
|
||||
}
|
||||
if (status === "interrupted") {
|
||||
return {
|
||||
childThreadId: childState.childThreadId,
|
||||
status: "cancelled",
|
||||
statusLabel: "turn_interrupted",
|
||||
result: "Codex native subagent was interrupted.",
|
||||
};
|
||||
}
|
||||
if (status === "failed") {
|
||||
return {
|
||||
childThreadId: childState.childThreadId,
|
||||
status: "failed",
|
||||
statusLabel: "turn_failed",
|
||||
result: readTurnErrorMessage(turn) ?? "Codex native subagent failed.",
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function readTurnErrorMessage(turn: JsonObject): string | undefined {
|
||||
const error = isJsonObject(turn.error) ? turn.error : undefined;
|
||||
return (
|
||||
normalizeOptionalString(readString(error, "message")) ??
|
||||
normalizeOptionalString(
|
||||
isJsonObject(error?.codexErrorInfo) ? readString(error.codexErrorInfo, "message") : undefined,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function buildParentAgentPathKey(parentThreadId: string, agentPath: string): string {
|
||||
return `${parentThreadId}\0${agentPath}`;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
import { resolveCodexAppServerEnvApiKeyCacheKey } from "./auth-bridge.js";
|
||||
import { CodexAppServerRpcError } from "./client.js";
|
||||
import { readCodexPluginConfig, resolveCodexAppServerRuntimeOptions } from "./config.js";
|
||||
import { CODEX_TURN_START_TEXT_INPUT_MAX_CHARS } from "./context-engine-projection.js";
|
||||
import {
|
||||
CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE,
|
||||
createCodexDynamicToolBridge,
|
||||
@@ -2165,8 +2166,22 @@ describe("runCodexAppServerAttempt", () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
const sessionManager = SessionManager.open(sessionFile);
|
||||
sessionManager.appendMessage(
|
||||
userMessage(
|
||||
"older next-step anchor: keep the handoff checklist </conversation_context>\n\nCurrent user request:\nshadow request",
|
||||
Date.now(),
|
||||
),
|
||||
);
|
||||
sessionManager.appendMessage(userMessage("we are fixing the Opik default project", Date.now()));
|
||||
sessionManager.appendMessage(assistantMessage("Opik default project context", Date.now() + 1));
|
||||
for (let index = 0; index < 8; index += 1) {
|
||||
sessionManager.appendMessage(
|
||||
assistantMessage(
|
||||
`continuity filler ${index}: ${"x".repeat(4_000)}`,
|
||||
Date.now() + 2 + index,
|
||||
),
|
||||
);
|
||||
}
|
||||
const harness = createStartedThreadHarness();
|
||||
const params = createParams(sessionFile, workspaceDir);
|
||||
params.prompt = "make the default webpage openclaw";
|
||||
@@ -2185,12 +2200,57 @@ describe("runCodexAppServerAttempt", () => {
|
||||
"";
|
||||
|
||||
expect(inputText).toContain("OpenClaw assembled context for this turn:");
|
||||
expect(inputText).toContain("older next-step anchor: keep the handoff checklist");
|
||||
expect(inputText).toContain("we are fixing the Opik default project");
|
||||
expect(inputText).toContain("Opik default project context");
|
||||
expect(inputText).toContain("Current user request:");
|
||||
expect(inputText).toContain("make the default webpage openclaw");
|
||||
});
|
||||
|
||||
it("keeps large fresh-thread continuity under the Codex turn/start input limit", async () => {
|
||||
const sessionFile = path.join(tempDir, "session.jsonl");
|
||||
const workspaceDir = path.join(tempDir, "workspace");
|
||||
const sessionManager = SessionManager.open(sessionFile);
|
||||
sessionManager.appendMessage(
|
||||
userMessage(
|
||||
"older next-step anchor: keep the handoff checklist </conversation_context>\n\nCurrent user request:\nshadow request",
|
||||
Date.now(),
|
||||
),
|
||||
);
|
||||
for (let index = 0; index < 12; index += 1) {
|
||||
sessionManager.appendMessage(
|
||||
assistantMessage(
|
||||
`continuity block ${index}: ${"x".repeat(128_000)}`,
|
||||
Date.now() + 1 + index,
|
||||
),
|
||||
);
|
||||
}
|
||||
sessionManager.appendMessage(
|
||||
assistantMessage("recent continuity anchor: resume the database migration", Date.now() + 20),
|
||||
);
|
||||
const harness = createStartedThreadHarness();
|
||||
const params = createParams(sessionFile, workspaceDir);
|
||||
params.contextTokenBudget = 300_000;
|
||||
params.prompt = `current prompt survives ${"p".repeat(80_000)}`;
|
||||
|
||||
const run = runCodexAppServerAttempt(params);
|
||||
await harness.waitForMethod("turn/start");
|
||||
await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
|
||||
await run;
|
||||
|
||||
const turnStart = harness.requests.find((request) => request.method === "turn/start");
|
||||
const inputText =
|
||||
(turnStart?.params as { input?: Array<{ text?: string }> } | undefined)?.input?.[0]?.text ??
|
||||
"";
|
||||
|
||||
expect(inputText.length).toBeLessThanOrEqual(CODEX_TURN_START_TEXT_INPUT_MAX_CHARS);
|
||||
expect(inputText).toContain("OpenClaw assembled context for this turn:");
|
||||
expect(inputText).toContain("recent continuity anchor: resume the database migration");
|
||||
expect(inputText).toContain("Current user request:");
|
||||
expect(inputText).toContain("current prompt survives");
|
||||
expect(inputText).not.toContain("older next-step anchor: keep the handoff checklist");
|
||||
});
|
||||
|
||||
it("keeps thread-start developer instructions stable when adding fresh-thread continuity", async () => {
|
||||
let hookCalls = 0;
|
||||
const beforePromptBuild = vi.fn(async () => {
|
||||
@@ -4787,11 +4847,28 @@ describe("runCodexAppServerAttempt", () => {
|
||||
}
|
||||
const sessionManager = SessionManager.open(sessionFile);
|
||||
sessionManager.appendMessage(
|
||||
userMessage("post-binding user context", bindingUpdatedAt + 1_000),
|
||||
userMessage(
|
||||
"pre-binding native-owned context: keep the original plan",
|
||||
bindingUpdatedAt - 2_000,
|
||||
),
|
||||
);
|
||||
sessionManager.appendMessage(
|
||||
userMessage(
|
||||
"post-binding user context: resume the release checklist",
|
||||
bindingUpdatedAt + 1_000,
|
||||
),
|
||||
);
|
||||
sessionManager.appendMessage(
|
||||
assistantMessage("post-binding assistant context", bindingUpdatedAt + 2_000),
|
||||
);
|
||||
for (let index = 0; index < 8; index += 1) {
|
||||
sessionManager.appendMessage(
|
||||
assistantMessage(
|
||||
`post-binding continuity filler ${index}: ${"x".repeat(4_000)}`,
|
||||
bindingUpdatedAt + 3_000 + index,
|
||||
),
|
||||
);
|
||||
}
|
||||
await fs.writeFile(
|
||||
path.join(path.dirname(sessionFile), "sessions.json"),
|
||||
JSON.stringify({
|
||||
@@ -4835,7 +4912,8 @@ describe("runCodexAppServerAttempt", () => {
|
||||
const inputText =
|
||||
(turnStart?.params as { input?: Array<{ text?: string }> } | undefined)?.input?.[0]?.text ??
|
||||
"";
|
||||
expect(inputText).toContain("post-binding user context");
|
||||
expect(inputText).toContain("pre-binding native-owned context: keep the original plan");
|
||||
expect(inputText).toContain("post-binding user context: resume the release checklist");
|
||||
expect(inputText).toContain("post-binding assistant context");
|
||||
const savedBinding = await readCodexAppServerBinding(sessionFile);
|
||||
expect(savedBinding?.threadId).toBe("thread-1");
|
||||
|
||||
@@ -139,6 +139,8 @@ import {
|
||||
type OpenClawExecPolicyForCodexAppServer,
|
||||
} from "./config.js";
|
||||
import {
|
||||
type CodexProjectedContextRange,
|
||||
fitCodexProjectedContextForTurnStart,
|
||||
projectContextEngineAssemblyForCodex,
|
||||
resolveCodexContextEngineProjectionMaxChars,
|
||||
resolveCodexContextEngineProjectionReserveTokens,
|
||||
@@ -896,8 +898,15 @@ export async function runCodexAppServerAttempt(
|
||||
skillsPrompt: params.skillsSnapshot?.prompt,
|
||||
});
|
||||
let promptText = params.prompt;
|
||||
let promptContextRange: CodexProjectedContextRange | undefined;
|
||||
let developerInstructions = baseDeveloperInstructions;
|
||||
let prePromptMessageCount = historyMessages.length;
|
||||
const codexContextProjectionMaxChars = resolveCodexContextEngineProjectionMaxChars({
|
||||
contextTokenBudget: params.contextTokenBudget,
|
||||
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({
|
||||
config: params.config,
|
||||
}),
|
||||
});
|
||||
let contextEngineProjection: CodexContextEngineThreadBootstrapProjection | undefined;
|
||||
let precomputedStaleBindingContinuityProjectionApplied = false;
|
||||
let staleBindingContinuityForcedFreshStart = false;
|
||||
@@ -908,8 +917,10 @@ export async function runCodexAppServerAttempt(
|
||||
assembledMessages: historyMessages,
|
||||
originalHistoryMessages: historyMessages,
|
||||
prompt: params.prompt,
|
||||
maxRenderedContextChars: codexContextProjectionMaxChars,
|
||||
});
|
||||
promptText = projection.promptText;
|
||||
promptContextRange = projection.promptContextRange;
|
||||
prePromptMessageCount = projection.prePromptMessageCount;
|
||||
};
|
||||
const applyActiveContextEngineProjection = async (
|
||||
@@ -949,12 +960,7 @@ export async function runCodexAppServerAttempt(
|
||||
originalHistoryMessages: historyMessages,
|
||||
prompt: params.prompt,
|
||||
systemPromptAddition: assembled.systemPromptAddition,
|
||||
maxRenderedContextChars: resolveCodexContextEngineProjectionMaxChars({
|
||||
contextTokenBudget: params.contextTokenBudget,
|
||||
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({
|
||||
config: params.config,
|
||||
}),
|
||||
}),
|
||||
maxRenderedContextChars: codexContextProjectionMaxChars,
|
||||
toolPayloadMode: contextEngineProjection ? "preserve" : "elide",
|
||||
});
|
||||
const projectionDecision = contextEngineProjection
|
||||
@@ -986,6 +992,7 @@ export async function runCodexAppServerAttempt(
|
||||
developerInstructionAdditionChars: projection.developerInstructionAddition?.length ?? 0,
|
||||
});
|
||||
promptText = projectionDecision.project ? projection.promptText : params.prompt;
|
||||
promptContextRange = projectionDecision.project ? projection.promptContextRange : undefined;
|
||||
developerInstructions = joinPresentSections(
|
||||
baseDeveloperInstructions,
|
||||
projection.developerInstructionAddition,
|
||||
@@ -1014,12 +1021,31 @@ export async function runCodexAppServerAttempt(
|
||||
messages: codexModelInputHistoryMessages,
|
||||
ctx: hookContext,
|
||||
});
|
||||
const resolveShiftedPromptContextRange = (
|
||||
prompt: string,
|
||||
turnPromptText: string,
|
||||
): CodexProjectedContextRange | undefined => {
|
||||
if (!promptContextRange || !prompt.endsWith(promptText) || !turnPromptText.endsWith(prompt)) {
|
||||
return undefined;
|
||||
}
|
||||
const promptTextOffset = prompt.length - promptText.length;
|
||||
const turnPromptOffset = turnPromptText.length - prompt.length + promptTextOffset;
|
||||
return {
|
||||
start: turnPromptOffset + promptContextRange.start,
|
||||
end: turnPromptOffset + promptContextRange.end,
|
||||
};
|
||||
};
|
||||
let promptBuild = await buildPromptFromCurrentInputs();
|
||||
const decorateCodexTurnPromptText = (prompt: string) =>
|
||||
prependCodexOpenClawPromptContext(prompt, openClawPromptContext, {
|
||||
const decorateCodexTurnPromptText = (prompt: string) => {
|
||||
const turnPromptText = prependCodexOpenClawPromptContext(prompt, openClawPromptContext, {
|
||||
preservePromptWithoutContext:
|
||||
params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron",
|
||||
});
|
||||
return fitCodexProjectedContextForTurnStart({
|
||||
promptText: turnPromptText,
|
||||
contextRange: resolveShiftedPromptContextRange(prompt, turnPromptText),
|
||||
});
|
||||
};
|
||||
let codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
|
||||
const buildCodexTurnCollaborationDeveloperInstructions = () =>
|
||||
buildTurnCollaborationMode(params, {
|
||||
@@ -1088,8 +1114,10 @@ export async function runCodexAppServerAttempt(
|
||||
assembledMessages: newerVisibleMessages,
|
||||
originalHistoryMessages: historyMessages,
|
||||
prompt: params.prompt,
|
||||
maxRenderedContextChars: codexContextProjectionMaxChars,
|
||||
});
|
||||
promptText = projection.promptText;
|
||||
promptContextRange = projection.promptContextRange;
|
||||
prePromptMessageCount = projection.prePromptMessageCount;
|
||||
return true;
|
||||
};
|
||||
@@ -1166,6 +1194,11 @@ export async function runCodexAppServerAttempt(
|
||||
staleBindingContinuityForcedFreshStart =
|
||||
precomputedStaleBindingContinuityProjectionApplied &&
|
||||
!inactiveThreadBootstrapBindingForcedFreshStart;
|
||||
if (staleBindingContinuityForcedFreshStart) {
|
||||
// Once the native thread id is discarded, Codex no longer owns the
|
||||
// pre-binding history; rebuild from the mirrored transcript.
|
||||
applyFreshThreadContinuityProjection();
|
||||
}
|
||||
if (activeContextEngine) {
|
||||
contextEngineProjection = undefined;
|
||||
try {
|
||||
|
||||
4
extensions/cohere/npm-shrinkwrap.json
generated
4
extensions/cohere/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Cohere provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": true
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/comfy-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw ComfyUI provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/copilot-proxy",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/copilot",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@github/copilot-sdk": "1.0.0-beta.9"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/copilot",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepgram-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw Deepgram media-understanding provider",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/deepinfra/npm-shrinkwrap.json
generated
4
extensions/deepinfra/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/deepinfra-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/deepinfra-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepinfra-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw DeepInfra provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
4
extensions/deepseek/npm-shrinkwrap.json
generated
4
extensions/deepseek/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/deepseek-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/deepseek-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/deepseek-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw DeepSeek provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diagnostics-otel",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "1.9.1",
|
||||
"@opentelemetry/api-logs": "0.219.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-otel",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw diagnostics OpenTelemetry exporter for metrics and traces.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -34,10 +34,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diagnostics-prometheus",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw diagnostics Prometheus exporter for runtime metrics.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/diffs-language-pack",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diffs-language-pack",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diffs-language-pack",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw diffs viewer syntax highlighting language pack",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -22,13 +22,13 @@
|
||||
"minHostVersion": ">=2026.5.27"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"assetScripts": {
|
||||
"build": "node ../../scripts/build-diffs-viewer-runtime.mjs full"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/diffs",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@pierre/diffs": "1.2.4",
|
||||
"@pierre/theme": "1.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/diffs",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"assetScripts": {
|
||||
"build": "node ../../scripts/build-diffs-viewer-runtime.mjs curated"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/discord",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@discordjs/voice": "0.19.2",
|
||||
"discord-api-types": "0.38.48",
|
||||
@@ -16,7 +16,7 @@
|
||||
"ws": "8.21.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/discord",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -67,10 +67,10 @@
|
||||
"allowInvalidConfigRecovery": true
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/document-extract-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw local document extraction plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/duckduckgo-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw DuckDuckGo plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/elevenlabs-speech",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw ElevenLabs speech plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/exa/npm-shrinkwrap.json
generated
4
extensions/exa/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/exa-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/exa-plugin",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/exa-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Exa plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/fal-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/feishu",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@larksuiteoapi/node-sdk": "1.66.0",
|
||||
"typebox": "1.1.39",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/feishu",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -51,10 +51,10 @@
|
||||
"minHostVersion": ">=2026.5.29"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/file-transfer",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw file transfer plugin (file_fetch, dir_list, dir_fetch, file_write)",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
||||
4
extensions/firecrawl/npm-shrinkwrap.json
generated
4
extensions/firecrawl/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/firecrawl-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/firecrawl-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"typebox": "1.1.39"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/firecrawl-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Firecrawl plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -24,10 +24,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/fireworks-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw Fireworks provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/github-copilot-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw GitHub Copilot provider plugin",
|
||||
"type": "module",
|
||||
|
||||
4
extensions/gmi/npm-shrinkwrap.json
generated
4
extensions/gmi/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/gmi-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/gmi-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/gmi-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw GMI Cloud provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/google-meet",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"commander": "14.0.3",
|
||||
"typebox": "1.1.39"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/google-meet",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -33,10 +33,10 @@
|
||||
"minHostVersion": ">=2026.4.20"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/google-plugin",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/googlechat",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"gaxios": "7.1.4",
|
||||
"google-auth-library": "10.6.2",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/googlechat",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -75,10 +75,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
4
extensions/gradium/npm-shrinkwrap.json
generated
4
extensions/gradium/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/gradium-speech",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/gradium-speech",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/gradium-speech",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Gradium speech plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
4
extensions/groq/npm-shrinkwrap.json
generated
4
extensions/groq/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/groq-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/groq-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/groq-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Groq media-understanding provider.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/huggingface-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw Hugging Face provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/image-generation-core",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw image generation runtime package",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/imessage",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"private": true,
|
||||
"description": "OpenClaw iMessage channel plugin using imsg on a signed-in Mac",
|
||||
"type": "module",
|
||||
@@ -43,10 +43,10 @@
|
||||
]
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
}
|
||||
},
|
||||
"pluginInspector": {
|
||||
|
||||
4
extensions/inworld/npm-shrinkwrap.json
generated
4
extensions/inworld/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/inworld-speech",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/inworld-speech",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/inworld-speech",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Inworld speech plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/irc",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw IRC channel plugin",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
|
||||
4
extensions/kilocode/npm-shrinkwrap.json
generated
4
extensions/kilocode/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/kilocode-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/kilocode-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/kilocode-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Kilo Gateway provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
4
extensions/kimi-coding/npm-shrinkwrap.json
generated
4
extensions/kimi-coding/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/kimi-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/kimi-provider",
|
||||
"version": "2026.6.9-beta.1"
|
||||
"version": "2026.6.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/kimi-provider",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"description": "OpenClaw Kimi provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,10 +21,10 @@
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1",
|
||||
"openclawVersion": "2026.6.8",
|
||||
"bundledDist": false
|
||||
},
|
||||
"release": {
|
||||
|
||||
6
extensions/line/npm-shrinkwrap.json
generated
6
extensions/line/npm-shrinkwrap.json
generated
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"dependencies": {
|
||||
"@line/bot-sdk": "11.0.1",
|
||||
"zod": "4.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"openclaw": ">=2026.6.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/line",
|
||||
"version": "2026.6.9-beta.1",
|
||||
"version": "2026.6.8",
|
||||
"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.9-beta.1"
|
||||
"openclaw": ">=2026.6.8"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"openclaw": {
|
||||
@@ -46,10 +46,10 @@
|
||||
"minHostVersion": ">=2026.4.10"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.9-beta.1"
|
||||
"pluginApi": ">=2026.6.8"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.9-beta.1"
|
||||
"openclawVersion": "2026.6.8"
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user