Commit Graph

87 Commits

Author SHA1 Message Date
Gustavo Madeira Santana
1777b99ccc Signal: move message actions behind plugin boundary 2026-03-18 03:19:35 +00:00
Gustavo Madeira Santana
9e8b9aba1f WhatsApp: isolate lazy action runtime boundary 2026-03-18 02:20:57 +00:00
Gustavo Madeira Santana
8165db758b WhatsApp: move action runtime into extension 2026-03-18 02:08:08 +00:00
Gustavo Madeira Santana
b3ae50c71c Slack: move action runtime into extension 2026-03-18 02:08:08 +00:00
Vincent Koc
77f145f1db docs(types): add JSDoc to plugin API capability registration methods
Label each registerX method with its capability type and add module-level
doc comment to channel runtime types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 15:00:33 -07:00
Peter Steinberger
6d9bf6de93 refactor: narrow extension public seams 2026-03-17 09:58:33 -07:00
Peter Steinberger
4b125762f6 refactor: clean extension api boundaries 2026-03-17 09:38:21 -07:00
Peter Steinberger
795f1f438b refactor: expose lazy runtime helper to plugins 2026-03-17 08:37:11 -07:00
Josh Lehman
1399ca5fcb fix(plugins): forward plugin subagent overrides (#48277)
Merged via squash.

Prepared head SHA: ffa45893e0
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-03-17 07:20:27 -07:00
Peter Steinberger
9648e7fecb refactor: consolidate lazy runtime surfaces 2026-03-17 00:59:20 -07:00
Peter Steinberger
52ad686ab5 refactor(runtime-tests): share typing lease assertions 2026-03-17 07:23:44 +00:00
Peter Steinberger
3dec814fda refactor: bundle lazy runtime surfaces 2026-03-17 00:00:45 -07:00
Peter Steinberger
38a6415a70 build: tighten lazy runtime boundaries 2026-03-16 23:24:17 -07:00
Peter Steinberger
e793e3873f refactor(whatsapp): reuse login tool implementation 2026-03-17 06:24:01 +00:00
Peter Steinberger
aa2d5aaa0c feat(plugins): add image generation capability 2026-03-16 22:58:55 -07:00
Vincent Koc
38bc364aed Runtime: narrow WhatsApp login tool surface 2026-03-16 21:39:21 -07:00
Peter Steinberger
4bba2888e7 feat(plugins): add web search runtime capability 2026-03-16 21:31:00 -07:00
Peter Steinberger
f4fa84aea7 feat(plugins): tighten media runtime integration 2026-03-16 21:13:51 -07:00
Peter Steinberger
c081dc52b7 feat(plugins): move media understanding into vendor plugins 2026-03-16 20:58:34 -07:00
Peter Steinberger
85781353ec feat(plugins): expand speech runtime ownership 2026-03-16 20:01:24 -07:00
Josh Lehman
eeb140b4f0 fix(plugins): late-binding subagent runtime for non-gateway load paths (#46648)
Merged via squash.

Prepared head SHA: 44742652c9
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-03-16 14:27:54 -07:00
Tak Hoffman
2de28379dd Plugins: remove public extension-api surface (#48462)
* Plugins: remove public extension-api surface

* Plugins: fix loader setup routing follow-ups

* CI: ignore non-extension helper dirs in extension-fast

* Docs: note extension-api removal as breaking
2026-03-16 15:51:08 -05:00
Vincent Koc
898d6840dc Runtime: lazy-load Telegram and Slack channel ops 2026-03-16 02:21:57 -07:00
Vincent Koc
abb21d9163 Runtime: lazy-load Discord channel ops 2026-03-16 02:07:13 -07:00
Peter Steinberger
f11589b311 refactor: tighten plugin sdk channel seams 2026-03-16 01:05:51 -07:00
Peter Steinberger
74d0c39b32 refactor: move session lifecycle and outbound fallbacks into plugins 2026-03-16 00:40:43 -07:00
Peter Steinberger
7964563299 refactor: finish plugin-owned channel runtime seams 2026-03-16 00:25:19 -07:00
Harold Hunt
aa1454d1a8 Plugins: broaden plugin surface for Codex App Server (#45318)
* Plugins: add inbound claim and Telegram interaction seams

* Plugins: add Discord interaction surface

* Chore: fix formatting after plugin rebase

* fix(hooks): preserve observers after inbound claim

* test(hooks): cover claimed inbound observer delivery

* fix(plugins): harden typing lease refreshes

* fix(discord): pass real auth to plugin interactions

* fix(plugins): remove raw session binding runtime exposure

* fix(plugins): tighten interactive callback handling

* Plugins: gate conversation binding with approvals

* Plugins: migrate legacy plugin binding records

* Plugins/phone-control: update test command context

* Plugins: migrate legacy binding ids

* Plugins: migrate legacy codex session bindings

* Discord: fix plugin interaction handling

* Discord: support direct plugin conversation binds

* Plugins: preserve Discord command bind targets

* Tests: fix plugin binding and interactive fallout

* Discord: stabilize directory lookup tests

* Discord: route bound DMs to plugins

* Discord: restore plugin bindings after restart

* Telegram: persist detached plugin bindings

* Plugins: limit binding APIs to Telegram and Discord

* Plugins: harden bound conversation routing

* Plugins: fix extension target imports

* Plugins: fix Telegram runtime extension imports

* Plugins: format rebased binding handlers

* Discord: bind group DM interactions by channel

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-15 16:06:11 -07:00
scoootscooob
439c21e078 refactor: remove channel shim directories, point all imports to extensions (#45967)
* refactor: remove channel shim directories, point all imports to extensions

Delete the 6 backward-compat shim directories (src/telegram, src/discord,
src/slack, src/signal, src/imessage, src/web) that were re-exporting from
extensions. Update all 112+ source files to import directly from
extensions/{channel}/src/ instead of through the shims.

Also:
- Move src/channels/telegram/ (allow-from, api) to extensions/telegram/src/
- Fix outbound adapters to use resolveOutboundSendDep (fixes 5 pre-existing TS errors)
- Update cross-extension imports (src/web/media.js → extensions/whatsapp/src/media.js)
- Update vitest, tsdown, knip, labeler, and script configs for new paths
- Update guard test allowlists for extension paths

After this, src/ has zero channel-specific implementation code — only the
generic plugin framework remains.

* fix: update raw-fetch guard allowlist line numbers after shim removal

* refactor: document direct extension channel imports

* test: mock transcript module in delivery helpers
2026-03-14 03:43:07 -07:00
Robin Waslander
a1520d70ff fix(gateway): propagate real gateway client into plugin subagent runtime
Plugin subagent dispatch used a hardcoded synthetic client carrying
operator.admin, operator.approvals, and operator.pairing for all
runtime.subagent.* calls. Plugin HTTP routes with auth:"plugin" require
no gateway auth by design, so an unauthenticated external request could
drive admin-only gateway methods (sessions.delete, agent.run) through
the subagent runtime.

Propagate the real gateway client into the plugin runtime request scope
when one is available. Plugin HTTP routes now run inside a scoped
runtime client: auth:"plugin" routes receive a non-admin synthetic
operator.write client; gateway-authenticated routes retain admin-capable
scopes. The security boundary is enforced at the HTTP handler level.

Fixes GHSA-xw77-45gv-p728
2026-03-11 14:17:01 +01:00
Xinhua Gu
4790e40ac6 fix(plugins): expose model auth API to context-engine plugins (#41090)
Merged via squash.

Prepared head SHA: ee96e96bb9
Co-authored-by: xinhuagu <562450+xinhuagu@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-03-09 16:07:26 -07:00
Peter Steinberger
fcdc1a13e1 fix: land #33992 from @darkamenosa
Co-authored-by: Tom <hxtxmu@gmail.com>
2026-03-08 04:49:04 +00:00
Josh Lehman
fee91fefce feature(context): extend plugin system to support custom context management (#22201)
* feat(context-engine): add ContextEngine interface and registry

Introduce the pluggable ContextEngine abstraction that allows external
plugins to register custom context management strategies.

- ContextEngine interface with lifecycle methods: bootstrap, ingest,
  ingestBatch, afterTurn, assemble, compact, prepareSubagentSpawn,
  onSubagentEnded, dispose
- Module-level singleton registry with registerContextEngine() and
  resolveContextEngine() (config-driven slot selection)
- LegacyContextEngine: pass-through implementation wrapping existing
  compaction behavior for 100% backward compatibility
- ensureContextEnginesInitialized() guard for safe one-time registration
- 19 tests covering contract, registry, resolution, and legacy parity

* feat(plugins): add context-engine slot and registerContextEngine API

Wire the ContextEngine abstraction into the plugin system so external
plugins can register context engines via the standard plugin API.

- Add 'context-engine' to PluginKind union type
- Add 'contextEngine' slot to PluginSlotsConfig (default: 'legacy')
- Wire registerContextEngine() through OpenClawPluginApi
- Export ContextEngine types from plugin-sdk for external consumers
- Restore proper slot-based resolution in registry

* feat(context-engine): wire ContextEngine into agent run lifecycle

Integrate the ContextEngine abstraction into the core agent run path:

- Resolve context engine once per run (reused across retries)
- Bootstrap: hydrate canonical store from session file on first run
- Assemble: route context assembly through pluggable engine
- Auto-compaction guard: disable built-in auto-compaction when
  the engine declares ownsCompaction (prevents double-compaction)
- AfterTurn: post-turn lifecycle hook for ingest + background
  compaction decisions
- Overflow compaction: route through contextEngine.compact()
- Dispose: clean up engine resources in finally block
- Notify context engine on subagent lifecycle events

Legacy engine: all lifecycle methods are pass-through/no-op, preserving
100% backward compatibility for users without a context engine plugin.

* feat(plugins): add scoped subagent methods and gateway request scope

Expose runtime.subagent.{run, waitForRun, getSession, deleteSession}
so external plugins can spawn sub-agent sessions without raw gateway
dispatch access.

Uses AsyncLocalStorage request-scope bridge to dispatch internally via
handleGatewayRequest with a synthetic operator client. Methods are only
available during gateway request handling.

- Symbol.for-backed global singleton for cross-module-reload safety
- Fallback gateway context for non-WS dispatch paths (Telegram/WhatsApp)
- Set gateway request scope for all handlers, not just plugin handlers
- 3 staleness tests for fallback context hardening

* feat(context-engine): route /compact and sessions.get through context engine

Wire the /compact command and sessions.get handler through the pluggable
ContextEngine interface.

- Thread tokenBudget and force parameters to context engine compact
- Route /compact through contextEngine.compact() when registered
- Wire sessions.get as runtime alias for plugin subagent dispatch
- Add .pebbles/ to .gitignore

* style: format with oxfmt 0.33.0

Fix duplicate import (ControlUiRootState in server.impl.ts) and
import ordering across all changed files.

* fix: update extension test mocks for context-engine types

Add missing subagent property to bluebubbles PluginRuntime mock.
Add missing registerContextEngine to lobster OpenClawPluginApi mock.

* fix(subagents): keep deferred delete cleanup retryable

* style: format run attempt for CI

* fix(rebase): remove duplicate embedded-run imports

* test: add missing gateway context mock export

* fix: pass resolved auth profile into afterTurn compaction

Ensure the embedded runner forwards resolved auth profile context into
legacy context-engine compaction params on the normal afterTurn path,
matching overflow compaction behavior. This allows downstream LCM
summarization to use the intended provider auth/profile consistently.

Also fix strict TS typing in external-link token dedupe and align an
attempt unit test reasoningLevel value with the current ReasoningLevel
enum.

Regeneration-Prompt: |
  We were debugging context-engine compaction where downstream summary
  calls were missing the right auth/profile context in normal afterTurn
  flow, while overflow compaction already propagated it. Preserve current
  behavior and keep changes additive: thread the resolved authProfileId
  through run -> attempt -> legacy compaction param builder without
  broad refactors.

  Add tests that prove the auth profile is included in afterTurn legacy
  params and that overflow compaction still passes it through run
  attempts. Keep existing APIs stable, and only adjust small type issues
  needed for strict compilation.

* fix: remove duplicate imports from rebase

* feat: add context-engine system prompt additions

* fix(rebase): dedupe attempt import declarations

* test: fix fetch mock typing in ollama autodiscovery

* fix(test): add registerContextEngine to diffs extension mock APIs

* test(windows): use path.delimiter in ios-team-id fixture PATH

* test(cron): add model formatting and precedence edge case tests

Covers:
- Provider/model string splitting (whitespace, nested paths, empty segments)
- Provider normalization (casing, aliases like bedrock→amazon-bedrock)
- Anthropic model alias normalization (opus-4.5→claude-opus-4-5)
- Precedence: job payload > session override > config default
- Sequential runs with different providers (CI flake regression pattern)
- forceNew session preserving stored model overrides
- Whitespace/empty model string edge cases
- Config model as string vs object format

* test(cron): fix model formatting test config types

* test(phone-control): add registerContextEngine to mock API

* fix: re-export ChannelKind from config-reload-plan

* fix: add subagent mock to plugin-runtime-mock test util

* docs: add changelog fragment for context engine PR #22201
2026-03-06 05:31:59 -08:00
Gustavo Madeira Santana
21e8d88c1d build: fix ineffective dynamic imports with lazy boundaries (#33690)
Merged via squash.

Prepared head SHA: 38b3c23d6f
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-03 20:14:41 -05:00
Peter Steinberger
9702d94196 refactor: split plugin runtime type contracts 2026-03-03 02:37:23 +00:00
Peter Steinberger
0fd77c9856 refactor: modularize plugin runtime and test hooks 2026-03-03 02:06:58 +00:00
Peter Steinberger
ebbb572639 fix: add requestHeartbeatNow runtime coverage (#19464) (thanks @AustinEral) 2026-03-03 01:40:31 +00:00
Austin Eral
40e5c6a18d feat(plugins): expose requestHeartbeatNow on plugin runtime
Add requestHeartbeatNow to PluginRuntime.system so extensions can
trigger an immediate heartbeat wake without importing internal modules.

This enables extensions to inject a system event and wake the agent
in one step — useful for inbound message handlers that use the
heartbeat model (e.g. agent-to-agent DMs via Nostr).

Changes:
- src/plugins/runtime/types.ts: add RequestHeartbeatNow type alias
  and requestHeartbeatNow to PluginRuntime.system
- src/plugins/runtime/index.ts: import and wire requestHeartbeatNow
  into createPluginRuntime()
2026-03-03 01:40:31 +00:00
Peter Steinberger
ee646dae82 fix: add runtime.events regression tests (#16044) (thanks @scifantastic) 2026-03-03 01:37:56 +00:00
SciFantastic
980388fcf0 plugin-sdk: expose onAgentEvent + onSessionTranscriptUpdate via PluginRuntime.events 2026-03-03 01:37:56 +00:00
benthecarman
faa4ffec03 Add runtime.stt.transcribeAudioFile for plugin STT access
Expose audio transcription through the PluginRuntime so external
plugins (e.g. marmot) can use openclaw's media-understanding provider
framework without importing unexported internal modules.

The new transcribeAudioFile() wraps runCapability({capability: "audio"})
and reads provider/model/apiKey from tools.media.audio in the config,
matching the pattern used by the Discord VC implementation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-02 21:43:01 +00:00
Peter Steinberger
bce643a0bd refactor(security): enforce account-scoped pairing APIs 2026-02-26 21:57:52 +01:00
Peter Steinberger
273973d374 refactor: unify typing dispatch lifecycle and policy boundaries 2026-02-26 17:36:16 +01:00
Peter Steinberger
e893157600 test(core): use lightweight clears in runtime and telegram setup 2026-02-22 08:09:14 +00:00
Peter Steinberger
bc6f983f85 fix(ci): resolve format drift and acp mock typing 2026-02-19 15:11:27 +00:00
Peter Steinberger
cc9be84b9c refactor(runtime): split runtime builders and stabilize cron tool seam 2026-02-19 16:09:56 +01:00
Peter Steinberger
2e421f32df fix(security): restore trusted plugin runtime exec default 2026-02-19 16:01:29 +01:00
Mariano
db73402235 Security: add explicit opt-in for deprecated plugin runtime exec (#20874)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: de69f81725
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
2026-02-19 11:30:36 +00:00
Mariano
45db2aa0cd Security: disable plugin runtime command execution primitive (#20828)
Co-authored-by: mbelinky <mbelinky@users.noreply.github.com>
2026-02-19 10:17:29 +00:00
Peter Steinberger
b8b43175c5 style: align formatting with oxfmt 0.33 2026-02-18 01:34:35 +00:00