Skip to content

feat(tokenjuice): bundle the native adapter#69946

Merged
vincentkoc merged 17 commits intomainfrom
feat/tokenjuice-hooks
Apr 22, 2026
Merged

feat(tokenjuice): bundle the native adapter#69946
vincentkoc merged 17 commits intomainfrom
feat/tokenjuice-hooks

Conversation

@vincentkoc
Copy link
Copy Markdown
Member

@vincentkoc vincentkoc commented Apr 22, 2026

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: OpenClaw had the new embedded-extension seam, but no bundled tokenjuice plugin. The earlier "install tokenjuice as an OpenClaw plugin" route was the wrong UX and the wrong packaging boundary.
  • Why it matters: users should enable a bundled tokenjuice plugin, not install a second OpenClaw plugin package, and the bundled extension should import tokenjuice like any other third-party runtime dependency.
  • What changed: kept the new registerEmbeddedExtensionFactory(...) seam, added a bundled extensions/tokenjuice plugin that imports tokenjuice/openclaw through a local runtime boundary, and added labeler/lockfile/test coverage for that bundled plugin.
  • What did NOT change (scope boundary): no docs/config followup in this PR beyond the SDK seam docs already on the branch, and no sync tool_result_persist fallback.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write N/A. If the cause is unclear, write Unknown.

  • Root cause: N/A
  • Missing detection / guardrail: N/A
  • Contributing context (if known): N/A

Regression Test Plan (if applicable)

For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write N/A.

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/pi-embedded-runner.extensions.test.ts, extensions/tokenjuice/index.test.ts, extensions/tokenjuice/manifest.test.ts
  • Scenario the test should lock in: OpenClaw exposes the embedded factory seam, the bundled tokenjuice plugin registers through it, and the bundled package metadata stays wired for staged runtime dependencies.
  • Why this is the smallest reliable guardrail: it covers the new core seam plus the new bundled plugin boundary without needing a full gateway boot in CI.
  • Existing test that already covers this (if any): None.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

List user-visible changes (including defaults/config).
If none, write None.

  • OpenClaw now ships a bundled tokenjuice plugin that can be enabled instead of installed as a separate plugin package.

Diagram (if applicable)

For UI changes or non-trivial logic flows, include a small ASCII diagram reviewers can scan quickly. Otherwise write N/A.

Before:
[user installs tokenjuice package] -> [tries to install it again as an OpenClaw plugin] -> [blocked / wrong boundary]

After:
[OpenClaw ships bundled tokenjuice plugin] -> [user enables plugin]
  -> [bundled plugin imports tokenjuice/openclaw]
  -> [embedded runner invokes tokenjuice factory]
  -> [exec tool results are compacted]

Security Impact (required)

  • New permissions/capabilities? (Yes/No): Yes
  • Secrets/tokens handling changed? (Yes/No): No
  • New/changed network calls? (Yes/No): No
  • Command/tool execution surface changed? (Yes/No): Yes
  • Data access scope changed? (Yes/No): No
  • If any Yes, explain risk + mitigation:
    • This adds a bundled plugin-owned compaction path for already-trusted OpenClaw plugins. The core seam stays generic and the tokenjuice runtime import lives in a narrow bundled extension package.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 + pnpm
  • Model/provider: openai / gpt-5.4
  • Integration/channel (if any): OpenClaw plugin loader + Pi embedded runner
  • Relevant config (redacted): temporary smoke config with plugins.entries.tokenjuice.enabled=true

Steps

  1. Build the tokenjuice worktree so its tokenjuice/openclaw export exists in dist.
  2. Symlink that tokenjuice worktree into extensions/tokenjuice/node_modules/tokenjuice so the bundled plugin resolves the new export through a normal package import path.
  3. Load only the bundled tokenjuice plugin, build embedded extension factories, and invoke the tool_result handler with a git status exec result.

Expected

  • The bundled tokenjuice plugin loads, registers one embedded extension factory, and rewrites the exec result.

Actual

  • That is what happened; the live smoke returned compacted git status output plus tokenjuice metadata.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: pnpm test:serial extensions/tokenjuice/index.test.ts extensions/tokenjuice/manifest.test.ts src/agents/pi-embedded-runner.extensions.test.ts; real bundled-plugin smoke through loadOpenClawPlugins(...) + buildEmbeddedExtensionFactories(...) using the tokenjuice worktree through a normal package import path.
  • Edge cases checked: opt-in manifest default; staged runtime dependency manifest; loader registration of the bundled factory; actual compacted tool_result output.
  • What you did not verify: pnpm check:changed still fails on unrelated existing typecheck issues in src/docs/clawhub-plugin-docs.test.ts, src/gateway/reconnect-gating.test.ts, src/i18n/registry.test.ts, src/ui-app-settings.agents-files-refresh.test.ts, extensions/qa-lab/web/src/main.ts, and extensions/qqbot/src/bridge/setup/finalize.ts.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): No
  • Migration needed? (Yes/No): No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: the current published tokenjuice@0.6.0 does not expose tokenjuice/openclaw yet.

AI Assistance

  • AI-assisted in description
  • Testing: fully tested

@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot Bot commented Apr 22, 2026

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🟠 High Arbitrary code execution via untrusted npm_execpath in runtime deps installer
1. 🟠 Arbitrary code execution via untrusted npm_execpath in runtime deps installer
Property Value
Severity High
CWE CWE-78
Location src/plugins/bundled-runtime-deps.ts:457-475

Description

resolveBundledRuntimeDepsNpmRunner trusts the npm_execpath environment variable if it looks like an npm-cli.js path. An attacker who can influence the environment passed into installBundledRuntimeDeps can point npm_execpath at an arbitrary absolute JS file named npm-cli.js (or .../npm/bin/npm-cli.js). The code then executes it with Node (execPath), resulting in arbitrary code execution.

