Commit Graph

91 Commits

Author SHA1 Message Date
Peter Steinberger dceb2c343c refactor: retire due compat-ledger surfaces (context-engine host params, deactivate alias, logging internals) (#121845)
* refactor(plugins): retire deactivate hook alias

* refactor(plugin-sdk): prune retired facade exports

* test(logging): isolate logger test controls

* refactor(logging): internalize file transport controls

* test(plugin-sdk): preserve retired facade coverage

* test(auto-reply): remove stale diagnostic imports

* refactor(logging): delete dead config-read guard

shouldSkipMutatingLoggingConfigRead had no production caller even on main;
it survived the dead-export scan only via logger's testApi re-export. The
test-isolation commit removed that mask, exposing the fossil. Delete the
guard, its test-only re-export, its mock entry, and its dedicated test file.

* refactor(plugin-sdk): retire due compatibility subpaths

* test(plugin-sdk): type group policy predicates

* refactor(plugin-sdk): split removed subpath records

* refactor(secrets): remove retired collector barrel

* test(plugin-sdk): tighten wildcard surface pin

* refactor(plugin-sdk): retire matrix facade metadata

* style(plugin-sdk): format facade metadata

* fix(ci): load channel setup contracts from source

Repair the main-owned regression from 99d662473c (Peter Steinberger): the new env-contract test could consume stale ignored dist metadata instead of the checked-in plugin declaration.

* test(plugin-sdk): refresh API baseline after rebase
2026-08-12 12:41:27 -07:00
Mariano edb7a1692e fix(telegram): expose live location updates to hooks (#122185)
* fix(telegram): expose live location updates to hooks

* test(telegram): keep location coverage focused

* fix(telegram): emit stopped live locations

* test(plugin-sdk): refresh location hook contracts

* docs(changelog): note Telegram live location hooks

* fix(telegram): complete live-location observer path

---------

Co-authored-by: mbelinky <mbelinky@users.noreply.github.com>
2026-08-11 23:26:23 +02:00
Ayaan Zaidi 4c951398ef fix(messages): keep runtime details out of chat alerts (#121600)
Keep raw commands, paths, and provider errors out of ordinary chat while preserving explicit raw diagnostics and structured admin history.

Default command progress is status-only; `/verbose full` and `commandText: "raw"` retain diagnostic detail.

Co-authored-by: Ayaan Zaidi <hi@obviy.us>
2026-08-10 21:37:48 +05:30
Frank Yang 511ecd9dba fix(plugins): expose inbound message id before dispatch (#112359)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:26:28 +08:00
Naka Masato 68dbf92281 fix(plugins): scope Codex relay with tool matchers (#109603)
* fix(plugins): scope Codex relay matchers

Co-authored-by: Masato Naka <masatonaka1989@gmail.com>

* fix(plugins): reject sparse tool hook matchers

* test(plugins): cover mixed relay matcher scopes

* fix(plugins): fail closed on invalid policy matchers

* test(plugins): prove composed relay policy scope

* fix(plugins): keep matcher scope internal

* fix(plugins): satisfy matcher static checks

* fix(plugins): enforce canonical tool hook matchers

* fix(codex): project native hook matcher aliases

* fix(plugins): scope Codex relay with tool matchers

* chore: keep release changelog maintainer-owned

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:39:08 +08:00
Peter Steinberger 6dc13c63b6 fix(memory-core): adopt legacy dreaming jobs (#115986) 2026-07-29 12:26:43 -04:00
Vincent Koc 41f118cec3 fix(plugins): forward tool cancellation to hooks (#115817)
* fix(plugins): forward tool cancellation to hooks

* test(plugins): prove hook cancellation propagation
2026-07-29 22:54:01 +08:00
Hannes Rudolph 6dc55fa65e fix(plugins): recover user turns with scoped reply hooks (#114836)
Allow before_agent_reply plugins to declare host-enforced trigger eligibility so scheduled-only hooks do not block interrupted user-turn recovery. Keep omitted and malformed scopes fail-closed, scope both memory-core maintenance hooks, and cover three runner reload cycles through the public registration contract.

Refs: #111442

Source: #114836

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 17:22:16 +08:00
Vincent Koc bf91a5786c fix(plugins): enforce hook security invariants (#115701) 2026-07-29 16:10:34 +08:00
Vincent Koc 14940edf15 feat(skills): add Skill Workshop lifecycle hooks (#115606)
* feat(skills): add lifecycle hook contracts

* feat(plugins): expose skill hook contracts

* feat(plugins): identify skill evaluators

* feat(skills): persist proposal evaluation lifecycle

* feat(skills): add agent evaluation action

* feat(skills): emit committed skill lifecycle changes

* feat(gateway): expose skill proposal evaluation lifecycle

* feat(ui): add Skill Workshop evaluations

* fix(skills): bind lifecycle state to proposal revisions

* fix(skills): preserve lifecycle events without artifacts

* feat(cli): evaluate skill proposals

* fix(ui): bind evaluations to proposal revisions

* docs(skills): document lifecycle hook primitives

* chore(plugin-sdk): refresh skill hook surface

* fix(skills): harden proposal evaluator execution

* fix(plugins): isolate skill evaluator inputs

* fix(cli): align skill lifecycle deadlines

* fix(skills): preserve evaluation replay invariants

* test(ui): capture Skill Workshop evaluation proof

* fix(skills): bind apply to evaluated target tree

* fix(skills): preserve evaluation contract edges

* fix(skills): bound evaluation event storage

* chore(skills): keep lifecycle helpers internal

* refactor(skills): isolate evaluation persistence

* fix(skills): satisfy lifecycle validation gates

* chore(protocol): refresh Skill Workshop clients

* docs: refresh Skill Workshop map

* chore: keep release notes in PR metadata

* docs: refresh merged docs map

* fix(ci): type Code Mode catch errors

* fix(skills): freeze lifecycle observation payloads

* fix(protocol): keep proposal inspect backward-decodable

* fix(skills): enforce final evaluator bundle limits

* fix(skills): preserve lifecycle caller attribution

* chore: drop subsumed Code Mode formatting

* test(plugins): adapt lifecycle hook mocks
2026-07-29 15:49:44 +08:00
Peter Steinberger d41a56fca1 feat(memory): isolate curated entries by project (#115438)
* feat(memory): scope recall to active projects

* feat(memory): preserve project scope in promotion

* docs(memory): explain project-scoped recall

* fix(memory): chunk curated files per entry

* refactor(memory): narrow project scope internals

* fix(memory): exclude annotations from concept tags

* fix(memory): tighten project isolation boundaries

* fix(memory): preserve project path casing

* fix(memory): prioritize project bootstrap candidates

* docs: refresh memory architecture map

* test(memory): cover project scope schema repair

* fix(memory): complete project isolation paths

* fix(memory): close project ranking checks

* fix(memory): reinitialize search provider before ranking

* fix(memory): tolerate missing bootstrap paths
2026-07-28 23:55:49 -04:00
Peter Steinberger 28630a9a65 feat(memory): provenance-gated memory with dreaming on by default (#114819)
* feat(memory): add provenance and recall metadata to the memory index

* feat(memory): provenance-gated promotion and capture hygiene

* feat(dreaming): LLM consolidation with deterministic gates, on by default

* feat(active-memory): deterministic recall lane with escalation default

* feat(memory): user model file and standing intents

* docs(memory): document the memory architecture

* fix(memory): live-QA fixes — metadata writers, provenance classes, intent scope, claim accumulation
2026-07-28 06:04:25 -04:00
Peter Steinberger 1e9d918037 feat(sdk): always persist media facts and ship facts-first replacements for legacy Media* surfaces (#113355)
* feat(sdk): always persist media facts and ship facts-first replacements for legacy Media* surfaces

PR 1 of the media legacy retirement program (audit-frozen, 4 PRs).

- Every media-bearing user turn now persists normalized __openclaw.media
  facts unconditionally while continuing to emit the legacy top-level
  Media* projection byte-identically (dual-write bridge; the conditional
  shouldPersistStructuredMediaEntries gate now always includes media).
- New replacement APIs, shipped before any removal: typed hook media
  facts (media[], originalMedia[], mediaStagingPending) on message
  events; {{AttachmentPath}}/{{AttachmentUrl}}/{{AttachmentContentType}}/
  {{AttachmentDir}}/{{AttachmentIndex}} template variables; focused
  openclaw/plugin-sdk/media-local-roots subpath split out of the
  deprecated agent-media-payload facade.
- Every legacy surface carries @deprecated naming its replacement, under
  one named compatibility record media-legacy-projection with the
  operator-approved removeAfter 2026-10-01 (two release trains; deletion
  additionally gates on a clean published-plugin artifact sweep).
- Generic transcript append invariant documented; SDK migration, hooks,
  and configuration docs updated to the facts-first path.

Writer golden matrix proves legacy bytes and model prompt bytes are
unchanged while nested facts become unconditional. 2,189 broad media
tests green; SDK api-baseline regenerated on fresh-env Testbox.

* feat(sdk): register media-local-roots subpath exports and deprecation metadata

Completes PR 1: package export map for openclaw/plugin-sdk/media-local-roots
plus the deprecated-subpath inventory and doc metadata entries for the
media-legacy-projection record.

* chore(sdk): track media-local-roots entrypoint and deprecated-export budgets

* fix(sdk): keep deprecated MSTeams buildMediaPayload re-export through the compat window

Deleting shipped runtime-api re-exports belongs to retirement PR 4 after
the media-legacy-projection window; PR 1 only deprecates. Also formats
the migration-guide schedule table.

* docs: regenerate docs map for media migration additions
2026-07-24 10:42:17 -07:00
Peter Steinberger 98742bc2c7 feat(cron): stream schedule sources with durable source identity (#112387)
* feat(cron): stream schedule sources (supervised command stdout)

Add gated argv stream schedules with bounded line batching and trigger.streamBatch composition.

Reuse the gateway ProcessSupervisor for source ownership, deterministic teardown, capped restart backoff, and schedule-key guarded batch execution. Expose additive protocol, CLI, tool, UI, docs, and generated snapshot surfaces without storage DDL.

Contract: stream schedules are event-driven, require cron.triggers.enabled, reject command payloads, and retain at most one bounded pending batch.

* fix(cron): reject retired stream source epochs at run admission

Thread an invalidatable per-owner source-generation token (ownerNonce.generation)
through cron.run admission alongside the schedule key. A batch handed to cron.run
under one source epoch can wait behind another run while its owner is stopped; a
disable→re-enable or A→B→A edit leaves the schedule key unchanged, so the key
check alone would admit the retired epoch's batch. The token is persisted in
job.state on every lifecycle write and compared at every admission site plus the
executeJobCore guard, so a stale epoch's batch is skipped.

Also fix direct stream-job mutations recording the wrong lifecycle status when
global cron is off but triggers are on: extract resolveStreamStopReason so the
direct path reports the remediable cron-disabled state like reconcile does.

* fix(cron): close stream admission windows from round-10 review

- Persist the retired source generation before draining stop teardown, so a
  batch queued behind another cron run cannot gain admission during the up-to-10s
  in-flight-batch wait (server-cron routed stop path).
- Add streamSourceGeneration to the closed gateway response schema (excluded from
  the writable patch schema) so a running stream job passes strict result
  validation without letting callers spoof source identity.
- Close the mutation-epoch ABA: track an eviction epoch so a snapshotted absent-0
  is trusted as unchanged only when no LRU eviction happened during the await.

* refactor(cron): stream sources own a durable logical identity

Split the conflated restart-generation/admission token into two concepts:
a persisted streamSourceIdentity owned by cron store mutations (rotates on
enable/disable, source replacement, once-trigger auto-disable, and explicit
retirement; stable across supervised child restarts) and a watcher-local
process generation used only to fence stale child callbacks. Admission now
requires schedule key + identity together at every window, closing the
A-to-B-to-A and restart-flush races from review rounds 8-11.

Also: match-mode regexes now see raw source text (the [truncated] marker is
applied after matching), stop-timeout failures set the live restartExhausted
mirror so shutdown preserves the terminal diagnostic, and the watcher is
split into owner/output/registry modules under the max-lines budget.

* fix(cron): harden stream teardown and intake from round-4 review

An exit queued ahead of a requested stop no longer counts toward restart
exhaustion (the synchronous stop fence owns it), overlapping cron.stop and
stopAndDrain share one memoized shutdown drain instead of double-stopping
every owner, raw output intake is bounded at 4x the batch cap so normal
64 KiB pipe reads stop losing complete lines to OS chunk boundaries, and
persisted-shape quarantine coverage for unsafe match expressions is pinned.

* fix(cron): keep watcher-internal owner disposal from retiring live identity

Disposing an obsolete owner while a start replaces it is not a durable
removal; a retiring stop there rotated the live job's identity and stranded
the replacement behind the CAS ownership guard. Also align the docs with the
implemented match semantics: complete lines match on full text past the
batch cap, only intake-cut prefixes are unmatchable.

* fix(cron): make oversized-line matching independent of pipe chunking

Partial lines are retained up to the raw-intake bound rather than the
delivery cap, so a complete over-cap line matches identically whether it
arrives in one callback or several; only a line the intake bound itself cut
remains an unprovable prefix. Reconcile also contains schedule-replacement
stop failures per job, matching the other stop branches.

* fix(cron): bound assembled lines, drop stale payload override, barrier stopAll

- enforce the 4x raw-intake per-line cap while assembling split callbacks,
  so an oversized line stays an unprovable prefix regardless of chunking
- stop passing the watcher-cached payload as a cron.run override; the run
  snapshots the persisted payload under its admission lock
- stopAll waits for every owner stop to settle before surfacing failures
- split cron-stream-output interleaving tests into their own file (max-lines)

* fix(cron): address first full-CI round (lint, knip, schema test, unused param)

* chore(cron): refresh codex prompt snapshots for stream schedule schema

* fix(cron): keep the first clean line after an intake drop ending at a newline

* fix(cron): fence stream reconcile list snapshots against direct mutation routes

A cron.list snapshot captured across the reconcile await could be applied
after a direct add/update route already started the owner, stopping it as
removed and retiring its live identity. A mutation revision bumped at every
direct route start invalidates the stale snapshot; reconcile re-lists
(bounded) instead of applying it.

* style(cron): format stream owner imports

* fix(cron): discard severed stream prefixes at EOF

* fix(cron): retry failed stream shutdown drains

* fix(cron): honor stream stop fence after output drain

* chore(cron): refresh landing checks
2026-07-21 15:01:30 -07:00
Peter Steinberger c7e7ac2728 refactor: remove expired plugin compatibility surfaces (#111451)
* docs(secrets): remove retired web credential paths

* refactor(web): remove retired provider compatibility paths

* refactor(providers): delete retired compatibility routes

* refactor(secrets): remove retired credential aliases

* refactor(plugin-sdk): delete retired compatibility surfaces

* docs(plugin-sdk): remove retired migration guidance

* chore(plugin-sdk): refresh rebased surface budgets

* chore(plugin-sdk): refresh API removal baseline

* refactor(compat): migrate retired internal callers

* chore(plugin-sdk): refresh current-main baselines

* test(config): migrate plugin-owned secret assertions

* test(gateway): narrow plugin secret refs

* fix(plugin-sdk): preserve private boundary type identity

* chore(compat): remove stale sweep references

* chore(lint): lower max-lines budget

* refactor(secrets): remove unused web helper

* build(plugin-sdk): drop removed compat entries

* chore(plugin-sdk): refresh rebased API baseline

* chore(plugin-sdk): use Linux API baseline hash

* fix(plugin-sdk): preserve private bundled build entries

* fix(plugin-sdk): package private runtime facades

* fix(plugins): preserve external credential contracts
2026-07-19 11:04:48 -07:00
Peter Steinberger 4c55a4fc28 feat(plugins): expose requester context to tool hooks (#111190)
* feat(plugins): expose requester context to tool hooks

* chore(plugin-sdk): restore generated API baseline

* chore: drop release-owned changelog entry

* docs: refresh documentation map
2026-07-19 10:31:58 -07:00
Kyle Klouzal e316e1c440 feat(discord): show subagent progress (#95604)
* feat(discord): show subagent progress

Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>

* fix(discord): serialize progress cleanup ownership

Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>

* test(discord): type progress state fixtures

* refactor(discord): split subagent progress state

* fix(discord): persist terminal progress outcomes

* fix(discord): narrow persisted cleanup rows

* refactor(discord): keep progress internals private

* perf(discord): preserve lazy progress loading

* chore(plugin-sdk): refresh API baseline after rebase

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Kyle Klouzal <kklouzal@users.noreply.github.com>
2026-07-17 12:02:33 +01:00
Peter Steinberger dde90a345a refactor(plugin-sdk): narrow wildcard barrels to explicit used exports (#108440)
* refactor(plugin-sdk): narrow wildcard barrels to explicit used exports

* refactor(tools): delete dead tool-planning module exposed by barrel narrowing

* fix(plugin-sdk): restore deprecation tag on OpenClawSchemaType alias

* test(agents): drop test for deleted runtime proxy module

* refactor(tools): trim descriptor types to cache consumers

* refactor(deadcode): harvest exports orphaned by barrel narrowing

* refactor(deadcode): harvest exports orphaned by barrel narrowing (rest)

* fix(agents): restore sdk imports and test markers via public predicate

* fix(plugin-sdk): named type re-exports in plugin-entry; trim types barrel precisely

* chore(plugin-sdk): account unmasked deprecated provider types in budgets

* fix(plugins): name star-only type rows for dts bundling

* fix(plugins): restore host-hook surface; unexport internal api compositions

* fix(plugins): named type imports for api composition; restore needed source exports

* fix(plugins): knip-visible type imports for registry surfaces

* test: adapt tests to privatized media and command internals

* fix(qa-lab): re-export snapshot conversation type

* style: format sessions sdk imports

* fix(plugins): restore smoke entry export; pin budgets to exact actuals

* fix(plugins): canonical smoke-entry import; drop orphaned root shims

* fix(plugins): allowlist manifest probe, repoint qa web import, drop dead browser barrels

* fix(plugin-sdk): pin codex auth marker and scaffold provider type

* fix(qa-lab): keep web-facing model-selection shim within boundary rules

* fix(plugin-sdk): preserve merged contracts through narrowed barrels

* chore(plugin-sdk): pin post-rebase surface budgets
2026-07-16 00:45:23 -07:00
Peter Steinberger f81f9d8570 chore: enforce max-lines suppression ratchet (#107315)
* ci: enforce max-lines suppression ratchet

* chore: prune stale max-lines suppression

* fix: close max-lines ratchet enforcement gaps

* fix: harden max-lines ratchet checks

* fix(ci): satisfy max-lines ratchet checks

* style: format max-lines declarations

* fix(ci): match oxlint suppression grammar

* test: isolate max-lines git fixtures

* chore: prune resolved max-lines debt

* test: skip newline path fixture on Windows

* fix: harden max-lines suppression ratchet

* chore: refresh max-lines baseline

* fix: close max-lines ratchet bypasses

* fix: derive ratchet base from PR merge tree

* fix: support older Git in staged ratchet

* fix: align max-lines declarations and baseline

* chore: refresh max-lines baseline for current main

* fix: exclude generated wizard locales from max-lines

* chore: prune resolved max-lines debt
2026-07-14 09:27:02 -07:00
Peter Steinberger 7875dd97a1 fix(cron): abort superseded reconciliation hooks (#104368)
* fix(cron): abort superseded reconciliation hooks

* fix(ci): align plugin SDK surface budget
2026-07-11 03:16:59 -07:00
Peter Steinberger 49b58288d3 feat(plugins): add cron reconciliation lifecycle hook (#104191)
* feat(plugins): add cron reconciliation lifecycle hook

* chore(plugin-sdk): refresh api baseline

* fix(plugin-sdk): update public export budget
2026-07-10 23:05:12 -07:00
Peter Steinberger 2d7472b3e4 fix(cron): emit scheduled events after durable wake changes (#103647)
* fix(cron): emit scheduled events after durable wake changes

* chore(changelog): defer cron note to release

* chore(docs): refresh plugin SDK baseline
2026-07-10 17:39:23 +01:00
Peter Steinberger 0d981095d4 refactor(codex): store app-server thread bindings in SQLite plugin state (#101210)
* test(codex): shorten placeholder auth fixture strings

* feat(plugin-state): add reject-new overflow policy for keyed namespaces

* feat(agents): thread agent identity and session generation through reset and hooks

* refactor(codex): add SQLite-backed app-server thread binding store

* refactor(codex): move app-server runtime callers onto the binding store

* refactor(codex): move conversation, entry, and thread-tool flows onto the binding store

* refactor(codex): move command handlers onto the binding store

* feat(codex): import legacy binding sidecars via doctor state migration

* fix(codex): keep doctor sidecar scan inside stateDir

* fix(codex): make binding migration landable

* chore(changelog): defer release note

* test(plugin-state): stabilize durable-capacity ordering
2026-07-07 03:03:44 +01:00
clawSean d84aabf642 feat: add channel pairing request hook (#97733)
* feat: add channel pairing request hook

* fix(plugin-sdk): keep pairing hook types internal

* docs: regenerate docs map

* docs: regenerate docs map

* docs: regenerate docs map

* fix(plugin-sdk): keep pairing hook types internal

* fix(plugin-sdk): keep pairing hook types internal

* docs: refresh plugin hook docs

* docs: refresh plugin hook docs

* docs: refresh plugin hook docs

---------

Co-authored-by: clawSean <260045960+clawSean@users.noreply.github.com>
Co-authored-by: Omar Shahine <omarshahine@users.noreply.github.com>
2026-07-05 19:11:58 -07:00
Cameron Beeley 68bfa42b9b feat(cron): on-exit cron schedule kind — fire a job when a watched command exits
Adds an `on-exit` cron schedule kind: a job fires once when a watched command/process
exits, via gateway ProcessSupervisor exit watchers. Covers CLI (`--on-exit`/`--on-exit-cwd`),
tool/protocol schema, RPC list-filter, Control UI + macOS read-only display, SQLite
round-trip, and origin-aware wake routing. Restart-safe one-shot (persists completion
before firing); platform-aware shell; bounded watched-command execution.

Squashed from 22 iterative commits for a clean rebase onto current main.
2026-07-01 10:47:01 -07:00
兰之 bd479958c0 feat(plugin-sdk): add extensible channel identity hook context (#91903)
Merged via squash.

Prepared head SHA: 90f51eafd5
Co-authored-by: lanzhi-lee <36190508+lanzhi-lee@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-23 11:56:49 +08:00
sandieman2 c67dc59b02 fix(reply): deliver final reply when queued follow-up claims session; scope dedupe to routed thread (#90943)
* fix(reply): deliver final reply when queued follow-up claims session; scope dedupe to routed thread

Two core bugs caused composed replies to be silently dropped (no delivery,
no error) when a second message arrived in the same thread mid-run:

1. dispatch-from-config: ensureDispatchReplyOperation only kept the
   dispatch-owned operation authoritative while it had no result. Once
   runReplyAgent completed the operation to drain queued follow-ups, a
   second same-thread inbound could claim the session and the first final
   reply would try to re-acquire the lane instead of finishing delivery,
   deadlocking behind the queued work. Keep the dispatch-owned operation
   authoritative through final delivery.

2. reply-payloads-dedupe: messaging-tool reply dedupe compared only the
   channel target, not the routed thread, so a send in one thread could
   suppress a later reply in a different thread. Thread the routed thread
   id through buildReplyPayloads + follow-up delivery and only fall back to
   channel-only matching for providers without a thread-aware suppression
   matcher when neither side carries thread evidence.

Adds regression tests; existing Telegram topic-suppression behavior is
preserved by gating the thread guard to providers lacking a plugin matcher.

* fix(reply): preserve threaded message delivery evidence

* fix(reply): dedupe final payloads by delivery route

* fix(slack): preserve native send thread evidence

* fix(reply): preserve explicit reply thread evidence

* fix(reply): align explicit reply route dedupe

* fix(reply): preserve delivery lane through final dispatch

* fix(mattermost): preserve threaded tool send routes

* chore(plugin-sdk): refresh API baseline

* fix(reply): align final delivery route dedupe

* fix(reply): gate followups on final delivery

* fix(reply): keep send receipts private

* fix(reply): infer implicit message provider

* fix(reply): align routed threading policy

* fix(reply): preserve queued delivery context

* fix(reply): hydrate queued system event routes

* fix(reply): hydrate queued execution routes

* fix(reply): scope final delivery barriers

* fix(slack): preserve DM target aliases

* fix(reply): mirror resolved source thread routes

* fix(mattermost): retain delayed delivery barrier

* fix(codex): separate message routing from tool policy

* fix(reply): consume normalized Slack DM targets once

* fix(slack): remove stale target alias

* style(reply): satisfy changed lint gates

* fix(mattermost): preserve explicit reply targets

* test: align Slack reply branch checks

* fix(reply): persist overflow summaries to admitted session

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-14 09:11:05 -07:00
Ayaan Zaidi 1c655008cd fix(hooks): tighten reply usage state correlation 2026-06-13 14:25:24 +05:30
Peter Lindsey 56f2102c28 fix(usage): thread real context occupancy + last-call usage into usageState
context.used_tokens / pct_used were derived from the snapshot's aggregate
prompt total (cacheRead+cacheWrite+input). Over a multi-call tool-loop turn
that is the run AGGREGATE, overstating window occupancy (often past 100%) so a
footer's context gauge pins full while /status shows the true ~7%.

Add two optional fields to PluginHookReplyUsageState and populate them in the
reply path:
- contextUsedTokens: the final call's prompt size (agentMeta.promptTokens) =
  real end-of-turn occupancy, a point-in-time state, not the aggregate.
- lastUsage: the final model call's usage only (vs `usage`, the turn
  aggregate), so a footer can render the last exchange's i/o + cache.

Both optional and additive; consumers fall back to the aggregate when absent
(correct for single-call turns). Renderer consumption lands separately (#89835).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:25:24 +05:30
Peter Lindsey 0dbfa1f6be fix(hooks): make usageState limits credential-aware + document best-effort delivery
Addresses review feedback on #89629.

1) Provider-limit resolution no longer defaults to OAuth. getProviderUsageLimits
   and getProviderUsageLimitsCached resolved with `credentialType ?? "oauth"`, and
   the agent-runner snapshot call passed no credential type, so an api-key OpenAI
   turn could borrow cached OAuth/ChatGPT usage windows. Drop the "oauth" default
   (missing credential type => no OpenAI usage provider) and thread the turn's
   authMode through at the call site. Adds provider-usage.limits.test.ts covering
   api-key/no-credential (no fetch), oauth/token (resolves), and non-OpenAI.

2) usageState is documented as best-effort, present only on live dispatcher
   delivery. Routed durable and recovered queue replays re-run this hook as a
   stateless transform over the original payload (see QueuedDeliveryPayload); a
   point-in-time usage snapshot is not stateless and would replay stale after a
   restart, so it is intentionally omitted there. Consumers must treat the field
   as optional.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:25:24 +05:30
Peter Lindsey f06f2f17c2 feat(hooks): per-turn usageState (with provider limits + rich atoms) on reply_payload_sending
Attach a per-turn execution snapshot to the reply_payload_sending hook as
`usageState`, so a plugin (or the future in-core /usage renderer) can render a
per-response usage readout as a pure consumer of the contract — no side calls.

Recorded in agent-runner, consumed in dispatch. Fields: provider, model,
resolvedRef/requested, reasoningEffort, fastMode, fallbackUsed, is_override
(overrideSource), authMode, compactionCount, contextTokenBudget, token usage,
turn cost (USD), duration, owning agentId/sessionId, chatType, the agent
identity (name/emoji), and the active provider's subscription `limits` windows.

reply_payload_sending is the one reply hook universal across every surface
(incl. the Codex app-server, which emits no llm_output/agent_end), so it is the
correct harness-agnostic place for per-turn usage. Limits are resolved by a
core-internal non-blocking SWR helper (src/infra/provider-usage.limits.ts) and
attached to the snapshot — no new plugin-SDK accessor. All fields optional/additive.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:25:24 +05:30
Vincent Koc 60e818f563 fix(agents): forward channel identity to CLI hooks 2026-06-11 19:33:00 +09:00
Ayaan Zaidi c84e521920 refactor(discord): distill reply hydration tests 2026-06-10 14:54:32 +05:30
FullerStackDev b08eef0508 fix(discord): hydrate reply context metadata 2026-06-10 14:54:32 +05:30
Vincent Koc e2524e0438 fix(ci): break plugin import cycles 2026-06-07 19:03:38 +09:00
Peter Steinberger 797bcd5bdb fix: propagate ClickClack toolsAllow through replies
Propagate ClickClack account-level runtime tool allowlists through inbound reply dispatch so restricted ClickClack accounts keep their tool policy when model/agent replies are generated.

This threads `toolsAllow` through shared dispatch, provider wrappers, embedded agent execution, and ACP hook events. ACP-bound sessions now fail closed for restrictive runtime allowlists because ACPX cannot enforce per-turn tool allowlists on reused persistent sessions.

Verification:
- Live ClickClack E2E on Crabbox AWS `run_6a0472ed7e71`, provider `aws`, id `cbx_dace25addcaa`.
- `node scripts/run-vitest.mjs run src/auto-reply/reply/dispatch-acp.test.ts src/plugin-sdk/acp-runtime.test.ts src/auto-reply/reply/dispatch-from-config.reply-dispatch.test.ts src/auto-reply/dispatch.test.ts src/auto-reply/reply/agent-runner-execution.test.ts src/auto-reply/reply/provider-dispatcher.test.ts extensions/clickclack/src/inbound.test.ts --reporter=verbose`
- Crabbox changed gate `run_d32af37fb265`, provider `aws`, id `cbx_8236876017c9`: `corepack pnpm check:changed`
- Autoreview clean: `.agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main`

Supersedes #89500.

Co-authored-by: Michael Appel <mappel@nvidia.com>
2026-06-05 08:40:35 -07:00
Peter Steinberger a6d084113a docs: document plugin install helpers 2026-06-04 04:15:33 -04:00
兰之 10d10faa25 feat(plugin-sdk): add resolve_exec_env hook
Summary:
- Add the plugin SDK `resolve_exec_env` hook for bounded exec environment contributions.
- Wire resolved exec env through exec preparation/final execution without exposing plugin env values to generic tool hooks.
- Cover lazy exec loading, host and command rewrites, node/gateway execution, filtering, and EXEC shell snapshot cache behavior.

Verification:
- `pnpm changed:lanes --json`
- `node scripts/run-vitest.mjs src/agents/bash-tools.exec.resolve-env-hook.test.ts src/agents/agent-tool-definition-adapter.test.ts src/agents/agent-tool-definition-adapter.after-tool-call.test.ts src/agents/shell-snapshot.test.ts src/plugins/hook-resolve-exec-env.test.ts`
- `pnpm check:test-types`
- `pnpm lint src/agents/bash-tools.exec.ts src/agents/bash-tools.exec.resolve-env-hook.test.ts`
- `.agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main`
- PR CI clean on 1bbad8d071: https://github.com/openclaw/openclaw/actions/runs/26817910293

Co-authored-by: Lanzhi <lizhan3@xiaomi.com>
2026-06-02 08:00:42 -04:00
Ted Li 6cb06f5fbc fix(reply): preserve sessions_send external routes (#88803)
* fix(reply): preserve sessions_send external routes

* fix(reply): preserve inherited route thread ids

* fix(reply): keep sessions_send delivery single-owner

* fix(reply): satisfy dispatch route lint

* fix(reply): preserve inherited ACP route metadata

* test(reply): type inherited route event assertions

* test(ci): satisfy current lint rules

* fix(reply): avoid stale inherited route threads

* fix(reply): trust explicit inherited route threads

* fix(reply): require trusted route thread sources

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-05-31 23:43:05 -04:00
Andy Ye 921598442a fix(hooks): expose inbound reply metadata before dispatch
Fixes #88521.

Expose finalized inbound reply metadata on plugin-visible hook payloads so before_dispatch and message hooks can implement reply-aware behavior without channel-specific workarounds.
2026-05-31 22:15:17 -04:00
Peter Steinberger 4c33aaa86c refactor: unify OpenAI provider identity (#88451)
* refactor: unify OpenAI provider identity

* refactor: move legacy oauth sidecar doctor helpers

* test: align OpenAI fixtures after rebase

* test: clean OpenAI provider unification

* fix: finish OpenAI provider cleanup

* fix: finish OpenAI cleanup follow-through

* fix: finish OpenAI CI cleanup
2026-05-31 00:29:44 +01:00
Peter Steinberger 3fc0df953c refactor(agents): bind subagent threads in core (#88416)
Move subagent thread binding ownership into core so session-mode spawns prepare channel bindings before launching the child agent. Deprecate the legacy subagent_spawning SDK hook in code, compatibility metadata, diagnostics, and plugin docs; plugin authors should observe subagent_spawned instead.

Verification:
- node scripts/run-vitest.mjs src/agents/sessions-spawn-hooks.test.ts src/agents/subagent-spawn.thread-binding.test.ts src/agents/subagent-spawn.workspace.test.ts src/agents/subagent-spawn.mode-session-diagnostics.test.ts
- node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo
- git diff --check
- .agents/skills/autoreview/scripts/autoreview --mode local
- CI run 26693808952 green, including checks-node-agentic-agents-core and checks-node-agentic-plugin-sdk
2026-05-30 21:19:09 +01:00
guanbear 044f5a814e Expose subagent resolved model metadata (#80037)
Co-authored-by: guanbear <guanbear@macmini.bearhome>
2026-05-30 18:52:21 +01:00
Rob Pierson b474f429ee feat(plugin-sdk): add reply payload sending hook (#82823)
* feat(plugin-sdk): add reply payload sending hook

* fix(dispatch): compose caller beforeDeliver with plugin hooks instead of nullish-coalescing

ClawSweeper review identified that Telegram's identity beforeDeliver
would skip reply_payload_sending and message_sending hooks entirely.
Now we always compose caller-provided hooks with global plugin hooks
so plugins get a chance to run even when the caller already supplies
a beforeDeliver hook.

Also adds regression test for composition case.

* test(dispatch): align beforeDeliver hook assertion with current context

* fix(plugin-sdk): remove leftover merge markers from hook types

* feat(plugin-sdk): add reply payload sending hook

* fix(plugin-sdk): protect reply payload media trust

* fix(auto-reply): honor suppressed routed ACP blocks

* fix(auto-reply): avoid double message sending hooks

* fix(auto-reply): require routed reply kind

* test(auto-reply): type routed suppression mock

* fix(auto-reply): honor reply payload hooks in followups

* fix(auto-reply): suppress empty hooked dispatcher replies

* fix(auto-reply): wire reply payload hooks at dispatcher boundary

* fix(plugins): preserve reply payload metadata in hooks

* fix(auto-reply): defer reply hook availability checks

* fix(auto-reply): preserve message hook order for routed payloads

* fix(auto-reply): persist routed payload hook decisions

* fix(auto-reply): run routed payload hooks inside delivery

* fix(auto-reply): enforce message hooks after payload edits

* fix(auto-reply): gate source reply mirrors on delivery

* fix(auto-reply): scope hook-mutated media delivery

* chore(plugin-sdk): refresh reply hook api baseline

* fix(auto-reply): mirror delivered source replies

---------

Co-authored-by: Rob via OpenClaw <noreply@openclaw.local>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-05-29 07:15:10 +01:00
Kevin Lin bb752c2b47 Revert "feat: expose plugin approval action metadata" (#87419)
This reverts commit 0c867eef75.

# Conflicts:
#	docs/.generated/plugin-sdk-api-baseline.sha256
2026-05-27 14:48:06 -07:00
Peter Steinberger bb46b79d3c refactor: internalize OpenClaw agent runtime (#85341)
* refactor: extract agent core package

Introduce packages/agent-core as the OpenClaw-owned home for reusable agent loop, harness, session, prompt, and runtime dependency contracts.

* refactor: extract shared llm runtime

Move provider model registries, stream wrappers, OAuth helpers, and LLM utilities into src/llm with plugin-sdk barrels instead of depending on the old embedded runtime layout.

* refactor: remove pi runtime internals

Rename remaining Pi-shaped agent surfaces to OpenClaw agent runtime names, delete obsolete Pi docs and package graph checks, and add the third-party notice for incorporated code.

* refactor: tighten agent session runtime

Make agent-core/runtime dependencies explicit, consolidate compaction and session transcript helpers, and move model/session helpers behind OpenClaw-owned contracts.

* refactor: remove static model and pi auth paths

Drop static model catalogs and Pi auth bridges, move model/provider facts to manifest-owned runtime contracts, and harden internal embedded-agent utilities.

* refactor: remove legacy provider compat paths

* docs: remove agent parity notes

* fix: skip provider wildcard metadata parsing

* refactor: share session extension sdk loading

* refactor: inline acpx proxy error formatter

* refactor: fold edit recovery into edit tool

* fix: accept extension batch separator

* test: align startup provider plugin expectations

* fix: restore provider-scoped release discovery

* test: align static asset packaging expectations

* fix: run static provider catalogs during scoped discovery

* fix: add provider entry catalogs for scoped live discovery

* fix: load lightweight provider catalog entries

* fix: refresh provider-scoped plugin metadata

* fix: keep provider catalog entries on release live path

* fix: keep static manifest models in release live checks

* fix: harden release model discovery

* fix: reduce OpenAI live cache probe reasoning

* fix: disable OpenAI cache probe reasoning

* ci: extend OpenAI gateway live timeout

* fix: extend live gateway model budget

* fix: stabilize release validation regressions

* fix: honor provider aliases in model rows

* fix: stabilize release validation lanes

* fix: stabilize release memory qa

* ci: stabilize release validation lanes

* ci: prefer ipv4 for live docker node calls

* fix: restore shared tool-call stream wrapper

* ci: remove legacy pi test shard alias

* fix: clean up embedded agent test drift

* fix: stabilize runtime alias status

* fix: clean up embedded agent ci drift

* fix: restore release ci invariants

* fix: clean up post-rebase runtime drift

* fix: restore release ci checks

* fix: restore release ci after rebase

* fix: remove stale pi runtime path

* test: align compaction runtime expectations

* test: update plugin prerelease expectations

* fix: handle claude live tool approvals

* fix: stabilize release validation gates

* fix: finish agent runtime import

* test: finish post-rebase agent runtime mocks

* fix: keep codex compaction native

* fix: stabilize codex app-server hook tests

* test: isolate codex diagnostic active run

* test: remove codex diagnostic completion race

# Conflicts:
#	extensions/codex/src/app-server/run-attempt.test.ts

* ci: fix full release manifest performance run id

* refactor: narrow llm plugin sdk boundary

* chore: drop generated google boundary stamps

* fix: repair rebase fallout

* fix: clean up rebased runtime references

* fix: decode codex jwt payloads as base64url

* fix: preserve shipped pi runtime alias

* fix: add scoped sdk virtual modules

* fix: decode llm codex oauth jwt as base64url

* fix: avoid stale vertex adc negative cache

* fix: harden tool arg decoding and codeql path

* fix: keep vertex adc negative checks live

* refactor: consolidate codex jwt and edit helpers

* fix: await codex oauth node runtime imports

* fix: preserve sdk tool and notice contracts

* fix: preserve shipped compat config boundaries

* fix: align codex oauth callback host

* fix: terminate agent-core loop streams on failure

* fix: keep codex oauth callback alive during fallback

* ci: include session tools in critical codeql scans

* fix: keep Cloudflare Anthropic provider auth header

* docs: redirect legacy pi runtime pages

* fix: honor bundled web provider compat discovery

* fix: protect session output spill files

* fix: keep legacy agent dir env blocked

* fix: contain auto-discovered skill symlinks

* fix: harden agent core sdk proxy surfaces

* fix: restore approval reaction sdk compat

* fix: keep live docker runs bounded

* fix: keep codex oauth redirect host aligned

* fix: resolve post-rebase agent runtime drift

* fix: redact anthropic oauth parse failures

* fix: preserve responses strict tool shaping

* fix: repair agent runtime rebase cleanup

* docs: redirect retired parity pages

* fix: bound auto-discovered resources to roots

* fix: repair post-rebase agent test drift

* fix: preserve bundled provider allowlist migration

* fix: preserve manifest-owned provider aliases

* fix: declare photon image dependency

* fix: keep provider headers out of proxy body

* fix: preserve shipped env aliases

* fix: refresh control ui i18n generated state

* fix: quote read fallback paths

* fix: preview edits through configured backend

* test: satisfy core test typecheck

* fix: preserve ZAI usage auth fallback

* test: repair codex diagnostic test

* fix: repair agent runtime rebase drift

* test: finish embedded runner import rename

* fix: repair agent runtime rebase integrations

* test: align compaction oauth fallback expectations

* fix: allow sdk-auth session models

* fix: update doctor tool schema import

* fix: preserve bedrock plugin region

* fix: stream harmony-like prose immediately

* ci: include session runtime in codeql shards

* fix: repair latest rebase integrations

* fix: honor explicit codex websocket transport

* fix: keep openai-compatible credentials provider-scoped

* fix: refresh sdk api baseline after rebase

* fix: route cli runtime aliases through openclaw harness

* test: rename stale harness mock expectation

* test: rename embedded agent overflow calls

* test: clean embedded auth test wording

* test: use openclaw stream types in deepinfra cache test

* fix: refresh sdk api baseline on latest main

* fix: honor bundled discovery compat allowlists

* fix: refresh sdk api baseline after latest rebase

* fix: remove stale rebase imports

* test: rename stale model catalog mock

* test: mock renamed doctor runtime modules

* fix: map canonical kimi env auth

* fix: use internal model registry in bench script

* fix: migrate deepinfra provider catalog entry

* fix: enforce builtin tool suppression

* fix: route compaction auth and proxy payloads safely

* refactor: prune unused llm registry leftovers

* test: update codex hooks session import

* test: fix model picker ci coverage

* test: align model picker auth mock types
2026-05-27 19:24:04 +01:00
Pablo Guardiola 0c867eef75 feat: expose plugin approval action metadata
Expose plugin approval action metadata so plugins can describe richer approval actions across gateway, SDK, channel, and UI surfaces.
2026-05-26 22:46:09 -07:00
Kaspre 1e1e45b72b fix(code-mode): align outer exec hook params 2026-05-22 09:46:27 +01:00
Peter Steinberger 02182d5a30 refactor: remove sender owner tool gating 2026-05-21 15:14:48 +01:00
Peter Steinberger 8477a67faf refactor(channels): unify session route projection 2026-05-19 00:49:25 +02:00