Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .trajectories/completed/2026-03/traj_hn0583gzi86w.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"id": "traj_hn0583gzi86w",
"version": 1,
"task": {
"title": "Fix DM routing filter in wrap.rs — allow thread replies, presence events, and conversation_id targets"
},
"status": "completed",
"startedAt": "2026-03-25T16:25:02.609Z",
"agents": [
{
"name": "default",
"role": "lead",
"joinedAt": "2026-03-25T16:25:26.589Z"
}
],
"chapters": [
{
"id": "chap_7w31qsrd314j",
"title": "Work",
"agentName": "default",
"startedAt": "2026-03-25T16:25:26.589Z",
"events": [
{
"ts": 1774455926589,
"type": "decision",
"content": "Widen DM filter rather than restructure — add pass-through for empty targets (presence), 'thread' synthetic targets, dm_/conv_ prefixed conversation IDs. Also removed dead code: format_injection_with_workspace import and function.: Widen DM filter rather than restructure — add pass-through for empty targets (presence), 'thread' synthetic targets, dm_/conv_ prefixed conversation IDs. Also removed dead code: format_injection_with_workspace import and function.",
"raw": {
"question": "Widen DM filter rather than restructure — add pass-through for empty targets (presence), 'thread' synthetic targets, dm_/conv_ prefixed conversation IDs. Also removed dead code: format_injection_with_workspace import and function.",
"chosen": "Widen DM filter rather than restructure — add pass-through for empty targets (presence), 'thread' synthetic targets, dm_/conv_ prefixed conversation IDs. Also removed dead code: format_injection_with_workspace import and function.",
"alternatives": [],
"reasoning": ""
},
"significance": "high"
},
{
"ts": 1774456153059,
"type": "decision",
"content": "Expanded DM filter to allow empty targets (presence), thread synthetic target, and dm_/conv_ prefixed conversation_id fallbacks. Removed unused format_injection_with_workspace function and import.: Expanded DM filter to allow empty targets (presence), thread synthetic target, and dm_/conv_ prefixed conversation_id fallbacks. Removed unused format_injection_with_workspace function and import.",
"raw": {
"question": "Expanded DM filter to allow empty targets (presence), thread synthetic target, and dm_/conv_ prefixed conversation_id fallbacks. Removed unused format_injection_with_workspace function and import.",
"chosen": "Expanded DM filter to allow empty targets (presence), thread synthetic target, and dm_/conv_ prefixed conversation_id fallbacks. Removed unused format_injection_with_workspace function and import.",
"alternatives": [],
"reasoning": ""
},
"significance": "high"
}
],
"endedAt": "2026-03-25T16:29:26.110Z"
}
],
"commits": [],
"filesChanged": [],
"projectId": "/Users/khaliqgant/Projects/Agent Workforce/relay",
"tags": [],
"_trace": {
"startRef": "184f502cf5542b2ba0f918681eff6be194699c71",
"endRef": "184f502cf5542b2ba0f918681eff6be194699c71"
},
"completedAt": "2026-03-25T16:29:26.110Z",
"retrospective": {
"summary": "Fixed DM routing filter and cleaned up dead code per Devin review on PR #641",
"approach": "Added explicit exceptions for empty targets, thread, dm_/conv_ prefixes. Removed unused format_injection_with_workspace.",
"confidence": 0.95
}
}
24 changes: 24 additions & 0 deletions .trajectories/completed/2026-03/traj_hn0583gzi86w.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Trajectory: Fix DM routing filter in wrap.rs — allow thread replies, presence events, and conversation_id targets

> **Status:** ✅ Completed
> **Confidence:** 95%
> **Started:** March 25, 2026 at 05:25 PM
> **Completed:** March 25, 2026 at 05:29 PM

---

## Summary

Fixed DM routing filter and cleaned up dead code per Devin review on PR #641

**Approach:** Added explicit exceptions for empty targets, thread, dm_/conv_ prefixes. Removed unused format_injection_with_workspace.

---

## Chapters

### 1. Work
*Agent: default*

- Widen DM filter rather than restructure — add pass-through for empty targets (presence), 'thread' synthetic targets, dm_/conv_ prefixed conversation IDs. Also removed dead code: format_injection_with_workspace import and function.: Widen DM filter rather than restructure — add pass-through for empty targets (presence), 'thread' synthetic targets, dm_/conv_ prefixed conversation IDs. Also removed dead code: format_injection_with_workspace import and function.
- Expanded DM filter to allow empty targets (presence), thread synthetic target, and dm_/conv_ prefixed conversation_id fallbacks. Removed unused format_injection_with_workspace function and import.: Expanded DM filter to allow empty targets (presence), thread synthetic target, and dm_/conv_ prefixed conversation_id fallbacks. Removed unused format_injection_with_workspace function and import.
9 changes: 8 additions & 1 deletion .trajectories/index.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"version": 1,
"lastUpdated": "2026-03-25T09:28:53.988Z",
"lastUpdated": "2026-03-25T16:29:26.213Z",
"trajectories": {
"traj_1b1dj40sl6jl": {
"title": "Revert aggressive retry logic in relay-pty-orchestrator",
Expand Down Expand Up @@ -856,6 +856,13 @@
"startedAt": "2026-03-25T09:28:08.884Z",
"completedAt": "2026-03-25T09:28:53.882Z",
"path": "/Users/khaliqgant/Projects/AgentWorkforce/relay/.trajectories/completed/2026-03/traj_1qnnaojcl0w6.json"
},
"traj_hn0583gzi86w": {
"title": "Fix DM routing filter in wrap.rs — allow thread replies, presence events, and conversation_id targets",
"status": "completed",
"startedAt": "2026-03-25T16:25:02.609Z",
"completedAt": "2026-03-25T16:29:26.110Z",
"path": "/Users/khaliqgant/Projects/Agent Workforce/relay/.trajectories/completed/2026-03/traj_hn0583gzi86w.json"
}
}
}
21 changes: 0 additions & 21 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,27 +532,6 @@ pub(crate) fn format_injection(from: &str, event_id: &str, body: &str, target: &
format_injection_with_reminder(from, event_id, body, target, true)
}