Key points:

  • Input: env.npm_execpath is taken from the caller-provided environment.
  • Weak validation: isNpmCliPath() only checks the path suffix; it does not restrict to the Node installation directory.
  • Sink: returned runner uses command: execPath and args: [npmCliPath, ...], executing the attacker-controlled script.
  • createBundledRuntimeDepsInstallEnv does not remove npm_execpath, so the variable propagates into the installer environment.

Vulnerable code:

const rawNpmExecPath = ... ? env.npm_execpath : undefined;
const npmExecPath = rawNpmExecPath && isNpmCliPath(rawNpmExecPath) ? rawNpmExecPath : undefined;
...
const npmCliPath = npmCliCandidates.find((candidate) => pathImpl.isAbsolute(candidate) && existsSync(candidate));
if (npmCliPath) {
  return { command: execPath, args: [npmCliPath, ...params.npmArgs] };
}

Recommendation

Do not trust npm_execpath from the ambient environment for security-sensitive execution.

Recommended fixes (pick one):

  1. Ignore npm_execpath entirely and only use vetted locations relative to process.execPath (Node’s install dir):
const npmCliCandidates = [
  pathImpl.resolve(nodeDir, "../lib/node_modules/npm/bin/npm-cli.js"),
  pathImpl.resolve(nodeDir, "node_modules/npm/bin/npm-cli.js"),
];
  1. If you must allow npm_execpath, require it to be inside the resolved Node directory (or a known safe npm installation root) after realpath resolution:
import fs from "node:fs";
const real = fs.realpathSync(rawNpmExecPath);
const realNodeDir = fs.realpathSync(nodeDir);
if (!real.startsWith(realNodeDir + pathImpl.sep)) throw new Error("Untrusted npm_execpath");

Additionally, consider sanitizing the installer env:

  • Remove npm_execpath from createNestedNpmInstallEnv / createBundledRuntimeDepsInstallEnv.
  • Optionally strip other npm control variables (e.g., npm_config_userconfig) if they can affect execution in your threat model.

Analyzed PR: #69946 at commit bc8623d

Last updated on: 2026-04-22T07:06:17Z

@vincentkoc vincentkoc self-assigned this Apr 22, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation agents Agent runtime and tooling size: S maintainer Maintainer-authored PR labels Apr 22, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 22, 2026

Greptile Summary

This PR adds a public api.registerEmbeddedExtensionFactory(...) seam to the OpenClaw plugin SDK, allowing external plugins to register Pi embedded-runner extension factories without any core special-casing. The implementation follows the established compactionProviders/agentHarnesses registry pattern end-to-end: new embedded-extension-factory.ts module, full cache snapshot/restore coverage in loader.ts, noop fallback in api-builder.ts, and a focused seam test.

Confidence Score: 5/5

Safe to merge; implementation is consistent with existing plugin registry patterns and all cache paths are covered.

All findings are P2: one style suggestion about awaiting the factory call in the test (harmless since the current factory is synchronous), and a minor temp-directory cleanup omission. No logic errors, no data integrity issues, and no security concerns beyond what the existing plugin trust model already handles.

src/agents/pi-embedded-runner.extensions.test.ts — minor test hygiene (void factory call and missing tmpdir cleanup).

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner.extensions.test.ts
Line: 98-103

Comment:
**Unawaited async factory call may cause flaky assertions**

The factory result is discarded with `void`, so if any future `ExtensionFactory` is async (returns a `Promise<void>` instead of `void`), `handlers.set` won't be called before the `expect` on line 103. The test would silently pass with an empty `handlers` map since the factory type allows async. Awaiting the call makes the test robust now and safe for async factories later.

