* fix(agents): persist embedded runner session transcripts (#77823)
Run persistCliTurnTranscript and post-turn compaction for executionTrace.runner embedded,
matching CLI turns so assistant text reaches session JSONL for webchat/Feishu-style runs.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(agents): narrow embedded transcript mirror with assistant dedupe (#77823)
Embedded runs pass embeddedAssistantGapFill so persistCliTurnTranscript skips
re-appending the user prompt Pi owns and only appends assistant text when the
transcript tail lacks equivalent visible assistant content.
Adds CLI transcript regression coverage for gap-fill dedupe.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(agents): dedupe embedded transcript gap fill by tail
* fix: persist embedded session transcripts (#77839) (thanks @neeravmakwana)
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
When directive consume() returned null (e.g. silent NO_REPLY chunk) or the
cleaned payload was empty, we still set lastBlockReplyText, so message_end
skipped the safety send while no channel delivery had occurred.
Fixes#77833.
Co-authored-by: Cursor <cursoragent@cursor.com>
type:"message" entries with a null, missing, or blank role cannot be
replayed to any provider — every router branches on message.role. The
auto-repair pass was passing them through unchanged, relocating the
corruption from the original file into the post-repair file (#77228
reported 935+ null-role entries surviving the pass).
Add isStructurallyInvalidMessageEntry ahead of the existing rewrite
predicates. Invalid message envelopes are counted as droppedLines and
skipped; non-message envelope types (summary, custom, …) are unaffected.
The .bak-* backup preserves the original bytes for postmortem before any
entries are dropped.
Tests:
- pnpm test src/agents/session-file-repair.test.ts
- pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/agents/session-file-repair.ts src/agents/session-file-repair.test.ts
- pnpm check:changed
Refs #77228
normalizeAssistantReplayContent rewrites empty assistant error turns into
a STREAM_ERROR_FALLBACK_TEXT sentinel to satisfy Bedrock Converse's
non-empty ContentBlock requirement for non-trailing turns. When that
sentinel is the trailing entry, prefill-strict providers reject the
request with "400 This model does not support assistant message prefill.
The conversation must end with a user message." and the session cannot
recover on its own.
Add a post-loop tail trim that drops trailing assistant turns whose
content is empty with stopReason "error" or zero-usage empty stop, or
carries only the sentinel text with the same synthetic provenance. A real
model reply whose content happens to equal the sentinel string is
preserved by requiring zero usage or stopReason "error" before dropping.
The trim catches both the in-memory rewrite shape and the sentinel
persisted to disk by session-file-repair.
Tests:
- pnpm test src/agents/pi-embedded-runner/replay-history.test.ts
- pnpm exec oxfmt --check --threads=1 CHANGELOG.md src/agents/pi-embedded-runner/replay-history.ts
src/agents/pi-embedded-runner/replay-history.test.ts
- pnpm check:changed
Refs #77228
Summary:
- This PR adds optional `agentId` filtering to `cron.list`, auto-fills it for agent tool calls, exposes `openclaw cron list --agent`, updates generated protocol clients, docs, changelog, tests, and prompt fixtures.
- Reproducibility: yes. The motivating behavior is source-reproducible on current main because cron tool, CLI, ... e list paths do not accept or apply `agentId`; the PR diff adds that path with focused regression coverage.
Automerge notes:
- Ran the ClawSweeper repair loop before final review.
- Included post-review commit in the final squash: chore: regenerate protocol schema after adding agentId to CronListParams
- Included post-review commit in the final squash: feat(cron): add agentId filtering to cron list
Validation:
- ClawSweeper review passed for head 35b692bc97.
- Required merge gates passed before the squash merge.
Prepared head SHA: 35b692bc97
Review: https://github.com/openclaw/openclaw/pull/77602#issuecomment-4375631700
Co-authored-by: zhanggttry <zhanggttry@163.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Accept drive-absolute Windows sandbox Docker bind sources in config and runtime validation while keeping blocked-path and allowed-root comparisons case-insensitive for Windows drive paths.
Also remove a stale WhatsApp setup import that blocked extension lint after the rebase.
Co-authored-by: 6607changchun <84566142+6607changchun@users.noreply.github.com>
Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com>
Summary:
- The PR updates agents skill prompt guidance to require exact `<location>` paths for single- and multi-skill selection, adds prompt assertions, and records the fix in the changelog.
- Reproducibility: yes. Static source reproduction is enough: current main lacks the exact-`<location>` guard ... illsSection()`, while the PR diff adds it to both selection branches and asserts the resulting prompt text.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix: enforce exact skill paths for all skill matches
Validation:
- ClawSweeper review passed for head 743c9840c1.
- Required merge gates passed before the squash merge.
Prepared head SHA: 743c9840c1
Review: https://github.com/openclaw/openclaw/pull/74161#issuecomment-4341488109
Co-authored-by: tianguicheng <tianguicheng@xiaomi.com>
Co-authored-by: sallyom <somalley@redhat.com>
Two correctness fixes from code review.
1. Zod schema (src/config/zod-schema.agent-runtime.ts) was strict and
rejected tools.loopDetection.postCompactionGuard.* keys at validation
time, making the guard's documented configurability inaccessible at
gateway startup. Adds ToolLoopPostCompactionGuardSchema with both
optional fields and wires it into ToolLoopDetectionSchema.
2. The runner observation cursor in pi-embedded-runner/run.ts used
absolute indices into state.toolCallHistory, but that array is
trimmed at historySize (default 30). Once the buffer was full, new
records shifted out from under the cursor and the guard silently
missed every loop in long-running sessions. Replaces the index
cursor with a monotonic toolOutcomeSeq on SessionState that
recordToolCallOutcome bumps on each observable push (unmatched
branch only, mirroring the prior cursor's effective semantics).
The runner now reads the most recent (currentSeq - lastSeq) entries
from the tail of toolCallHistory, which is trim-resilient.
Adds zod parse tests for the new config keys (valid, empty, unknown
key, non-positive, non-integer) and a runner regression test that
seeds toolCallHistory at the trim cap before triggering a
post-compaction loop, asserting the abort still fires.
Refs #77474
Arms the guard at each of the three compaction-success points in
run.ts and observes tool-call outcomes from the diagnostic session
state's toolCallHistory after each attempt. Aborts with
PostCompactionLoopPersistedError when the same (tool, args, result)
triple repeats windowSize times within the post-compaction window.
Refs #77474
- Add PostCompactionLoopPersistedError.fromVerdict factory.
- Add unit tests for the error class + fromVerdict adapter.
- Disabled guard is now truly dormant (no state mutation when enabled=false).
- Tighten help text for postCompactionGuard.enabled.
Refs #77474
Pure module with unit tests; not yet wired into runner. The guard arms
after auto-compaction-retry and aborts when the same (tool, args, result)
triple repeats within the configured window.
Refs #77474
Resolve Windows npm .cmd shim startup failures for bundled LSP servers by routing LSP process spawning through the shared Windows spawn resolver with a sanitized child environment.
The change reuses existing PATH/PATHEXT and .cmd shim handling, keeps non-Windows behavior unchanged, and adds focused regression coverage for resolver wiring, env sanitization, and spawn materialization.
Fixes#75352.
Tests:
- pnpm test src/agents/pi-bundle-lsp-runtime.windows-spawn.test.ts src/agents/pi-bundle-lsp-runtime.test.ts
- pnpm check:changed
Thanks @ElliotDrel.
Co-authored-by: Elliot Drel <156480527+ElliotDrel@users.noreply.github.com>
Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com>
Reuse compatible workspace-scoped plugin metadata snapshots for unscoped model catalog and manifest-contract readers while preserving env/config/workspace compatibility checks.
Also updates the stale kitchen-sink prerelease canary assertion to the current script default.
Fixes#77519.
Related #77532.