fix(server): agents can continue the same reviewer conversation#23253
0 / 4 viewed4 files changedLine totals unavailable
apps/server/src/scheduledTasks/webhookFilter.ts · Earlier revision 091f756f · right 39–41
Original diff
@@ -27,9 +23,29 @@ function matchesWebhookFilter(filter: ScheduledTaskWebhookFilter, value: unknown
return filter.value.includes(text);
case "startsWith":
return text.startsWith(filter.value);
+ case "exists":
+ return true;
}
}
+/**
+ * Placeholders render null as missing, so filters treat it the same way. A
+ * path with a `[]` wildcard resolves to a list: `equals`, `in` and
+ * `startsWith` match when any element does, `notEquals` only when none equals
+ * the value, and `exists` when the list has an element.
+ */
+function matchesWebhookFilter(filter: ScheduledTaskWebhookFilter, value: unknown): boolean {
+ if (Array.isArray(value) && /\[\]/.test(filter.path)) {
+ const texts = value.map(scalarText).filter((text): text is string => text !== undefined);
+ if (filter.op === "notEquals") return texts.every((text) => text !== filter.value);
+ return texts.some((text) => matchesScalar(filter, text));apps/server/src/scheduledTasks/webhookFilter.ts · right 39–41
apps/server/src/scheduledTasks/webhookFilter.ts · Earlier revision 091f756f · right 39–41
Original diff
@@ -27,9 +23,29 @@ function matchesWebhookFilter(filter: ScheduledTaskWebhookFilter, value: unknown
return filter.value.includes(text);
case "startsWith":
return text.startsWith(filter.value);
+ case "exists":
+ return true;
}
}
+/**
+ * Placeholders render null as missing, so filters treat it the same way. A
+ * path with a `[]` wildcard resolves to a list: `equals`, `in` and
+ * `startsWith` match when any element does, `notEquals` only when none equals
+ * the value, and `exists` when the list has an element.
+ */
+function matchesWebhookFilter(filter: ScheduledTaskWebhookFilter, value: unknown): boolean {
+ if (Array.isArray(value) && /\[\]/.test(filter.path)) {
+ const texts = value.map(scalarText).filter((text): text is string => text !== undefined);
+ if (filter.op === "notEquals") return texts.every((text) => text !== filter.value);
+ return texts.some((text) => matchesScalar(filter, text));apps/server/src/scheduledTasks/webhookFilter.ts · right 39–41
docs/orchestration-v2/orchestrator-mcp-server.md · Earlier revision 091f756f · right 260–261
Original diff
@@ -252,13 +252,13 @@ omits it for a provider that offers all of them. When the target lists `runtimeModes`, an explicit `runtimeMode` outside that list is refused, and an inherited mode steps down to the broadest mode the target offers. -Each delegated review round uses a new `delegate_task` call with the original brief, +Each independent review round uses a new `delegate_task` call with the original brief, prior findings, responses, and unresolved objections. Track each round by its own `taskId` and use a distinct `clientRequestId` per round, stable across retries of that round. -`childThreadId` is backing storage, not a target for another review round through -`t3_thread_send`. Ordinary thread messaging remains available for user-requested -conversations; it does not reopen a completed task. There is no task-level follow-up -API for preserving the same reviewer session. +`childThreadId` is backing storage, not a target for another independent review round through +`t3_thread_send`. A follow-up that needs the same child's conversation goes to +`childThreadId` through `t3_thread_send`; it starts a fresh task in that thread and +does not reopen the completed one.
docs/orchestration-v2/orchestrator-mcp-server.md · right 260–261