Skip to content

Integrate embedded WhatsApp and text channels#89

Merged
bglusman merged 5 commits into
mainfrom
codex-whatsapp-migration
Apr 30, 2026
Merged

Integrate embedded WhatsApp and text channels#89
bglusman merged 5 commits into
mainfrom
codex-whatsapp-migration

Conversation

@bglusman

Copy link
Copy Markdown
Owner

Summary

  • Replace the WhatsApp webhook sidecar adapter with embedded zeroclawlabs::WhatsAppWebChannel support.
  • Add a Linq-backed kind = "sms" Text/iMessage channel for iMessage/RCS/SMS webhooks and replies.
  • Move Signal onto the outbound message envelope so artifact-producing agents render attachment fallbacks consistently.
  • Add Matrix 429 retry handling and update channel/agent docs with compile-tested TOML examples.
  • Extend the local Docker smoke path with optional npcsh/OmO/Gas Town recipe smoke checks.

Verification

  • cargo check -p calciforge
  • cargo test -p calciforge test_channel -- --nocapture
  • cargo test -p calciforge test_agents_doc_full_config_toml_blocks_valid -- --nocapture
  • cargo test -p calciforge channels::whatsapp::tests -- --nocapture
  • cargo test -p calciforge channels::sms::tests -- --nocapture
  • CALCIFORGE_AGENT_RECIPE_SMOKE=1 scripts/manual-docker-test.sh
  • push hook: fmt, clippy, unit/e2e/doc tests, loom tests, workspace checks

Notes

Live WhatsApp pairing and live Linq delivery still need provider-backed staging credentials. The mocked channel tests cover identity drops, reply target preservation, legacy WhatsApp config rejection, and artifact fallback rendering.

Copilot AI review requested due to automatic review settings April 30, 2026 11:48
@qodo-code-review

This comment was marked as low quality.

greptile-apps[bot]

This comment was marked as low quality.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Integrates embedded channel transports (WhatsApp Web + Signal) and adds a new Linq-backed sms channel, while updating docs and smoke tooling to reflect the expanded channel set and improved delivery behavior.

Changes:

  • Replaces the WhatsApp webhook sidecar with an embedded WhatsAppWebChannel transport loop and adds a new Linq webhook-based sms channel.
  • Moves Signal/WhatsApp outbound sending to OutboundMessage text fallbacks for consistent artifact rendering.
  • Adds Matrix 429 retry/backoff handling and updates install/docs + docker smoke scripts for the new channel and recipe smoke option.

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/manual-docker-test.sh Adds optional agent recipe smoke run under env flag.
scripts/install-calciforge.sh Updates sample config snippets for embedded WhatsApp/Signal and new sms channel.
docs/staging-test-matrix.md Documents when to run recipe smoke as part of staging verification.
docs/index.md Updates channel list + adds WhatsApp session and sms Linq examples; links to new agents/routing guide.
docs/channels/whatsapp.md Rewrites WhatsApp setup guide for embedded session transport + migration notes.
docs/channels/sms.md New setup guide for Linq-backed text/iMessage channel.
docs/agents.md New guide documenting [[agents]], [[identities]], [[routing]] with full-config example.
docs/agent-adapters.md Mentions running recipe smoke via the docker smoke path.
docs/README.md Adds agents.md to docs index.
crates/calciforge/src/main.rs Wires up sms channel startup/join; updates WhatsApp/Signal startup log text.
crates/calciforge/src/config.rs Adds sms + embedded WhatsApp fields; adds doc TOML block parsing tests (sms + agents.md).
crates/calciforge/src/channels/whatsapp.rs Replaces webhook receiver with embedded transport listener loop; uses OutboundMessage fallback rendering; adds migration rejection + tests.
crates/calciforge/src/channels/telemetry.rs Updates module docs to include SMS in the cross-channel telemetry schema statement.
crates/calciforge/src/channels/sms.rs New Linq webhook receiver + dispatch bridge using OutboundMessage fallbacks + signature verification support.
crates/calciforge/src/channels/signal.rs Adds !secure handling + switches to OutboundMessage fallback rendering path.
crates/calciforge/src/channels/mod.rs Updates module docs and exports new sms channel module.
crates/calciforge/src/channels/matrix.rs Adds retry handling for Matrix 429 rate-limit responses.
crates/calciforge/Dockerfile Exposes port 18798 for the SMS webhook listener.
crates/calciforge/Cargo.toml Enables zeroclawlabs feature for WhatsApp Web transport.
README.md Updates feature table to include text/iMessage routing.
Cargo.lock Lockfile updates for dependency graph changes from WhatsApp Web enablement.

Comment thread crates/calciforge/src/channels/whatsapp.rs Outdated
Comment thread docs/agents.md
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from 56a2c0e to b780340 Compare April 30, 2026 12:01
greptile-apps[bot]

This comment was marked as low quality.

Copilot AI review requested due to automatic review settings April 30, 2026 12:20
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from b780340 to b88d845 Compare April 30, 2026 12:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 1 comment.

Comment thread docs/index.md Outdated
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from b88d845 to 749f060 Compare April 30, 2026 12:30
Copilot AI review requested due to automatic review settings April 30, 2026 12:53
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from 749f060 to d58b190 Compare April 30, 2026 12:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 26 changed files in this pull request and generated 1 comment.

Comment thread docs/index.md Outdated
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from d58b190 to d320b43 Compare April 30, 2026 13:02
Copilot AI review requested due to automatic review settings April 30, 2026 13:13
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from d320b43 to 2cd9203 Compare April 30, 2026 13:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 26 out of 27 changed files in this pull request and generated 6 comments.

Comment thread crates/calciforge/src/channels/whatsapp.rs Outdated
Comment thread crates/calciforge/src/channels/sms.rs Outdated
Comment thread crates/calciforge/src/channels/whatsapp.rs
Comment thread crates/calciforge/src/channels/sms.rs
Comment thread crates/calciforge/src/channels/matrix.rs
Comment thread crates/calciforge/src/config.rs Outdated
@bglusman bglusman force-pushed the codex-whatsapp-migration branch from 2cd9203 to 3e480f3 Compare April 30, 2026 13:30
Copilot AI review requested due to automatic review settings April 30, 2026 14:05

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 3 comments.

Comment thread crates/calciforge/src/adapters/acpx.rs
Comment thread docs/index.md
Comment thread crates/calciforge/src/channels/whatsapp.rs
Copilot AI review requested due to automatic review settings April 30, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 39 out of 40 changed files in this pull request and generated 3 comments.

Comment thread docs/index.md
Comment on lines 179 to 183
<div class="nav">
<a href="https://github.com/bglusman/calciforge">GitHub</a>
<a href="https://github.com/bglusman/calciforge/blob/main/README.md">README</a>
<a href="https://github.com/bglusman/calciforge/tree/main/docs">Docs</a>
<a href="#quick-install-mac">Install</a>
<a href="agents.md">Agents</a>
</div>

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nav link points to agents.md, but the published GitHub Pages site will generate agents.html for that page. Linking to the .md path will likely 404 (or render raw source) in production; use agents.html (or a root-relative /agents.html) to match the rest of the site links.

Copilot uses AI. Check for mistakes.
Comment on lines 988 to 1001
/// List ACPX sessions for an agent using the acpx CLI.
async fn list_acpx_sessions(&self, agent_name: &str) -> Result<Vec<String>, String> {
tokio::fs::create_dir_all(crate::adapters::acpx::ACPX_SESSION_DIR)
.await
.map_err(|e| format!("Failed to create acpx session dir: {}", e))?;

let output = tokio::process::Command::new("acpx")
.arg(agent_name)
.arg("sessions")
.arg("list")
.current_dir("/tmp")
.current_dir(crate::adapters::acpx::ACPX_SESSION_DIR)
.output()
.await
.map_err(|e| format!("Failed to run acpx: {}", e))?;

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list_acpx_sessions awaits Command::output() with no timeout and without kill_on_drop(true). If acpx sessions list hangs (or the task is cancelled), this can stall !sessions handling and potentially leave an orphaned subprocess. Consider adding a reasonable timeout (similar to the adapter) and enabling kill-on-drop for the child process.

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +179
if let Some(reply) = self.command_handler.handle(&text) {
debug!(identity = %identity.id, cmd = %text.trim(), "Text/iMessage: handled pre-auth command");
let channel = self.clone();
let target = reply_target.clone();
tokio::spawn(async move {
channel.send_reply(&target, &reply).await;
});
return;

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SMS command handling sends replies but doesn't emit telemetry::command_reply_ready(...) events (unlike Telegram/WhatsApp). Since channels/telemetry.rs explicitly calls out cross-channel comparability (and now mentions SMS), consider adding command telemetry here (pre-auth, unknown, status, switch, etc.) so command latency/volume is observable consistently.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 30, 2026 15:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 45 out of 46 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

crates/calciforge/src/adapters/acpx.rs:105

  • ensure_session invokes acpx sessions ensure ... via Command::output().await without kill_on_drop(true) and without using the adapter's existing timeout_ms. If acpx blocks, this can hang dispatch permanently, and cancellation may leave the child process running. Consider setting kill_on_drop(true) and wrapping the wait in tokio::time::timeout(Duration::from_millis(self.timeout_ms), ...), returning a clear AdapterError::Unavailable on timeout.
        let output = Command::new("acpx")
            .arg(&self.agent_name)
            .arg("sessions")
            .arg("ensure")
            .arg("--name")
            .arg(session_name)
            .current_dir(&self.session_dir)
            .envs(&self.env)
            .output()
            .await
            .map_err(|e| AdapterError::Unavailable(format!("Failed to create session: {}", e)))?;

@bglusman bglusman force-pushed the codex-whatsapp-migration branch from a9cc4b8 to d46c860 Compare April 30, 2026 15:25
@bglusman bglusman merged commit 608aa7b into main Apr 30, 2026
34 checks passed
@bglusman bglusman deleted the codex-whatsapp-migration branch April 30, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants