Release: merge main into release - #4490
Conversation
…ot pose (#4354) Co-authored-by: M3gA-Mind <megamind@mahadao.com>
…w-coverage fixtures (#4372)
…eetings page, reply-name setting (#4391)
…able tools (#4419) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…l tool-calling alive (#4414) Co-authored-by: M3gA-Mind <megamind@mahadao.com>
…emaCleanr / model-context / observed stream (#4539)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…ndary (whatsapp_web, telegram) (#4569)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4d451ed27a
ℹ️ 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".
| # [skip ci]: the bump commit lands on an already-validated release | ||
| # tree — don't re-trigger the full suite (ci-full.yml, push:release). | ||
| git commit -m "chore(staging): v${VERSION} [skip ci]" | ||
| git push origin HEAD:release |
There was a problem hiding this comment.
Reject stale staging SHAs before pushing
When release-staging.yml is dispatched with commit_sha set to a reachable ancestor of current origin/release, this workflow checks out that SHA detached, creates the staging bump commit there, and then runs git push origin HEAD:release. I checked git push -h, which lists --force/--force-with-lease as the force-update options; this command uses neither, so historical staging cuts fail as a non-fast-forward push instead of producing the requested bump/tag/build. Require commit_sha to equal origin/release before committing to release, or avoid pushing a bump for historical builds.
Useful? React with 👍 / 👎.
| setBackendMeetLeft(state, _action: PayloadAction<{ reason: string; correlationId?: string }>) { | ||
| state.status = 'ended'; |
There was a problem hiding this comment.
Ignore stale leave events before ending the active meeting
When an agent_meetings:left event from an earlier correlation arrives after the user has started a different meeting, this reducer ignores the action's correlationId and unconditionally marks the current call ended while clearing the live transcript buffer. In that overlap, a delayed leave from the old bot can close the active meeting banner for the new call; compare the event correlation with state.meetingId and ignore mismatches before mutating the current meeting state.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3906dfeb3
ℹ️ 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".
| let record_status = if remote_status(&remote).as_deref() == Some("accepted") { | ||
| PairingStatus::Linked | ||
| } else { | ||
| PairingStatus::Pending | ||
| }; |
There was a problem hiding this comment.
Promote accepted pairings before ingest
When the contact request created here is accepted later by the remote agent, this row stays Pending; neither list() nor linked_agent_ids() reconciles it with /contacts. Since orchestration::ingest_one only decrypts/saves DMs from local Linked records, replies from that now-accepted session are skipped until the user manually links again. Upgrade pending records when /contacts reports accepted, or re-check before gating ingest.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f24220ee68
ℹ️ 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 let Some(gate) = crate::openhuman::approval::ApprovalGate::try_global() { | ||
| let summary = crate::openhuman::approval::summarize_action(slug, &args); | ||
| let redacted = crate::openhuman::approval::redact_args(&args); | ||
| let (outcome, request_id) = gate.intercept_audited(slug, &summary, redacted).await; |
There was a problem hiding this comment.
Enforce autonomy on workflow tool calls
When a saved flow with a tool_call node runs under read-only autonomy and require_approval=false (the RPC/default saved-flow path), this branch goes straight from curation to ApprovalGate; the gate sees TrustedAutomation::Workflow { require_approval: false } from flows_run and returns Allow, so a Composio action can execute even though read-only blocks acting tools and the HTTP/code nodes below call enforce_node_tier_gate. Add the same autonomy-tier gate for tool_call before invoking Composio.
Useful? React with 👍 / 👎.
| const validated = validate(); | ||
| if (!validated) return; | ||
| setTestStatus({ kind: 'testing' }); | ||
| log('handleTest: url=%s tokenLen=%d', validated.url, validated.token.length); |
There was a problem hiding this comment.
Redact remote core URLs before logging
When a remote-core URL includes sensitive query material (for example a tunnel/access token or signed URL), this debug line writes the full normalized URL to renderer logs; the save path below logs the same value. The component already rejects user:pass@host, but query strings are preserved by normalizeRpcUrl, so use the existing redactRpcUrlForLog helper here before logging.
Useful? React with 👍 / 👎.
…tes, workflow-builder agent, engine 0.5.0, Skills rename (#4570)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 44614a7354
ℹ️ 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".
| setBackendMeetTranscript(state, action: PayloadAction<BackendMeetTranscriptEvent>) { | ||
| state.transcript = action.payload; | ||
| // The final transcript is authoritative — drop the accumulated live | ||
| // buffer so the same turns aren't rendered twice (reconcile on end). | ||
| state.liveTranscript = []; |
There was a problem hiding this comment.
Ignore stale final transcripts before clearing live text
When a delayed agent_meetings:transcript from a previous meeting arrives after state.meetingId has moved to a new call, this reducer ignores action.payload.correlationId, stores the old transcript, and clears the current call's liveTranscript. In that overlap the active meeting banner can lose its live text and show the prior call's final transcript; compare the event correlation to the active meeting before accepting the final transcript.
Useful? React with 👍 / 👎.
| let path_policy = super::security_for_tool_context(&self.security, context, "file_write"); | ||
| let resolved_target = match path_policy.validate_parent_path(path).await { |
There was a problem hiding this comment.
Gate context file edits against the context path
When file_write runs with a ToolExecutionContext for a delegated/TinyAgents workspace, this new context-aware execution path resolves and writes under context.workspace.root, but the ask-before-edit gate still calls external_effect_with_args first and probes self.security.action_dir. If foo.ts already exists in the delegated workspace but not in the original action dir, supervised mode classifies the call as a new-file create and skips approval, then overwrites the existing context file here; the gate needs to use the same effective action dir or conservatively prompt for context writes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d8644f105d
ℹ️ 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".
| @@ -205,7 +214,7 @@ fn build_registered_controllers() -> Vec<RegisteredController> { | |||
| // Managed Node.js runtime bridge (tool listing + dispatch) | |||
| controllers.extend(crate::openhuman::javascript::all_javascript_registered_controllers()); | |||
| // Discovered SKILL.md skills and their bundled resources | |||
| controllers.extend(crate::openhuman::workflows::all_workflows_registered_controllers()); | |||
| controllers.extend(crate::openhuman::skills::all_skills_registered_controllers()); | |||
There was a problem hiding this comment.
Keep workflows RPC aliases registered
When this switches the public registration to only the new skills controllers, there is no remaining controller for the old workflows namespace (I searched for namespace: "workflows" / all_workflows_registered and found none). The desktop and Playwright smoke specs still call openhuman.workflows_list in app/test/e2e/specs/skill-lifecycle.spec.ts:62 and app/test/playwright/specs/skill-lifecycle.spec.ts:25, so CI Full will get method-not-found on those routes; keep a compatibility alias or update the remaining callers/tests together.
Useful? React with 👍 / 👎.
| "[flows] tool_call: connection_ref connection_id not found among the user's \ | ||
| live connected accounts (stale cache or foreign id) — forwarding to \ | ||
| Composio Direct mode as-is" |
There was a problem hiding this comment.
Fail closed on unresolved Composio connection refs
When a saved flow runs in Direct Composio mode with a stale, typoed, or foreign connection_ref, this branch only warns and still forwards the unresolved id to direct_execute. That call sends the id to v3, but the existing v2 fallback drops the account id entirely, so if v3 rejects the id the action can still execute against the ambient account instead of the account the flow was configured for; reject unresolved connection ids before dispatching.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cadeee5d89
ℹ️ 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".
| const result = await runFlow(flowId); | ||
| log('run: started flow id=%s thread_id=%s', flowId, result.thread_id); | ||
| setActiveRunId(result.thread_id); |
There was a problem hiding this comment.
Subscribe to run progress before awaiting completion
When a user clicks Run on any persisted flow, runFlow() calls openhuman.flows_run, and the Rust handler awaits run_with_checkpointer_journaled_observed until the flow completes or parks before returning the thread_id. The canvas only sets activeRunId after that await, while useFlowRunProgress(activeRunId) subscribes only once the id is available, so all live flow:run_progress events emitted during the run are missed and the advertised per-node live overlay never appears for manual runs; return/register the run id before waiting for completion, or start watching a run id that is known before the observer emits progress.
Useful? React with 👍 / 👎.
| let outcome = crate::openhuman::runtime_node::ops::execute_tool( | ||
| &self.config, | ||
| tool_name, | ||
| args, | ||
| false, | ||
| ) | ||
| .await | ||
| .map_err(EngineError::Capability)?; |
There was a problem hiding this comment.
Record native tool execution in approval audit
When a workflow tool_call uses a native oh:<tool> and the call is approved (for example under Supervised autonomy or a flow with require_approval=true), gate_call_for_tier can return an audit request id, but this native branch executes the tool and returns without calling ApprovalGate::record_execution. Unlike the Composio, HTTP, and code branches below, approved native-tool rows are left without executed_at/success/failure, so the approval audit trail cannot tell whether the approved action actually ran or failed.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0cc4c39af8
ℹ️ 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".
| function defaultPortsForKind(kind: NodeKind): Port[] { | ||
| if (kind === 'condition') { | ||
| return [{ name: 'true' }, { name: 'false' }]; | ||
| } | ||
| return []; |
There was a problem hiding this comment.
Seed switch nodes with routable ports
When a user adds a switch node from the palette, this falls through to no declared ports, so createFlowNode gives it only the fallback main output. The switch runtime routes to the matching case port or default, and the config drawer only edits expression/field (not ports), so newly-authored switch flows cannot wire the normal default/case branches and downstream nodes will not run for ordinary switch values; add switch/default ports or a port editor before saving these nodes.
Useful? React with 👍 / 👎.
| tracing::debug!( | ||
| target: "flows", | ||
| method = ?request.get("method"), | ||
| url = ?request.get("url"), |
There was a problem hiding this comment.
Redact flow HTTP URLs before tracing
When a flow HTTP node calls a signed URL or includes tokens in the query string, this debug trace records the full url value into app/core logs. The approval path above intentionally redacts request data before display, but this separate trace bypasses that protection for every flow HTTP request; log a redacted URL (for example stripping query/fragment) instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ff442240a
ℹ️ 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".
| const RECALL_DETECT_TTL: Duration = Duration::from_secs(30 * 60); | ||
|
|
||
| /// Process-wide memo of the last Recall probe: `(taken_at, connected)`. | ||
| static RECALL_DETECT_CACHE: Mutex<Option<(Instant, bool)>> = Mutex::new(None); |
There was a problem hiding this comment.
Key Recall detection cache by active user
When the desktop process changes backend users (logout/login, or a new app-session JWT in the same running core), this process-wide cache reuses the previous user's connected result for up to 30 minutes. The hot-path callers in upcoming-meetings and heartbeat then either fetch Recall meetings for a user who has not connected Recall, or suppress Recall for a newly logged-in connected user; include the backend user/session (or invalidate on auth changes) in this memo instead of caching a bare boolean globally.
Useful? React with 👍 / 👎.
| policy_id = %workspace.policy_id, | ||
| "[tools:filesystem] using TinyAgents workspace descriptor as action dir" | ||
| ); | ||
| scoped.action_dir = workspace.root.clone(); |
There was a problem hiding this comment.
Grant descriptor roots in the scoped security policy
When a ToolExecutionContext supplies a TinyAgents workspace that is allowed by its WorkspaceDescriptor but is not already under the parent SecurityPolicy's workspace_dir/trusted_roots, changing only action_dir is not enough: validate_path/validate_parent_path still perform containment and forbidden-path checks against the original policy roots, so context-aware file tools can reject legitimate delegated/worktree files as escaping the workspace. Add the descriptor root/trusted roots to the scoped policy (or rebuild the policy around the descriptor) so the path validation matches the context being used for I/O.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 169379c2fa
ℹ️ 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".
| // `[System]` turns occupy an index but are never sent as deltas — so we | ||
| // leave a gap (a sparse slot) rather than shifting later turns. Rendering | ||
| // skips the empty slots. | ||
| state.liveTranscript[index] = turn; |
There was a problem hiding this comment.
Ignore stale live transcript deltas
When a delayed agent_meetings:transcript_delta from a previous call arrives after meetingId has moved to a new meeting, this reducer accepts it because it only reads turn/index/is_partial and ignores the payload correlationId that socketService passes. In that overlap the active meeting's live transcript can show stale lines or partial-state from the old call; compare the event correlation to the active state.meetingId before writing liveTranscript.
Useful? React with 👍 / 👎.
| uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 | ||
| with: | ||
| path: .ci/artifacts/e2e-playwright-linux.tar.gz | ||
| key: e2e-playwright-linux-${{ hashFiles('src/**', 'Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', 'app/src/**', 'app/public/**', 'app/index.html', 'app/vite.config.*', 'app/tailwind.config.*', 'app/postcss.config.*', 'app/package.json', 'pnpm-lock.yaml', 'app/scripts/e2e-web-build.sh') }} |
There was a problem hiding this comment.
Rebuild Playwright artifact when vendored SDKs change
In the CI Full build-playwright-e2e-artifact job, the build step is skipped on an exact artifact-cache hit, but this key hashes core/app sources and Cargo files without vendor/** or .gitmodules, even though Cargo.toml patches tinyagents/tinyflows/etc. from vendor/. When a PR only advances one of those submodule SHAs, this can reuse a cached e2e-playwright-linux.tar.gz, so Playwright runs an old core artifact and misses regressions in the vendored SDK change; include the vendored submodule content or SHAs in the key.
Useful? React with 👍 / 👎.
Auto-prepared by prepare-release-pr.yml on push to main.
This PR runs the full Release CI suite (unit + Rust E2E + Playwright + desktop E2E on 3 OSes). Maintainers can push fixes to it; merge once green to advance the release branch, then cut a release with release-staging.yml / release-production.yml.