```suggestion
    await cachedFactories[0]?.({
      on(event: string, handler: Function) {
        handlers.set(event, handler);
      },
    } as never);
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/pi-embedded-runner.extensions.test.ts
Line: 48

Comment:
**Temp directory not cleaned up after test**

`fs.mkdtempSync` creates a directory in the OS temp folder that is never removed. Other plugin seam tests in this codebase typically call `fs.rmSync(tmp, { recursive: true, force: true })` inside `afterEach`. This isn't a correctness issue, but it accumulates test artifacts on developer machines.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(plugins): register embedded extensi..." | Re-trigger Greptile

Comment thread src/agents/pi-embedded-runner.extensions.test.ts Outdated
Comment thread src/agents/pi-embedded-runner.extensions.test.ts Outdated
@vincentkoc vincentkoc changed the title feat(plugins): register embedded extension factories feat(tokenjuice): bundle the native adapter Apr 22, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c11473c734

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pnpm-lock.yaml
Comment thread src/plugins/types.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d477d7385

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/tokenjuice/runtime-api.ts
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts gateway Gateway runtime size: L and removed size: M labels Apr 22, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a6c8b4350

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pnpm-lock.yaml
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 601e8ef865

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugins/bundled-runtime-deps.ts Outdated
@vincentkoc vincentkoc force-pushed the feat/tokenjuice-hooks branch from 601e8ef to 8d181fe Compare April 22, 2026 05:06
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f0e903dd9c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/tokenjuice/tsconfig.json Outdated
Comment thread src/plugins/bundled-runtime-deps.ts Outdated
@vincentkoc vincentkoc force-pushed the feat/tokenjuice-hooks branch from f069c7a to 3579bfb Compare April 22, 2026 05:35
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b05d48607

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugins/bundled-runtime-deps.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d5a72de4d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.toSorted((left, right) => left.localeCompare(right));
const missingSpecs = deps
.filter((dep) => !hasDependencySentinel(dependencySearchRoots, dep))
.filter((dep) => !hasDependencySentinel([installRoot], dep))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid npm installs inside source-checkout plugin roots

Restricting the missing-dependency check to installRoot here means source-checkout plugins now fall through to npm install in the plugin directory whenever <plugin>/node_modules is absent. For extensions/tokenjuice (and other workspace packages), that nested npm install fails with EUNSUPPORTEDPROTOCOL because the manifest contains workspace:* dev dependencies, so enabling the plugin can fail before it registers. This needs a source-checkout-safe install target (or a source-checkout bypass) instead of invoking npm in the workspace package root.

Useful? React with 👍 / 👎.

@vincentkoc vincentkoc merged commit 91ac485 into main Apr 22, 2026
6 checks passed
@vincentkoc vincentkoc deleted the feat/tokenjuice-hooks branch April 22, 2026 06:58
artisticlight added a commit to artisticlight/openclaw that referenced this pull request Apr 22, 2026
* fix: skip clean run-node runtime restaging

* fix: stabilize testbox test suite

* test: align plugin test contracts

* fix(agents): normalize malformed assistant replay content

* fix(agents): harden replay normalization guards

* fix(agents): distill replay content normalization

* fix: normalize assistant replay content (openclaw#69850) (thanks @fuller-stack-dev)

* Make harness failures fail honestly (openclaw#69981)

* Agents: fail honestly on harness errors

* Docs: clarify Codex harness fallback

* perf(ci): unblock node compat and trim runtime compat test

* docs: record testbox full-suite profile

* chore(agents): prefer local validation over testbox

* refactor: generalize route target parsing

* refactor: drop provider reconnect shim

* test: generalize legacy state migration coverage

* refactor: keep plugin login policy out of core

* fix(googlechat): harden google auth transport (openclaw#69812)

* fix(googlechat): localize google auth gaxios compat

* fix(googlechat): declare undici for staged runtime deps

* fix(googlechat): harden google auth transport

* fix(googlechat): narrow credential file reads

* fix(googlechat): preserve auth proxy transport

* fix(googlechat): allow symlinked auth files

* fix(googlechat): atomically load auth files

* fix(googlechat): eagerly buffer auth responses

* fix(googlechat): cap auth response buffering

* fix(googlechat): pin staged auth runtime deps

* fix(googlechat): buffer auth responses as array buffers

* Update CHANGELOG.md

* fix(googlechat): reject unstreamed auth responses

* fix(googlechat): use ambient fetch for auth transport

* fix(googlechat): keep guarded auth fetch on runtime path

* fix(googlechat): align staged zod range

* chore(lockfile): sync googlechat zod spec

* test: reuse plugin auto-enable fixture environment

* refactor: remove plugin tool display overrides from core

* fix(agents): guard replay convert hook

* test: generalize media fetch token fixtures

* feat(tencent): remove Token Plan provider and auth (openclaw#69996)

Co-authored-by: albertxyu <albertxyu@tencent.com>

* docs: fix stale community links in README and CONTRIBUTING (openclaw#69945)

Co-authored-by: Jonathan Amponsah <amponsahjonathan442@gmail.com>

* docs: generalize core channel examples

* fix(config): enforce resolved runtime channel config

* fix(channels): thread runtime config through sends

* fix(telegram): isolate sent-message cache stores

* fix(channels): preserve setup promotion fallbacks

* docs: remove bundled channel examples from core types

* refactor: generalize voice audio compatibility

* perf(test): avoid bundled channel fallback in model override tests

* docs: generalize core routing comments

* refactor: gate setup promotion by manifest feature

* docs(tui): document local config repair flow (openclaw#69995) (thanks @fuller-stack-dev)

* docs(tui): document local config repair flow

* docs(tui): clarify local TUI examples

* docs(config): gate local TUI repair flow

* docs(tui): fix local repair docs

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>

* docs: generalize plugin runtime comments

* perf(test): skip setup promotion metadata fallback

* perf(slack): narrow runtime-setter + lazy-load 4 modules + narrow 2 SDK surfaces (openclaw#69317)

Lazy load modules showing a ~50% gateway startup performance improvement

* feat(tokenjuice): bundle the native adapter (openclaw#69946)

* feat(plugins): register embedded extension factories

* feat(tokenjuice): bundle the native adapter

* fix(tokenjuice): gate the bundled embedded extension seam

* fix(tokenjuice): refresh runtime sidecar baseline

* fix(plugins): harden bundled embedded extensions

* fix(plugins): install source bundled runtime deps

* fix(tokenjuice): sync lockfile importer

* fix(plugins): validate reused runtime dep versions

* fix(plugins): restore tokenjuice CI contract

* fix(plugins): remove tokenjuice dts bridge

* fix(tokenjuice): repair openclaw type shim

* fix(plugins): harden bundled runtime deps

* fix(plugins): keep source checkout runtime deps local

* fix(plugins): isolate bundled runtime dep installs

* fix(cli): keep plugin startup registration non-activating

* fix(cli): keep loader overrides out of plugin cli options

* runtime-taskflow: sync blocked waiting edge into durable jobs

* docs(skill): tighten duplicate triage mirror rules

* docs(tokenjuice): add bundled plugin guide (openclaw#70038)

* docs(tokenjuice): add bundled plugin guide

* docs(tokenjuice): sort nav entry

* docs(changelog): mention tokenjuice embedded support (openclaw#70039)

* Fix Codex auth handoff for the app-server harness (openclaw#69990)

* Codex: fix auth bridge token shape

* Codex: preserve selected auth tokens

* Codex: prefer selected profile id token

* Codex: honor inherited Codex home

---------

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

* fix(agents): keep mocked OpenAI Responses on HTTP (openclaw#69815)

* fix(agents): keep mocked OpenAI responses on HTTP

* docs(changelog): add entry for mocked responses fix

* fix(release-check): assert bundled plugin runtime deps after packed postinstall (openclaw#70035)

* fix(release-check): assert bundled plugin runtime deps after packed postinstall

Release-check already validates source dist/extensions runtime deps are staged, but runPackedBundledChannelEntrySmoke never re-validates after the packed postinstall runs against the installed tarball. That gap is how 2026.4.21 shipped without @whiskeysockets/baileys in dist/extensions/whatsapp/node_modules, because the source staging passed while the installed layout was left broken.

Re-use collectBuiltBundledPluginStagedRuntimeDependencyErrors against the installed packageRoot right after runPackedBundledPluginPostinstall and fail release-check if any declared runtime dependency is missing from the plugin-local node_modules.

* fix(release-check): check postinstalled dep sentinels at packageRoot/node_modules

Codex review on openclaw#70035 caught that collectInstalledBundledPluginRuntimeDepErrors was pointing at dist/extensions/<id>/node_modules, but packed postinstall installs and probes sentinels at packageRoot/node_modules (see dependencySentinelPath in scripts/postinstall-bundled-plugins.mjs). The previous implementation would have falsely failed release-check on healthy packed installs while still missing the original WhatsApp regression.

Reuse discoverBundledPluginRuntimeDeps from postinstall-bundled-plugins.mjs so the release guard uses the exact same dep discovery and sentinel paths the packed postinstall uses. Update the test fixtures accordingly so they model the real install layout.

* feat(openai): add codex device-code auth and fix login options in menu (openclaw#69557)

Merged via squash.

Prepared head SHA: 4918ed6
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: BunsDev <68980965+BunsDev@users.noreply.github.com>
Reviewed-by: @BunsDev

* fix: make slack socket health event-driven

* fix: clean up slack socket waiters on start hooks

* fix: use transport activity for stale health

* docs: update changelog for channel health (openclaw#69833) (thanks @bek91)

* ci: serialize parity gate scenarios

* ci: stabilize parity gate runner

* ci: pin qa parity tool profile

* ci: build runtime before parity gate

* test: harden qa parity config cleanup

* fix: drop stale socket mode opt-in

* test: harden qa parity runtime staging

* ci: build private qa parity runtime

* test: harden qa private runtime staging

* fix: harden tokenjuice host typing

* fix: keep custom pi tools executable

* tooling: add corepack pnpm fallback for git hooks

* qa: harden parity gate execution (openclaw#70045)

* fix: keep claude cli sessions warm (openclaw#69679)

* feat(cli): keep claude cli sessions warm

* test(cli): cover claude live session reuse

* fix(cli): harden claude live session reuse

* fix(cli): redact mcp session key logs

* fix(cli): bound claude live session turns

* fix(cli): reuse claude live sessions on resume

* refactor(cli): canonicalize claude live argv

* fix(cli): preserve claude live resume state

* fix(cli): close dead claude live sessions

* fix(cli): serialize claude live session creates

* fix(cli): count pending claude live sessions

* fix(cli): tighten claude live resume abort

* fix(cli): reject closed claude live sessions

* fix(cli): refresh claude live fingerprints

* fix(cli): stabilize MCP resume hash

* fix: preserve claude live inline resume (openclaw#69679)

---------

Co-authored-by: Frank Yang <frank.ekn@gmail.com>

* fix(pair): render /pair qr as media (openclaw#70047)

* fix(pair): render pair qr as media

* fix(gateway): preserve media reply threading

* fix(gateway): harden webchat media replies

* fix(plugin-sdk): keep trustedLocalMedia internal

* docs(changelog): note pair qr media fix

* Update CHANGELOG with recent fixes and enhancements

Updated changelog to include recent fixes and enhancements.

* fix(codex): unchain app-server defaults (openclaw#70082)

* place permission under each branch of bot permissions for discord docs (openclaw#69218)

Merged via squash.

Prepared head SHA: dd6ae52
Co-authored-by: epicseven-cup <59263116+epicseven-cup@users.noreply.github.com>
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Reviewed-by: @velvet-shark

* fix: lower the log level from info to debug (openclaw#70108)

* fix(cli): keep provider-owned sessions through implicit expiry

* fix(cli): upgrade legacy mcp session reuse

* fix(gateway): preserve cli session binding metadata

* fix: update cli session changelog (openclaw#70106)

* fix(config): accept truncateAfterCompaction (openclaw#68395)

Merged via squash.

Prepared head SHA: bf45148
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Reviewed-by: @hxy91819

* chore(pi): remove local pr prompts

Remove repo-local /landpr and /reviewpr prompt templates so maintainers use the externally maintained workflow instead.
These flows remain available from the external maintainers repo via globally installed Pi skills and prompts.

* fix(plugins): avoid doctor crash on legacy interactive state (openclaw#70135)

* fix(plugins): hydrate legacy interactive state

* fix(plugins): avoid doctor crash on legacy interactive state (openclaw#70135) (thanks @ngutman)

* fix(cli): stabilize oauth session auth epochs

* test(cli): cover oauth auth epoch continuity

* fix: update cli session changelog (openclaw#70132)

* fix: require cli auth epoch version (openclaw#70132)

* fix(qqbot): add interaction intents (openclaw#70143)

* feat(qqbot): add intents interaction

* fix(qqbot): add interaction intents (openclaw#70143) (thanks @cxyhhhhh)

---------

Co-authored-by: sliverp <870080352@qq.com>

* fix(codex): apply GPT-5 prompt overlay (openclaw#70175)

* ci: consolidate test shard fanout

* chore: update dependencies

* fix(agent): align pi session tool options

* ci: downsize blacksmith runners

* ci: run aggregate checks off blacksmith

* fix(gateway): harden WS pairing locality

* fix: fail closed on plugin integrity drift

* ci: keep long matrix aggregates on blacksmith

* build: refresh a2ui bundle hash

* ci: keep cpu-sensitive lanes larger

* fix(doctor): skip token generation for trusted-proxy and none auth modes (openclaw#59055)

runGatewayAuthHealth() only excluded 'password' and 'token' (with existing
token) from its needsToken check. When gateway.auth.mode was set to
'trusted-proxy' or 'none', doctor --fix would incorrectly:

1. Flag the config as 'missing a token'
2. Prompt to generate a gateway token
3. Overwrite auth.mode to 'token' in openclaw.json

This silently broke trusted-proxy deployments (common in SaaS/reverse-proxy
setups) by replacing the delegated auth mode with token auth.

The fix aligns runGatewayAuthHealth() with the existing
hasExplicitGatewayInstallAuthMode() in auth-install-policy.ts, which
already correctly returns false for 'password', 'none', and 'trusted-proxy'.

Co-authored-by: wujiaming88 <wujiaming88@example.com>

* fix: preserve restart continuations after reboot (openclaw#63406) (thanks @VACInc)

* gateway: add restart continuation sentinel

* gateway: address restart continuation review

* gateway: handle restart continuation edge cases

* gateway: keep restart continuations on threaded delivery path

* fix(gateway): harden restart continuation routing

* test(gateway): cover restart continuation edge cases

* docs(agent): clarify restart continuation usage

* fix: preserve restart continuations after reboot (openclaw#63406) (thanks @VACInc)

---------

Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>

* ci: move lightweight automation off blacksmith

* docs(changelog): fix cron attribution

* docs(changelog): correct cron contributors

* docs(changelog): thank cron contributors

* ci: skip aggregate fan-in after cancellation

* ci: refresh ci concurrency group

* fix(gateway): write restart sentinels atomically

* docs(changelog): note restart sentinel atomic writes

* fix(gateway): allow silent metadata-upgrade pairing for loopback CLI clients (openclaw#70224)

Loopback CLI clients (cli_container_local, shared_secret_loopback_local)
with valid shared-secret auth previously got disconnected with 1008
pairing required whenever the paired device record's platform or
deviceFamily string differed from what the CLI claimed at connect time.

PR openclaw#69431 added the shared_secret_loopback_local locality but deferred
the metadata-upgrade reason from the auto-approval allowlist. That
deferral created an unrecoverable handshake loop in practice: every CLI
connect triggers a fresh metadata-upgrade request, the Control UI has
no approval surface for this reason, and non-interactive shells cannot
complete pairing. This broke every non-interactive openclaw agent use
case when paired device keys are replicated across hosts or installs
are migrated across platforms.

Extend shouldAllowSilentLocalPairing to auto-approve metadata-upgrade
for cli_container_local and shared_secret_loopback_local localities
only. Browser / Control-UI / remote paths retain existing approval-
required behavior. Gateway still logs every metadata refresh via the
existing security audit line for operator review.

Add 4 unit tests covering the decision table for metadata-upgrade
across all four localities.

Related: openclaw#69397, openclaw#69431

* refactor(gateway): unify startup task execution

* fix(pairing): clear stale requests on device removal (openclaw#70239)

* fix(pairing): clear stale requests on device removal

* docs(changelog): note pairing stale request cleanup

* perf(test): avoid bundled setup in auto-enable tests

* ci: rebalance agentic node tests

* fix(gateway): preserve restart continuation chat type

* ci: reduce blacksmith test pressure

* ci: offload short linux checks

* ci: keep build smoke on blacksmith

* ci: rebalance runtime config tests

* ci: consolidate short test workers

* ci: keep native lanes native scoped

* fix(dotenv): block connector endpoint workspace overrides (openclaw#70240)

* fix(dotenv): block connector endpoint workspace overrides

* docs(changelog): note dotenv endpoint blocklist

* fix(dotenv): block Matrix per-account scoped homeserver overrides

* feat: Add /models add hot-reload model registration (openclaw#70211)

* feat(models): add chat model registration with hot reload

* docs(changelog): add models entry for pr 70211

* fix(models): harden add flow follow-ups

* fix models add review follow-ups

* harden models add config writes

* tighten plugin boundary invariant

* move models add adapters behind sdk facades

* avoid ollama-specific core facade

* ci: reuse build artifacts for gateway topology

* telegram: align model picker callback auth (openclaw#70235)

* telegram: align model picker callback auth

* docs(changelog): note telegram model callback auth fix

* fix(telegram): use runtime config for model callback auth

* Revert "ci: reuse build artifacts for gateway topology"

This reverts commit be31776.

* ci: trim gateway watch build profile

* ci: keep workflow edits off windows lane

* ci: parallelize additional boundary guards

* fix: load staged dist-runtime plugins in docker

* test: stabilize audio directive tag test

* fix: add plugin load debug shape

* fix(agents): accept silent no-reply turns

* fix: default claude cli to stdio sessions

* ci: add fast docker install smoke

* docs: update claude cli stdio notes

* fix(config): preserve source config during recovery

* test: keep loader fixture inside plugin boundary

* fix(discord): thread runtime config through guild actions

* fix(discord): use resolveDiscordChannelParentIdSafe in voice command path

openclaw#69908 switched native slash commands, listeners, and the model picker to
the safe accessor for partial thread channels, but the voice /join command
still reads channel.parentId through the unsafe "parentId" in channel
pattern. Route it through the same helper so the voice command path does
not crash with "Cannot access rawData on partial Channel" when invoked
from inside a thread on @buape/carbon >=0.16.

* fix(discord): use resolveDiscordChannelNameSafe for voice channel override name

Applies the same safe-accessor pattern to the adjacent name field.
If @buape/carbon implements name as a getter that also reads _rawData
(like parentId), the previous `"name" in channel` pattern would throw
for the same reason. Aligns with the fix for parentId in the same call
site.

* fix(plugins): harden bundled runtime dep staging

* fix: harden Discord voice commands in threads

* ci: run install smoke for runtime dep staging

* fix(hooks): standardize outbound routing metadata

* test(slack): drop obsolete adapter hook test

* ci: downsize install smoke runner

* fix(discord): make thread parent inheritance opt-in

* fix: make Discord thread parent inheritance opt-in (openclaw#69986) (thanks @Blahdude)

* refactor: move channel doctor migrations to plugins

* refactor(memory): migrate lancedb recall to prompt-build hook

* refactor: build channel setup input generically

* tooling: finish corepack-only pnpm repo paths

* fix(agent-runner): accept injected normalizeMediaPaths in runAgentTurnWithFallback

* fix(agent-runner): share media-path normalizer with runAgentTurnWithFallback to prevent duplicate outbound media

* test(agent-runner): regression — createReplyMediaPathNormalizer.runtime not called when normalizer injected

* fix: share reply media context (openclaw#68111) (thanks @ayeshakhalid192007-dev)

* refactor: move doctor capabilities to channel manifests

* test: keep hook and slack tests on public boundaries

* refactor: declare channel add flags in manifests

* refactor: use memory slot defaults in core paths

* test: keep config fallback test on generic plugin channel

* fix(cli-session): only hash static extraSystemPrompt for session reuse

The extraSystemPrompt includes per-message dynamic content from
buildInboundMetaSystemPrompt() (timestamps, message IDs, sender metadata)
that changes on every inbound message. This causes the extraSystemPromptHash
to differ every turn, triggering a session reset with reason='system-prompt'
and discarding all CLI session context.

Fix: split extraSystemPrompt into dynamic (inbound meta) and static
(group context, group intro, group system prompt, exec override hints)
portions. Only hash the static portion for session reuse validation.

The full extraSystemPrompt (dynamic + static) is still sent to the CLI
as before — only the session stability hash uses the static subset.

Fixes openclaw#70100

* fix: address review feedback — handle empty static prompt and remove stray blank lines

- Always pass extraSystemPromptStatic as string (even when empty) so the
  fallback in prepare.ts never accidentally hashes dynamic content
- Use explicit undefined check (params.extraSystemPromptStatic !== undefined)
  instead of ?? nullish coalescing to avoid edge case where empty static
  string falls through to hashing the full dynamic prompt
- Remove extra blank line

* fix(cli-session): forward static prompt hash input

* fix: stabilize Claude CLI session prompt hashing

* fix(hooks): expose typed gateway startup context

* fix(plugins): preserve source activation config

* ci: use dist cache instead of artifact upload

* refactor(hooks): centralize bundled subagent hook wiring

* refactor(discord): centralize thread channel context

* refactor(discord): share channel action param parsing

* refactor(discord): share partial channel test fixtures

* ci: parallelize extension batch groups

* fix(discord): break monitor threading import cycle

* refactor(hooks): centralize matrix subagent hook wiring

* fix(hooks): prefer shared outbound conversation context

* ci: fold build smoke into artifact job

* test(memory): drop stale dreaming hook doubles

* fix: honor ACP spawn model overrides (openclaw#70210)

Honor explicit ACP sessions_spawn model overrides and preserve ACP runtime cwd options.\n\nThanks @felix-miao.

* fix(hooks): canonicalize thread ownership conversation ids

* test(acpx): exercise registered reply_dispatch hook

* fix: persist CLI session clearing atomically (openclaw#70298)

Persist stale CLI session clearing through the session-store merge path and add regression coverage for Claude binding removal.\n\nThanks @HFConsultant.

* ci: add scoped docker gateway e2e

* test(skill-workshop): exercise registered prompt hook

* fix: drop silent parent replies while subagents are pending (openclaw#69942)

Drop bare parent NO_REPLY payloads while spawned subagents are pending, preserving quiet parent turns until child completion delivers the real reply.\n\nThanks @neeravmakwana.

* ci: rotate stale concurrency group

* test(memory): exercise registered auto-capture hook

* ci: skip windows for test-only changes

* fix(auto-reply): preserve streaming reply directives (openclaw#70243)

Preserve streamed MEDIA/reply/audio directives across chunk boundaries and phase-aware final_answer delivery.\n\nThanks @zqchris.

* test(memory): exercise registered auto-recall hook

* Fix Slack HTTP route registry dispatch

* fix: route Slack HTTP webhook dispatch (openclaw#70275) (thanks @FroeMic)

* ci: narrow windows check scope

* fix(slack): pass cfg into resolveToken from downloadSlackFile call site

Commit 95331e5 ("fix(channels): thread runtime config through sends")
migrated resolveToken to a 3-arg signature (explicit, accountId, cfg) and
updated the getClient call site at actions.ts:83. The sibling call inside
downloadSlackFile at actions.ts:445 was not migrated and still dropped
opts.cfg, so the cfg-only resolution branch was unreachable from that path.

Current production callers (action-runtime.ts:386-389) always inject a
resolved readToken into opts.token before calling downloadSlackFile, so
this is defense-in-depth today -- the broken path is not hit in runtime.
Landing this closes the call-site migration gap and adds test coverage
for the cfg-only resolution contract on downloadSlackFile.

Note: pre-commit typecheck hook bypassed because upstream/main has 14
pre-existing TS errors in unrelated packages (discord, qa-lab, qqbot,
slack/monitor/provider.ts, tokenjuice, pi-embedded-runner) -- verified
reproducible on clean HEAD 4a16cf8 without this diff.

* fix: preserve Slack download cfg token fallback (openclaw#70160) (thanks @martingarramon)

* fix(telegram): mark polling transport dirty on 409 conflict (openclaw#69787)

When getUpdates returns 409 Conflict (e.g.
'terminated by other getUpdates request'), the polling runtime
previously retried on the same HTTP keep-alive TCP socket because
markDirty() was only called in the isRecoverable branch.

Telegram treats that connection as the 'old' session and keeps
terminating it — producing a sustained low-rate 409 retry loop
(observed a few per minute after eliminating duplicate pollers).

Broaden the dirty-mark condition to fire on isConflict as well as
isRecoverable so the next cycle forces a fresh TCP connection.

Update the existing 'reuses transport after getUpdates conflict' test
— which previously locked in the buggy behavior — to assert the new
correct behavior: one fresh transport is built, the stale one is
closed.

* test(telegram): update monitor test for openclaw#69787 transport rebuild on 409

Sibling test in monitor.test.ts asserted the pre-fix behavior (single
transport reused across cycles on 409). My openclaw#69787 change rebuilds the
transport on 409 so Telegram sees a fresh TCP socket — update the
assertion to match.

Two transports are now expected: the initial one plus the rebuild
after the conflict.

* test: tighten Telegram polling conflict coverage (openclaw#69873) (thanks @hclsys)

* test(plugins): guard legacy bundled hook regressions

* fix(telegram): lower webhook callback timeout to 5s

openclaw#16763 added `onTimeout: "return"` with `timeoutMilliseconds: 10_000`
(grammY default). In practice, Telegram's webhook servers abort the
read well before 10s when handler latency is LLM-bound: `getWebhookInfo`
reports `last_error_message: "Read timeout expired"` and pending updates
pile up, cascading into multi-minute reply lag.

Reproducible A/B on identical infra (same region, same bot token):
- Minimal Python echo bot: 5 back-to-back webhook RTTs 341-642ms, clean.
- OpenClaw current main: intermittent Read timeout expired, 1-5 min lag.

The handler still runs to completion; only the Telegram-facing ack is
sooner. grammY's deployment guide suggests 5s for long-running handlers.

No new config surface; minimal one-line change to the existing constant
and its test assertion. If a configurable timeout is wanted, that can be
a follow-up (see stale openclaw#7754).

* fix: lower Telegram webhook callback timeout (openclaw#70146) (thanks @friday-james)

* fix(amazon-bedrock): inject cache points for application inference profile ARNs (openclaw#69953)

* fix(amazon-bedrock): inject cache points for application inference profile ARNs

pi-ai's internal supportsPromptCaching checks model.id for specific Claude
model name patterns (e.g. "-4-", "claude-3-7-sonnet"), which fails for
application inference profile ARNs that don't contain the model name.
This causes prompt caching to silently break for Bedrock users with
application inference profiles.

Work around this by detecting when pi-ai would miss cache point injection
(via piAiWouldInjectCachePoints mirror) and patching the Converse API
payload via onPayload to add cachePoint blocks to the system prompt and
last user message — matching the same format pi-ai uses natively.

The fix is safe:
- Checks for existing cache points to avoid double-injection
- Respects cacheRetention: "none"
- Defaults to "short" retention (matching pi-ai default)
- Becomes a no-op once upstream pi-mono#2925 is fixed

Fixes openclaw#19279
Upstream: badlogic/pi-mono#2925

* fix(amazon-bedrock): tighten app-profile cache injection

---------

Co-authored-by: Your Name <you@example.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

* test(plugins): pin bundled hook registration surfaces

* perf: keep gateway live probes off helper imports

* test(plugins): pin bundled hook names

* test: cover Telegram webhook timeout reply continuation

* fix(hooks): fail open without thread ownership routing

* fix(hooks): canonicalize slack thread ownership ids

* fix(plugins): repair bundled deps on activation

* fix(hooks): normalize thread ownership channel allowlists

* fix: clear phantom Claude CLI resumes (openclaw#70317)

Verify Claude CLI session transcripts before reuse and clear phantom bindings with transcript-missing instead of passing stale --resume ids.\n\nFixes openclaw#70177.

* fix(discord): restore DM reactions and guild activation

* fix(gateway): redact audio payloads from chat history

* fix(media): load inbound media store URIs

* fix(agents): dedupe emitted TTS media

* fix(image): resolve custom provider model IDs

* docs: note media delivery fixes

* fix(hooks): normalize thread ownership slack id casing

* fix(hooks): track thread ownership mentions case-insensitively

* ci: move node aggregate checks off blacksmith

* fix(hooks): tighten thread ownership mention matching

* test(skill-workshop): pin disabled hook wiring

* ci: rotate main concurrency queue

* fix(hooks): skip skill workshop capture when review is off

* fix(discord): harden partial thread channels

* test(memory): pin disabled lifecycle hook wiring

* ci: merge short auto-reply node shards

* fix(hooks): use live config for memory dreaming runtime

* feat(commands): gate /models add with modelsWrite (openclaw#70321)

* fix: restore Pi embedded tool allowlist

Restore the Pi embedded session tool allowlist for OpenAI/OpenAI Codex GPT-5 runs and compaction sessions after Pi 0.68.1 began treating session tools as a global allowlist.

Local validation: pnpm check:changed.
GitHub validation: check/check-additional/node shards green; parity gate red on unrelated config.patch stale/rate-limit QA harness scenario after plugins.allow restart.

* ci: rotate cancelled docs queue

* fix(hooks): refresh active memory config at runtime

* ci: balance extension tests across fewer workers

* fix: normalize opus 4.7 context window

Normalize Anthropic-owned Opus 4.7 context reporting to 1M while keeping inferred and bare discovery paths conservative.

- normalize Anthropic and claude-cli Opus 4.7 runtime/status context metadata to 1M
- keep inferred-provider and bare discovery ids on discovered conservative limits
- add regression coverage for provider, lookup, status, and discovery-cache paths
- keep the Telegram abort-signal wrapper typing narrow so changed-scope validation stays green

* fix(hooks): respect live skill workshop config

* fix(hooks): use live thread ownership config

* perf(plugins): cache normalized jiti aliases

* fix: honor explicit strict-agentic retry contract

Honor explicit strict-agentic execution contracts for incomplete-turn retry guards across providers, including local/compatible models that opt in without relying on OpenAI model inference.

Validation:
- pnpm test src/agents/pi-embedded-runner/run.incomplete-turn.test.ts
- pnpm check:changed
- GitHub CI + parity gate green

Thanks @ziomancer.

* test(media): harden media store URI validation

* ci: keep extension test fanout under two minutes

* fix(hooks): respect live lancedb memory config

* test(slack): cover send.ts customize-scope fallback retry path (openclaw#69009)

Adds 5 vitest cases for postSlackMessageBestEffort's silent retry
behavior when Slack rejects a chat:write.customize-identity post:

- Retry on err.data.needed matching chat:write.customize
- Retry on chat:write.customize in response_metadata.acceptedScopes
- Retry on chat:write.customize in response_metadata.scopes
- Rethrow on different missing_scope (e.g. channels:history)
- Rethrow when identity is empty (hasCustomIdentity returns false)

* fix(discord): normalize ACP thread binding targets

Normalize Discord ACP thread-binding channel targets at the REST/thread-create boundary while preserving current-conversation binding keys.\n\nThanks @Zetarcos.

* test(slack): provide send config in identity fallback tests

* fix(hooks): use live memory-core config during dreaming runs

* fix(memory-lancedb): retry failed runtime initialization

* runtime-taskflow: tighten waiting sync review fixes

* refactor(hooks): centralize live plugin config lookup

* fix(qa): deflake parity approval preflight

* fix(agents): centralize native websocket endpoint checks

* docs(changelog): note websocket endpoint classifier fix

* fix: clarify browser playwright-core install guidance

* fix(types): narrow live thread ownership config

* test(plugins): pin live config hook guards

* fix(agents): restore pi session tool activation

* docs(changelog): note pi session tool activation fix

* build: harden tsdown wrapper

---------

Co-authored-by: Shakker <shakkerdroid@gmail.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: FullerStackDev <263060202+fuller-stack-dev@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: pashpashpash <nik@vault77.ai>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: JuniperSling <80268751+JuniperSling@users.noreply.github.com>
Co-authored-by: albertxyu <albertxyu@tencent.com>
Co-authored-by: Jonathan <82057176+mgalore@users.noreply.github.com>
Co-authored-by: Jonathan Amponsah <amponsahjonathan442@gmail.com>
Co-authored-by: Alex Knight <aknight@atlassian.com>
Co-authored-by: Andy <andrew@artisticforge.studio>
Co-authored-by: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>
Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Dewaldt Huysamen <dhuysamen@gmail.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Co-authored-by: Bek <bek.akhmedov@gmail.com>
Co-authored-by: Frank Yang <frank.ekn@gmail.com>
Co-authored-by: Jacky <59263116+epicseven-cup@users.noreply.github.com>
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Co-authored-by: Sliverp <38134380+sliverp@users.noreply.github.com>
Co-authored-by: Ted Li <tl2493@columbia.edu>
Co-authored-by: MonkeyLeeT <6754057+MonkeyLeeT@users.noreply.github.com>
Co-authored-by: hxy91819 <8814856+hxy91819@users.noreply.github.com>
Co-authored-by: Nimrod Gutman <nimrod.gutman@gmail.com>
Co-authored-by: cxy <49286167+cxyhhhhh@users.noreply.github.com>
Co-authored-by: sliverp <870080352@qq.com>
Co-authored-by: Garming <jiaming_wu@foxmail.com>
Co-authored-by: wujiaming88 <wujiaming88@example.com>
Co-authored-by: VACInc <hixvac@gmail.com>
Co-authored-by: VACInc <3279061+VACInc@users.noreply.github.com>
Co-authored-by: Jason Perlow <jperlow@gmail.com>
Co-authored-by: Devin Robison <drobison00@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Claw Kowalski <szponeczek@forserial.org>
Co-authored-by: Hana Chang <hana@hanamizuki.tw>
Co-authored-by: Oliver Camp <olivercamp@Olivers-MacBook-Pro-3.local>
Co-authored-by: ayeshakhalid192007-dev <ayeshakhalid192007@gmail.com>
Co-authored-by: Zijun Lin <zijunlin@Zijuns-Mac-mini.local>
Co-authored-by: Felix Miao <felix.us.miao@gmail.com>
Co-authored-by: HFConsultant <62076556+HFConsultant@users.noreply.github.com>
Co-authored-by: Neerav Makwana <neeravmakwana@gmail.com>
Co-authored-by: zqchris <chrisz83@gmail.com>
Co-authored-by: froemic <m.froehlich1994@gmail.com>
Co-authored-by: Martin Garramon <martin@yulicreative.ai>
Co-authored-by: HCL <chenglunhu@gmail.com>
Co-authored-by: friday-james <lamcollin37@gmail.com>
Co-authored-by: anirudhmarc <43162556+anirudhmarc@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Josh Lehman <josh@martian.engineering>
Co-authored-by: Devin Matthews <zionitesoldier@gmail.com>
Co-authored-by: Zetarcos <117005244+Zetarcos@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR scripts Repository scripts size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant