Gateway: hide delegated threads unless they wait on the user
This commit is contained in:
1 parent
221622b574
commit
442036b22f
3 files changed
+15
-2
No files matched your search
@@ -14,6 +14,7 @@ export type Phase =
|
|||||||
type AwarenessFields = Pick<
|
type AwarenessFields = Pick<
|
||||||
ThreadShell,
|
ThreadShell,
|
||||||
| "activityRunStatus"
|
| "activityRunStatus"
|
||||||
|
| "delegatedFrom"
|
||||||
| "lineage"
|
| "lineage"
|
||||||
| "latestRunStopRequested"
|
| "latestRunStopRequested"
|
||||||
| "pendingBackgroundTasks"
|
| "pendingBackgroundTasks"
|
||||||
@@ -24,12 +25,14 @@ type AwarenessFields = Pick<
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The phase to show for a thread, or null when the watch should not show it: subagent children,
|
* The phase to show for a thread, or null when the watch should not show it: subagent children,
|
||||||
* threads that never ran or were stopped, and finished work the user already settled.
|
* threads that never ran or were stopped, and finished work the user already settled. Delegated
|
||||||
|
* threads show only while they wait on the user, so their approvals still reach the watch.
|
||||||
*/
|
*/
|
||||||
export function threadPhase(thread: AwarenessFields): Phase | null {
|
export function threadPhase(thread: AwarenessFields): Phase | null {
|
||||||
if (thread.lineage.relationshipToParent === "subagent") return null;
|
if (thread.lineage.relationshipToParent === "subagent") return null;
|
||||||
const phase = resolvePhase(thread);
|
const phase = resolvePhase(thread);
|
||||||
if (phase === null) return null;
|
if (phase === null) return null;
|
||||||
|
if (thread.delegatedFrom && phase !== "waiting_for_approval" && phase !== "waiting_for_input") return null;
|
||||||
if (phase === "completed" && thread.latestRunStopRequested === true) return null;
|
if (phase === "completed" && thread.latestRunStopRequested === true) return null;
|
||||||
if (
|
if (
|
||||||
thread.settledOverride === "settled" &&
|
thread.settledOverride === "settled" &&
|
||||||
|
|||||||
@@ -68,7 +68,9 @@ export interface ThreadShell {
|
|||||||
lastError?: string | null;
|
lastError?: string | null;
|
||||||
modelSelection: ModelSelection;
|
modelSelection: ModelSelection;
|
||||||
runtimeMode?: string;
|
runtimeMode?: string;
|
||||||
lineage: { relationshipToParent: Open<"subagent"> | null };
|
lineage: { relationshipToParent: Open<"fork" | "subagent"> | null };
|
||||||
|
/** Set on threads an agent started with delegate_task, which T3 does not mark as subagents. */
|
||||||
|
delegatedFrom?: { environmentId: string; threadId: string; title: string };
|
||||||
settledOverride?: Open<"settled"> | null;
|
settledOverride?: Open<"settled"> | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,4 +95,12 @@ describe("threadPhase", () => {
|
|||||||
it("hides threads that never ran", () => {
|
it("hides threads that never ran", () => {
|
||||||
expect(threadPhase(thread({ status: "idle" }))).toBeNull();
|
expect(threadPhase(thread({ status: "idle" }))).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Not from upstream: delegate_task children carry no subagent lineage, only delegatedFrom.
|
||||||
|
it("shows delegated threads only while they wait on the user", () => {
|
||||||
|
const delegatedFrom = { environmentId: "env-desktop", threadId: "thread-1", title: "Parent" };
|
||||||
|
expect(threadPhase(thread({ delegatedFrom }))).toBeNull();
|
||||||
|
expect(threadPhase(thread({ delegatedFrom, status: "completed" }))).toBeNull();
|
||||||
|
expect(threadPhase(thread({ delegatedFrom, pendingRuntimeRequest: request("command") }))).toBe("waiting_for_approval");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user