* fix(agents,cron): remove pattern field from model-facing cron tool schema
Fixes#107449
* fix(agents): regenerate prompt snapshots for cron schema pattern removal
Remove "pattern": "\\S" from the declarationKey field in the
model-facing cron tool schema across all three codex dynamic-tools
snapshot fixtures. This aligns the committed prompt contract with
the runtime schema change that removed the unanchored pattern
constraint incompatible with llama.cpp.
* test(cron): lock llama.cpp schema boundary
Co-authored-by: 李健0668000722 <li.jian21@xydigit.com>
* docs(changelog): place cron fix in release tail
Co-authored-by: 李健0668000722 <li.jian21@xydigit.com>
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Phase 3 of #107237. Removes config.apply/config.patch/restart from the
regular-agent gateway tool (mirroring Phase 2's update.run removal); only
config.get and config.schema.lookup reads remain. Persistent config changes
and restarts now go exclusively through the human-approved openclaw
delegation path — closing the last unmediated agent config-write surface.
gateway stays owner-only/control-plane gated (config reads expose secrets and
host topology). Legacy setups can re-enable writes via the existing per-agent
tool allowlist; no new config key. Net -2271 LOC.
Refs #107237
New openclaw delegation tool relays to openclaw.chat in-process; persistent
writes surface through the existing durable operator-approval registry as a
third system-agent kind (no parallel store), armed only by a human operator
in the Control UI — a delegated agent can never self-approve. Setup wizards
(channel/model/open-setup/open-tui) are refused in delegated mode so a
machine agent cannot complete setup or persist credentials unattended.
Vendor-neutral inference fallback ladder (requester route first, then other
authed providers by provider id). update.run removed from the gateway tool.
Caveman system-prompt fragment steers config/channels/plugins/agents/updates
to the openclaw tool. Doctor-owned state migration widens the approval-kind
constraint; runtime stays canonical-only.
Refs #107237
* fix(codex): use structured turn status for aborts, repair tool schemas, relay native results to middleware
- turn aborts are detected from the correlated turn/completed status instead
of byte-matching private codex-rs prose; the <turn_aborted> marker remains a
non-terminal user-interrupt hint (tags only, wording-independent) because the
app-server collapses all abort reasons into "interrupted" (#99268)
- dynamic-tool schemas are repaired before projection via the shared OpenAI
normalizer: annotation nulls stripped, type:null inferred from object/array
shape hints; unrepairable null constraints stay quarantined instead of
widening the schema (#106277, #97913)
- Codex-native tool results now flow through agentToolResultMiddleware at the
post_tool_use relay boundary (observe-only: the Codex PostToolUse contract
cannot replace a native tool response) (#95597)
* test(codex): regenerate prompt snapshots for normalized dynamic-tool schemas
The shared OpenAI strict-compat normalization now runs on Codex dynamic tools,
so empty object schemas gain additionalProperties:false and required:[] in the
snapshot payloads, matching what the OpenAI provider family sends.
New grouped sessions tool (patch: label/pin/archive/model/thinking; group
CRUD; owner-gated; no reset/delete/compact). sessions_spawn gains visible +
worktree via sessions.create with admission reservation and abort-confirmed
rollback; a started run with no run id is aborted and deleted rather than
left orphaned. subagents tool reads the unified task_runs ledger tree-scoped
(subagent/acp/media/cron) and cancels detached runs, enforcing the
controlScope gate for leaf callers. session_status gains a cost line.
Agent-origin model patches record a fallback marker; runs failing on
auth/billing/model_not_found revert to the last working model (transient
errors never revert), and an independent thinkingLevel change realigns the
marker so revert cannot clobber it.
Refs #107237
Distinguish progress from terminal source delivery across Codex telemetry,
payload suppression, terminal failure routing, and stranded-reply recovery.
Preserve legacy behavior when explicit markers are absent.
* feat(nodes): route alerts by active computer
* fix(ci): allowlist node presence mobile coverage
* test(prompts): refresh node presence snapshots
* fix(macos): await presence reporter actor hop
* fix(macos): type presence test delivery state
* docs(nodes): add active presence guide
* docs(nodes): format presence troubleshooting
Adds a core sessions_search agent tool backed by a SQLite FTS5 index that
lives next to the transcript rows in the per-agent database. Indexing is
transactional: user/assistant text is indexed inside the same write
transaction that persists the event, deletes drop index rows in the same
transaction, and branch rewinds mark the session dirty so the next search
rebuilds it from the same visible-path resolution sessions_history uses
(which also lazily backfills doctor-migrated databases). Search executes
gateway-side behind an additive sessions.search method with a bounded
session-key allowlist; visibility, sandbox restrictions, and snippet
redaction mirror sessions_history.
Closes#100978
* feat(sessions): durable session state events with parent invalidation
Parents no longer act on stale child-session state: a durable, typed
signal log (session_state_events + per-agent heads) records direct human
messages to children, child spawn/terminal outcomes, goal changes, and
compaction at the seams where those facts are created. A frozen-watermark
cursor protocol (session_watch_cursors) delivers one coalesced system
notice to the parent through the existing system-event + heartbeat wake
idiom, acknowledged at the shared generic drain, with a deferred startup
sweep for restart recovery. session_status gains stateVersion and
changesSince (with exact pruned-history gap signaling); sessions_list
rows gain stateVersion.
Closes#104565
* chore: regenerate docs map and prompt snapshots for session_status changesSince
* feat(tooling): add tsgo typecheck lane for scripts/**
* fix(scripts): burn down scripts type debt surfaced by the new lane
Typing-only except bugs the lane surfaced: gh-read timeout race,
Discord Headers spread dropping entries, undefined allowedHeadBranches
match, plugin-boundary matchAll crash. Deletes retired config keys from
fixtures/benches (prompt snapshots regenerated, config dump only) and
the orphaned non-runnable sync-moonshot-docs script. Adds full-surface
.d.mts declarations for existing .mjs boundaries.
* feat(cron): add headless code-mode driver and trigger-script evaluator
Part A of cron event triggers: runCodeModeScriptHeadless runs a script
to completion (exec/settle/resume, no snapshots, no session), plus the
cron-facing evaluator with per-job tool catalog cache, semaphore, 16KB
state cap, and closed failure taxonomy.
* fix(cron): correct trigger-script bootstrap flags and cache narrowing
* feat(cron): add event triggers (polled condition-watcher scripts)
Part B: trigger field on cron jobs gated by cron.triggers.enabled;
timer evaluates the script each due tick, quiet ticks leave no run
history, fired runs append the script message to the payload; once
semantics, min-interval floor, SQLite columns, RPC/CLI/agent-tool
surfaces, and docs.
* fix(cron): propagate triggerEval through startup catch-up outcomes
* fix(cron): honor cron staggering on quiet trigger ticks; fix trigger test types
* fix(cron): reject with Error reason in trigger-script abort test
* fix(cron): regenerate protocol/docs/snapshot artifacts and break madge cycle for trigger types
CI fixes for #101195: trigger evaluator result types move to the cron
types leaf (madge cycle), cron tool schema inventory gains trigger,
Swift protocol bindings + docs map + Linux prompt snapshots regenerated.
* fix(cron): drop underscore-dangle names in trigger code sync assert
* fix(cron): adopt registerHeadlessToolSearchCatalog after tool-search symbol localization
Upstream #101831 made registerToolSearchCatalog module-private; fold the
headless ref-only catalog registration into one public seam.
* refactor(codex): raise app-server floor to 0.142 and drop range-compat protocol paths
* refactor(codex): model subagent mirror state as one map
* style(codex): format event-projector
* test(codex): drop unused shared-client test import
* refactor(codex): drop v1-era notification field aliases
* fix(codex): teach models to load deferred native spawn_agent via tool_search
* docs(codex): realign harness config tables
* docs(changelog): note Codex app-server protocol update
* fix(cron): accept null fallbacks in cron update patch payload
createCronPatchObjectSchema passes nullableStringArraySchema for model and
toolsAllow, but fallbacks was still hardcoded as a non-nullable array in
cronPayloadObjectSchema, rejecting null clears before they reach the
Gateway service layer.
Switch fallbacks to a parameter so the patch context can pass the nullable
variant, matching the existing pattern for model and toolsAllow.
Fixes#100707
Co-Authored-By: Claude <noreply@anthropic.com>
* test(cron): cover model+fallbacks null clear in patch schema test
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(auto-reply): render chat history since last reply as per-message prose
The inbound chat-history block dumped batched history as a raw JSON array, which models read poorly compared to the chat-window block's per-message prose. Reuse the existing formatChatWindowMessage renderer for history entries so both blocks share one shape, keep the untrusted framing label, and keep media rendered as a bare content-type tag so local paths and URLs stay redacted. Teach the metadata stripper to consume the new prose block form.
* fix(auto-reply): preserve every media content type in chat-history prose
The prose chat-history renderer only forwarded the first attachment's
content type per history message, dropping the rest for entries with
multiple media items. Join all bounded content types instead, and
regenerate the prompt snapshot fixture this changes.
* test(qa-lab): accept prose pending history
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* feat: add session thread management
Squash of codex/thread-management (025aefc3ad1) onto origin/main:
pin/archive/rename sessions via sessions.patch, archived-aware
sessions.list, lifecycle fencing, read-only archived chat, SDK +
Swift protocol support, Control UI session management.
* refactor(ui): minimal session rows with hover-revealed management
Chat picker and sidebar recents share session-row primitives: single-line
rows, relative timestamps, rename/archive/pin revealed on hover or focus,
accent pin badge for pinned rows, and an active-run spinner in the trail
slot. Sidebar floats pinned sessions above recency via the shared
comparator and gains archive/pin actions through the unified sessions-view
patch fallback. Archive eligibility is one shared policy
(canArchiveSessionRow); the sidebar/picker active-run tooltip now uses the
real sessionsView.activeRun locale key.
* fix: align session admission with mailbox-era main
Integration fixes after rebasing onto current main: sessions_list mailbox
test expectations learn the archived/pinned row fields and archived:false
list param; gateway agent admission treats a session as deleted only when
both the requested and canonical alias sets miss it (legacy bare-main
stores and exec-approval followups read under different spellings); cron
persist tests keep a consistent store across claim-guarded persist calls;
the ACP abort hook test asserts abort propagation instead of signal
identity; drop dead lifecycle writes flagged by no-useless-assignment and
fix the promise-executor return in the codex compact test.
* fix(qa): align UI e2e and shard fixtures with redesigned session rows
Sidebar session rows are wrapper divs with an inner link now: update the
navigation browser tests and chat-flow Playwright selectors. Seed a real
per-test session store for the auto-fallback admission guard instead of
depending on leftover host files at /tmp/sessions.json. Teach the
test-projects routing fixture about the suites that newly import the
shared temp-dir helper. Document the Codex thread-format contract for
archivedAt/pinnedAt (flag derived from server-stamped timestamp, epoch ms
here vs Codex epoch seconds) at the type and in the session docs.
* test: route auto-fallback suite through temp-dir helper plans
The auto-fallback suite now imports the shared temp-dir helper for its
seeded session store, so the top-level helper routing fixture must list
it in the auto-reply plan.
* fix(codex): keep OpenClaw control tools direct
* test(codex): refresh direct-tool prompt snapshots
* fix(codex): keep heartbeat direct only when available
* fix(codex): keep heartbeat tool schema stable
---------
Co-authored-by: Eva <eva@100yen.org>
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
* fix: default cron runMode to 'due' instead of 'force'
When the runMode parameter is omitted from a cron 'run' action,
the default value now respects schedule guards ('due') instead
of bypassing them ('force'). This prevents unintended execution
of scheduled jobs outside their configured time windows.
Fixes#94270
Co-Authored-By: Claude <noreply@anthropic.com>
* test: update runMode expectations for default 'due' (#94270)
* ci: trigger re-evaluation of real behavior proof
* fix(cron): document due-by-default agent runs
Signed-off-by: sallyom <somalley@redhat.com>
---------
Signed-off-by: sallyom <somalley@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: sallyom <somalley@redhat.com>
Adds Codex as a selectable hosted web-search provider, routes native Codex search safely across model overrides, and isolates bounded hosted-search workers from configured tools.\n\nVerification: focused post-merge regression suite passed 202/202 tests on exact head 23824af49a.
Honor caller-provided sessionKey values when stale label metadata is also present, and keep denied session-id sends from echoing the resolved canonical session key.
Supersedes openclaw/openclaw#74009 and fixesopenclaw/openclaw#64699.
Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
Capture the originating sessionKey and agentId for cron wake tool calls so non-main session and multi-agent wakes return to the conversation lane that requested them.
Carry stored delivery context through queued wake events so topic/thread replies route correctly, while preserving the default no-origin wake behavior and explicit target:none opt-out.
Refs #46886.
Refs #64556.
Thanks @anagnorisis2peripeteia.
Co-authored-by: Cameron Beeley <cameron.beeley@gmail.com>
* fix(cron): include job name in single-job run history
The cron.runs gateway handler enriches log entries with jobName in the all-jobs scope, but the single-job scope did not pass any job-name lookup into the SQLite run-log reader. Entries returned for one job could therefore reach Control UI without jobName, making the run-history title fall back to the raw job id.
Build a one-entry jobNameById map for the current job and pass it through the same reader enrichment path used by all-jobs history. If the job no longer exists, the map stays undefined and existing fallback behavior is unchanged.
* test(cron): cover single-job run history job name enrichment
Asserts that readCronRunLogEntriesPage stamps a supplied jobNameById map onto single-job page entries, matching the gateway data shape used for both all-jobs and single-job cron.runs responses.
Addresses review feedback on #88294.
* test(cron): preserve nullable tool schema validation
* test(cron): assert runtime nullable tool schema
* test(cron): refresh prompt snapshots
---------
Co-authored-by: Kip Claw <kip@kipclaw.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>