mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 13:11:40 +00:00
fix(infra): extend exec completion detection to cover local background exec formats [AI-assisted] (#64376)
* fix: address issue * fix: address PR review feedback * fix: address PR review feedback * fix: address PR review feedback * chore(changelog): add exec completion owner-downgrade entry --------- Co-authored-by: Devin Robison <drobison@nvidia.com>
This commit is contained in:
@@ -124,6 +124,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Browser/sandbox: gate `/sandbox/novnc` behind bridge auth and stop surfacing sandbox observer URLs in model-visible prompt context. (#63882) Thanks @eleqtrizit.
|
||||
|
||||
- Discord/sandbox: include `image` in sandbox media param normalization so Discord event cover images cannot bypass sandbox path rewriting. (#64377) Thanks @mmaps.
|
||||
- Agents/exec: extend exec completion detection to cover local background exec formats so the owner-downgrade fires correctly for all exec paths. (#64376) Thanks @mmaps.
|
||||
## 2026.4.9
|
||||
|
||||
### Changes
|
||||
|
||||
@@ -71,7 +71,13 @@ describe("heartbeat event prompts", () => {
|
||||
describe("heartbeat event classification", () => {
|
||||
it.each([
|
||||
{ value: "exec finished: ok", expected: true },
|
||||
{ value: "Exec Finished: failed", expected: true },
|
||||
{ value: "Exec finished (node=abc, code 0)", expected: true },
|
||||
{ value: "Exec Finished (node=abc, code 1)", expected: true },
|
||||
{ value: "Exec completed (abc12345, code 0) :: some output", expected: true },
|
||||
{ value: "Exec failed (abc12345, signal SIGTERM) :: error output", expected: true },
|
||||
{ value: "Exec completed (rotate api keys)", expected: false },
|
||||
{ value: "Exec failed: notify me if this happens", expected: false },
|
||||
{ value: "Reminder: if exec failed, notify me", expected: false },
|
||||
{ value: "cron finished", expected: false },
|
||||
])("classifies exec completion events for %j", ({ value, expected }) => {
|
||||
expect(isExecCompletionEvent(value)).toBe(expected);
|
||||
@@ -87,6 +93,11 @@ describe("heartbeat event classification", () => {
|
||||
{ value: "heartbeat poll: noop", expected: false },
|
||||
{ value: "heartbeat wake: noop", expected: false },
|
||||
{ value: "exec finished: ok", expected: false },
|
||||
{ value: "Exec finished (node=abc, code 0)", expected: false },
|
||||
{ value: "Exec completed (abc12345, code 0) :: some output", expected: false },
|
||||
{ value: "Exec failed (abc12345, signal SIGTERM) :: error output", expected: false },
|
||||
{ value: "Exec completed (rotate api keys)", expected: true },
|
||||
{ value: "Reminder: if exec failed, notify me", expected: true },
|
||||
])("classifies cron system events for %j", ({ value, expected }) => {
|
||||
expect(isCronSystemEvent(value)).toBe(expected);
|
||||
});
|
||||
|
||||
@@ -85,7 +85,13 @@ function isHeartbeatNoiseEvent(evt: string): boolean {
|
||||
}
|
||||
|
||||
export function isExecCompletionEvent(evt: string): boolean {
|
||||
return normalizeLowercaseStringOrEmpty(evt).includes("exec finished");
|
||||
const normalized = normalizeLowercaseStringOrEmpty(evt).trimStart();
|
||||
return (
|
||||
/^exec finished(?::|\s*\()/.test(normalized) ||
|
||||
/^exec (completed|failed) \([a-z0-9_-]{1,64}, (code -?\d+|signal [^)]+)\)( :: .*)?$/.test(
|
||||
normalized,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Returns true when a system event should be treated as real cron reminder content.
|
||||
|
||||
Reference in New Issue
Block a user