pub(crate) fn format_injection_with_workspace(
from: &str,
event_id: &str,
body: &str,
target: &str,
workspace_id: Option<&str>,
workspace_alias: Option<&str>,
) -> String {
format_injection_for_worker_with_workspace(
from,
event_id,
body,
target,
true,
true,
None,
workspace_id,
workspace_alias,
)
}

#[cfg_attr(not(test), allow(dead_code))]
pub(crate) fn format_injection_with_reminder(
from: &str,
Expand Down
44 changes: 40 additions & 4 deletions src/wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::time::{Duration, Instant};

use super::*;
use crate::helpers::{
check_echo_in_output, floor_char_boundary, format_injection_with_workspace, ActivityDetector,
DeliveryOutcome, PendingActivity, PendingVerification, ThrottleState,
check_echo_in_output, floor_char_boundary, format_injection_for_worker_with_workspace,
ActivityDetector, DeliveryOutcome, PendingActivity, PendingVerification, ThrottleState,
ACTIVITY_BUFFER_KEEP_BYTES, ACTIVITY_BUFFER_MAX_BYTES, ACTIVITY_WINDOW,
MAX_VERIFICATION_ATTEMPTS, VERIFICATION_WINDOW,
};
Expand Down Expand Up @@ -546,6 +546,7 @@ pub(crate) async fn run_wrap(
let requested_name = std::env::var("RELAY_AGENT_NAME").unwrap_or_else(|_| resolved_cli.clone());
let channels = std::env::var("RELAY_CHANNELS").unwrap_or_else(|_| "general".to_string());
let channel_list = channels_from_csv(&channels);
let skip_prompt = env_flag_enabled("RELAY_SKIP_PROMPT");

eprintln!(
"[agent-relay] wrapping {} (agent: {}, channels: {:?})",
Expand Down Expand Up @@ -578,6 +579,16 @@ pub(crate) async fn run_wrap(
workspaces,
mut ws_inbound_rx,
} = relay;
// Ensure the requested agent name (from RELAY_AGENT_NAME) is in self_names
// so that messages sent by the MCP server child (which registers with the
// same name) are recognized as self-echo and filtered out.
let workspaces: Vec<RelayWorkspace> = workspaces
.into_iter()
.map(|mut ws| {
ws.self_names.insert(requested_name.clone());
ws
})
.collect();
let workspace_lookup: std::collections::HashMap<String, RelayWorkspace> = workspaces
.iter()
.cloned()
Expand Down Expand Up @@ -1024,6 +1035,25 @@ pub(crate) async fn run_wrap(
continue;
}

// DM routing: only deliver DMs addressed to this agent.
// Channel messages (target starts with '#') are broadcast
// to all subscribers. Allow through: empty targets (presence),
// thread replies, conversation_id fallbacks.
if !mapped.target.is_empty()
&& !mapped.target.starts_with('#')
&& mapped.target != "thread"
&& !mapped.target.starts_with("dm_")
&& !mapped.target.starts_with("conv_")
&& !workspace_self_names.contains(&mapped.target)
{
tracing::debug!(
target = %mapped.target,
self_names = ?workspace_self_names,
"skipping DM not addressed to this agent"
);
continue;
}

let delivery_id = format!("wrap_{}", mapped.event_id);
tracing::debug!(
delivery_id = %delivery_id,
Expand Down Expand Up @@ -1072,11 +1102,14 @@ pub(crate) async fn run_wrap(
pty_auto.auto_suggestion_visible = false;
}
tracing::debug!("relay from {} → {}", pending.from, pending.target);
let injection = format_injection_with_workspace(
let injection = format_injection_for_worker_with_workspace(
&pending.from,
&pending.event_id,
&pending.body,
&pending.target,
!skip_prompt, // include_reminder
true, // pre_registered
None, // assigned_name
pending.workspace_id.as_deref(),
pending.workspace_alias.as_deref(),
);
Expand Down Expand Up @@ -1171,11 +1204,14 @@ pub(crate) async fn run_wrap(
// Re-inject retries
for mut pv in retry_queue {
tokio::time::sleep(throttle.delay()).await;
let injection = format_injection_with_workspace(
let injection = format_injection_for_worker_with_workspace(
&pv.from,
&pv.event_id,
&pv.body,
&pv.target,
!skip_prompt,
true,
None,
pv.workspace_id.as_deref(),
pv.workspace_alias.as_deref(),
);
Expand Down
Loading