fix(macos): use foundationValue when serializing browser proxy POST body#41635
fix(macos): use foundationValue when serializing browser proxy POST body#41635Effet wants to merge 103 commits intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR fixes a deterministic SIGABRT crash in
Confidence Score: 4/5
Last reviewed commit: 991d42b |
991d42b to
b33b805
Compare
…dary marker variants (openclaw#35983) Merged via squash. Prepared head SHA: ff07dc4 Co-authored-by: urianpaul94 <[email protected]> Co-authored-by: frankekn <[email protected]> Reviewed-by: @frankekn
…penclaw#40740) Merged via squash. Prepared head SHA: a4456d4 Co-authored-by: sircrumpet <[email protected]> Co-authored-by: obviyus <[email protected]> Reviewed-by: @obviyus
Merged via squash. Prepared head SHA: 0a8ebf8 Co-authored-by: frankekn <[email protected]> Co-authored-by: frankekn <[email protected]> Reviewed-by: @frankekn
Merged via squash. Prepared head SHA: 8abc6c1 Co-authored-by: BunsDev <[email protected]> Co-authored-by: BunsDev <[email protected]> Reviewed-by: @BunsDev
…penclaw#14967) Merged via squash. Prepared head SHA: 1bb49b2 Co-authored-by: rixau <[email protected]> Co-authored-by: BunsDev <[email protected]> Reviewed-by: @BunsDev
…ess is ro (openclaw#40757) Merged via squash. Prepared head SHA: 0e8b27b Co-authored-by: dsantoreis <[email protected]> Co-authored-by: mcaxtr <[email protected]> Reviewed-by: @mcaxtr
…claw#41176) Merged via squash. Prepared head SHA: 33cac4c Co-authored-by: hnykda <[email protected]> Co-authored-by: mukhtharcm <[email protected]> Reviewed-by: @mukhtharcm
… Framework compatibility (openclaw#41838) * fix(msteams): use General channel conversation ID as team key for Bot Framework compatibility Bot Framework sends `activity.channelData.team.id` as the General channel's conversation ID (e.g. `19:[email protected]`), not the Graph API group GUID (e.g. `fa101332-cf00-431b-b0ea-f701a85fde81`). The startup resolver was storing the Graph GUID as the team config key, so runtime matching always failed and every channel message was silently dropped. Fix: always call `listChannelsForTeam` during resolution to find the General channel, then use its conversation ID as the stored `teamId`. When a specific channel is also configured, reuse the same channel list rather than issuing a second API call. Falls back to the Graph GUID if the General channel cannot be found (renamed/deleted edge case). Fixes openclaw#41390 * fix(msteams): handle listChannelsForTeam failure gracefully * fix(msteams): trim General channel ID and guard against empty string * fix: document MS Teams allowlist team-key fix (openclaw#41838) (thanks @BradGroux) --------- Co-authored-by: bradgroux <[email protected]> Co-authored-by: Onur <[email protected]>
Merged via squash. Prepared head SHA: 5cffcb0 Co-authored-by: teconomix <[email protected]> Co-authored-by: mukhtharcm <[email protected]> Reviewed-by: @mukhtharcm
* ACPX: bump bundled acpx to 0.1.16 * fix: bump acpx pin to 0.1.16 (openclaw#41975) (thanks @dutifulbob) --------- Co-authored-by: Onur <[email protected]>
…me (openclaw#41847) * feat(acp): add resumeSessionId to sessions_spawn for ACP session resume Thread resumeSessionId through the ACP session spawn pipeline so agents can resume existing sessions (e.g. a prior Codex conversation) instead of starting fresh. Flow: sessions_spawn tool → spawnAcpDirect → initializeSession → ensureSession → acpx --resume-session flag → agent session/load - Add resumeSessionId param to sessions-spawn-tool schema with description so agents can discover and use it - Thread through SpawnAcpParams → AcpInitializeSessionInput → AcpRuntimeEnsureInput → acpx extension runtime - Pass as --resume-session flag to acpx CLI - Error hard (exit 4) on non-existent session, no silent fallback - All new fields optional for backward compatibility Depends on acpx >= 0.1.16 (openclaw/acpx#85, merged, pending release). Tests: 26/26 pass (runtime + tool schema) Verified e2e: Discord → sessions_spawn(resumeSessionId) → Codex resumed session and recalled stored secret. 🤖 AI-assisted * fix: guard resumeSessionId against non-ACP runtime Add early-return error when resumeSessionId is passed without runtime="acp" (mirrors existing streamTo guard). Without this, the parameter is silently ignored and the agent gets a fresh session instead of resuming. Also update schema description to note the runtime=acp requirement. Addresses Greptile review feedback. * ACP: add changelog entry for session resume (openclaw#41847) (thanks @pejmanjohn) --------- Co-authored-by: Pejman Pour-Moezzi <[email protected]> Co-authored-by: Onur <[email protected]>
…claw#18655) Merged via squash. Prepared head SHA: d30fff1 Co-authored-by: echo931 <[email protected]> Co-authored-by: mukhtharcm <[email protected]> Reviewed-by: @mukhtharcm
…k runs (openclaw#41711) Merged via squash. Prepared head SHA: 8be8967 Co-authored-by: cgdusek <[email protected]> Co-authored-by: altaywtf <[email protected]> Reviewed-by: @altaywtf
Merged via squash. Prepared head SHA: 85c4eb7 Co-authored-by: smysle <[email protected]> Co-authored-by: hydro13 <[email protected]> Reviewed-by: @hydro13
…w#42173) Models like GLM-5 and DeepSeek sometimes emit internal delimiter tokens in their responses. Uses generic pattern in the text extraction pipeline, following the same architecture as stripMinimaxToolCallXml. Closes openclaw#40020 Supersedes openclaw#40573 Co-authored-by: imwyvern <[email protected]>
…34369) Strip trailing /v1beta from baseUrl before appending the version segment, so callers that already include /v1beta in their base URL (e.g. subagent-registry) no longer produce /v1beta/v1beta/models/… which results in a 404 from the Gemini API. Closes openclaw#34312 Co-authored-by: Claude Opus 4.6 <[email protected]>
* docs(acp): document resumeSessionId for session resume * docs: clarify ACP resumeSessionId thread/mode behavior (openclaw#42280) (thanks @pejmanjohn) --------- Co-authored-by: Onur <[email protected]>
…penclaw#42278) Merged via squash. Prepared head SHA: f3cdfa7 Co-authored-by: CryUshio <[email protected]> Co-authored-by: altaywtf <[email protected]> Reviewed-by: @altaywtf
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
1 similar comment
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
5 similar comments
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
15 similar comments
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3874cf00f1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!child.stdin) { | ||
| const identity = await runPinnedWriteFallback(params); | ||
| await exitPromise.catch(() => {}); | ||
| return identity; | ||
| } |
There was a problem hiding this comment.
Fall back when pinned-write helper startup fails
The fallback path is guarded only by if (!child.stdin), but with stdio: ["pipe", "pipe", "pipe"] that branch is effectively unreachable for normal process creation, so a missing python3 binary causes the helper call to fail instead of degrading to runPinnedWriteFallback. On non-Windows hosts without Python installed, every safe write/copy now fails hard, which is a runtime regression for core file mutation paths.
Useful? React with 👍 / 👎.
| " chunk = sys.stdin.buffer.read(65536)", | ||
| " if not chunk:", | ||
| " break", | ||
| " os.write(temp_fd, chunk)", |
There was a problem hiding this comment.
Loop until full chunk is written in pinned write script
The embedded Python writer calls os.write(temp_fd, chunk) once per chunk and ignores the returned byte count. os.write may legally short-write under resource pressure or interruption, so this can silently persist truncated content while still renaming the temp file into place and reporting success, leading to data corruption in writeFileWithinRoot/copyFileWithinRoot paths.
Useful? React with 👍 / 👎.
Summary
MacNodeBrowserProxy.makeRequestpassesparams.body?.valuedirectly toJSONSerialization.data(withJSONObject:).AnyCodable.init(from:)stores decoded JSON objects as[String: AnyCodable]internally — a pure Swift struct (__SwiftValue) thatNSJSONSerializationcan't handle, causing anNSInvalidArgumentExceptioncrash (SIGABRT) on every non-GET request with a JSON body.params.body?.foundationValueinstead ofparams.body?.value.foundationValue(already defined inAnyCodable+Helpers.swift) recursively converts[String: AnyCodable]→[String: Any]soJSONSerializationreceives only Foundation-compatible types.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
Mac app no longer crashes when making POST/PUT/PATCH requests through the browser proxy.
Security Impact (required)
Repro + Verification
Environment
Steps
MacNodeBrowserProxy.request)NSInvalidArgumentException: Invalid type in JSON write (__SwiftValue)Expected
Actual
MacNodeBrowserProxy.makeRequestatJSONSerialization.data(withJSONObject:)Evidence
postRequestSerializesNestedBodyWithoutCrashinMacNodeBrowserProxyTests.swift— covers nested dict + array body, was impossible to add before the fix (would crash)Human Verification (required)
foundationValueis the correct converter, added failing→passing testfoundationValuerecursionReview Conversations
Compatibility / Migration
Failure Recovery (if this breaks)
params.body?.valueinMacNodeBrowserProxy.swift:149Risks and Mitigations
foundationValueon an unrecognized type falls through toself.value(the default case) — same behavior as before, so no regression risk.