Skip to content

Commit ce40de2

Browse files
committed
Revert delivery guard fold to avoid sibling branch collision
Revert 974e96d: sibling cl-7949-tui-micro-inlines renames queued-delivery.ts, so this branch keeps deliver-agent-message.ts separate to merge cleanly.
1 parent 5195bb1 commit ce40de2

9 files changed

Lines changed: 104 additions & 101 deletions

‎src/tui/deliver-agent-message.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AgentClosedError } from "@intx/agent";
33
import {
44
deliverAgentMessage,
55
deliveryResultNotice,
6-
} from "./queued-delivery.js";
6+
} from "./deliver-agent-message.js";
77

88
describe("deliverAgentMessage", () => {
99
test("reports session-unavailable without calling deliver when rebuild failed", async () => {

‎src/tui/deliver-agent-message.ts‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* Guards a queued/steer deliver against a mid-rebuild or closed agent. The shell
3+
* paints the delivered row and pops the queue item before this runs, so the
4+
* caller must settle ownership from the structured result — a swallowed failure
5+
* here means the transcript claims delivery for a message that never reached
6+
* the agent.
7+
*/
8+
import { AgentClosedError } from "@intx/agent";
9+
10+
export type AgentDeliveryNotDeliveredReason =
11+
| "agent-closed"
12+
| "session-unavailable"
13+
| "superseded"
14+
| "preparation-failed";
15+
16+
export type AgentDeliveryResult =
17+
| { readonly status: "accepted" }
18+
| {
19+
readonly status: "not-delivered";
20+
readonly reason: AgentDeliveryNotDeliveredReason;
21+
readonly detail: string;
22+
}
23+
| {
24+
readonly status: "uncertain";
25+
readonly detail: string;
26+
};
27+
28+
export interface DeliverAgentMessageDeps {
29+
getFatalBuildError: () => Error | null;
30+
deliverToLiveAgent: () => void;
31+
}
32+
33+
export async function deliverAgentMessage(
34+
deps: DeliverAgentMessageDeps,
35+
): Promise<AgentDeliveryResult> {
36+
const fatal = deps.getFatalBuildError();
37+
if (fatal !== null) {
38+
return {
39+
status: "not-delivered",
40+
reason: "session-unavailable",
41+
detail: fatal.message,
42+
};
43+
}
44+
try {
45+
deps.deliverToLiveAgent();
46+
return { status: "accepted" };
47+
} catch (err) {
48+
if (err instanceof AgentClosedError) {
49+
return {
50+
status: "not-delivered",
51+
reason: "agent-closed",
52+
detail: err.message,
53+
};
54+
}
55+
return {
56+
status: "uncertain",
57+
detail: err instanceof Error ? err.message : String(err),
58+
};
59+
}
60+
}
61+
62+
/** Operator-facing copy for a settled delivery that did not accept. */
63+
export function deliveryResultNotice(
64+
result: Exclude<AgentDeliveryResult, { status: "accepted" }>,
65+
disposition: "restored" | "deferred" | "none" = "none",
66+
): string {
67+
if (result.status === "uncertain") {
68+
const base = `Delivery failed: ${result.detail}. Delivery status is uncertain; review the transcript before sending again.`;
69+
return appendDisposition(base, disposition);
70+
}
71+
if (result.reason === "agent-closed") {
72+
if (disposition === "restored") {
73+
return "Message not delivered because the agent closed. It is back in the prompt; press Enter to send it.";
74+
}
75+
if (disposition === "deferred") {
76+
return "Message not delivered because the agent closed. Your current draft is unchanged; the message will return to the prompt after you send it.";
77+
}
78+
return "Message not delivered because the agent closed.";
79+
}
80+
const base = `Message not delivered: ${result.detail}`;
81+
return appendDisposition(base, disposition);
82+
}
83+
84+
function appendDisposition(
85+
base: string,
86+
disposition: "restored" | "deferred" | "none",
87+
): string {
88+
if (disposition === "restored") {
89+
return `${base} It is back in the prompt; press Enter to send it.`;
90+
}
91+
if (disposition === "deferred") {
92+
return `${base} Your current draft is unchanged; the message will return to the prompt after you send it.`;
93+
}
94+
return base;
95+
}

‎src/tui/queued-delivery-hop.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
} from "./queued-delivery.js";
1515
import { createSessionOperationQueue } from "./session-operation-queue.js";
1616
import { badgeCount, type QueueItem } from "./session-queue";
17-
import type { AgentDeliveryResult } from "./queued-delivery.js";
17+
import type { AgentDeliveryResult } from "./deliver-agent-message.js";
1818

1919
function lastHopPort(bridgeRef: { current: SessionBridge | undefined }) {
2020
const sends: string[] = [];

‎src/tui/queued-delivery.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {
77
createLiveSteerDeliver,
88
routeQueuedDelivery,
99
SESSION_IDENTITY_ABORT_REASON,
10-
type AgentDeliveryResult,
1110
} from "./queued-delivery.js";
1211
import { createSessionOperationQueue } from "./session-operation-queue.js";
12+
import type { AgentDeliveryResult } from "./deliver-agent-message.js";
1313

1414
const image: PendingImageAttachment = {
1515
id: "img-1",

‎src/tui/queued-delivery.ts‎

Lines changed: 1 addition & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -7,104 +7,12 @@
77
* parent tool.boundary. Leftover steers at idle, idle-with-fleet, or
88
* post-interrupt share the send path (sendQueue, inFlight, token refresh).
99
*/
10-
import { AgentClosedError } from "@intx/agent";
1110
import type { PendingImageAttachment } from "./image-attachments.js";
11+
import type { AgentDeliveryResult } from "./deliver-agent-message.js";
1212
import type { ProductHostDeliver } from "./product-host.js";
1313
import { ASK_DIRECTOR_WAKE_PREFIX } from "../subagent/fleet-report.js";
1414
import { MAILBOX_MAIL_WAKE_PREFIX } from "../subagent/mailbox-mail-drive.js";
1515

16-
export type AgentDeliveryNotDeliveredReason =
17-
| "agent-closed"
18-
| "session-unavailable"
19-
| "superseded"
20-
| "preparation-failed";
21-
22-
export type AgentDeliveryResult =
23-
| { readonly status: "accepted" }
24-
| {
25-
readonly status: "not-delivered";
26-
readonly reason: AgentDeliveryNotDeliveredReason;
27-
readonly detail: string;
28-
}
29-
| {
30-
readonly status: "uncertain";
31-
readonly detail: string;
32-
};
33-
34-
export interface DeliverAgentMessageDeps {
35-
getFatalBuildError: () => Error | null;
36-
deliverToLiveAgent: () => void;
37-
}
38-
39-
/**
40-
* Guards a queued/steer deliver against a mid-rebuild or closed agent. The
41-
* shell paints the delivered row and pops the queue item before this runs, so
42-
* the caller must settle ownership from the structured result.
43-
*/
44-
export async function deliverAgentMessage(
45-
deps: DeliverAgentMessageDeps,
46-
): Promise<AgentDeliveryResult> {
47-
const fatal = deps.getFatalBuildError();
48-
if (fatal !== null) {
49-
return {
50-
status: "not-delivered",
51-
reason: "session-unavailable",
52-
detail: fatal.message,
53-
};
54-
}
55-
try {
56-
deps.deliverToLiveAgent();
57-
return { status: "accepted" };
58-
} catch (err) {
59-
if (err instanceof AgentClosedError) {
60-
return {
61-
status: "not-delivered",
62-
reason: "agent-closed",
63-
detail: err.message,
64-
};
65-
}
66-
return {
67-
status: "uncertain",
68-
detail: err instanceof Error ? err.message : String(err),
69-
};
70-
}
71-
}
72-
73-
/** Operator-facing copy for a settled delivery that did not accept. */
74-
export function deliveryResultNotice(
75-
result: Exclude<AgentDeliveryResult, { status: "accepted" }>,
76-
disposition: "restored" | "deferred" | "none" = "none",
77-
): string {
78-
if (result.status === "uncertain") {
79-
const base = `Delivery failed: ${result.detail}. Delivery status is uncertain; review the transcript before sending again.`;
80-
return appendDisposition(base, disposition);
81-
}
82-
if (result.reason === "agent-closed") {
83-
if (disposition === "restored") {
84-
return "Message not delivered because the agent closed. It is back in the prompt; press Enter to send it.";
85-
}
86-
if (disposition === "deferred") {
87-
return "Message not delivered because the agent closed. Your current draft is unchanged; the message will return to the prompt after you send it.";
88-
}
89-
return "Message not delivered because the agent closed.";
90-
}
91-
const base = `Message not delivered: ${result.detail}`;
92-
return appendDisposition(base, disposition);
93-
}
94-
95-
function appendDisposition(
96-
base: string,
97-
disposition: "restored" | "deferred" | "none",
98-
): string {
99-
if (disposition === "restored") {
100-
return `${base} It is back in the prompt; press Enter to send it.`;
101-
}
102-
if (disposition === "deferred") {
103-
return `${base} Your current draft is unchanged; the message will return to the prompt after you send it.`;
104-
}
105-
return base;
106-
}
107-
10816
export type DeliverySettle = (result: AgentDeliveryResult) => void;
10917
type MaybeAsyncDeliveryResult =
11018
| Promise<AgentDeliveryResult>

‎src/tui/runner/session.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ import {
9494
deliverAgentMessage,
9595
deliveryResultNotice,
9696
type AgentDeliveryResult,
97-
} from "../queued-delivery.js";
97+
} from "../deliver-agent-message.js";
9898
import { createProviderFailureAttemptTracker } from "../provider/failure-attempt.js";
9999
import { getTelemetry, liveTelemetry } from "../../telemetry/singleton.js";
100100
import {

‎src/tui/runner/state.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import type { ProviderFailureAttempt } from "../provider/failure-attempt.js";
3232
import type { ScopedApproval } from "../../permission/admin.js";
3333
import type { ConnectedMcpServer, RunState } from "../../session/state.js";
3434
import type { PendingImageAttachment } from "../image-attachments.js";
35-
import type { AgentDeliveryResult } from "../queued-delivery.js";
35+
import type { AgentDeliveryResult } from "../deliver-agent-message.js";
3636
import type { SubmitOutcome } from "./submit.js";
3737
import type { mountRunnerHost } from "./host.js";
3838
import { EventEmitter } from "node:events";

‎src/tui/runner/submit.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ import {
3535
createLeftoverSend,
3636
createLiveSteerDeliver,
3737
routeQueuedDelivery,
38-
type AgentDeliveryResult,
3938
} from "../queued-delivery.js";
39+
import type { AgentDeliveryResult } from "../deliver-agent-message.js";
4040
import type { InferenceAttemptIdentity } from "./state.js";
4141
import { tuiSendFailureMessage } from "./send-failure-message.js";
4242
import type { ProviderFailureAttempt } from "../provider/failure-attempt.js";

‎src/tui/runtime-bridge.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ import {
7171
import {
7272
deliveryResultNotice,
7373
type AgentDeliveryResult,
74-
type DeliverySettle,
75-
} from "./queued-delivery.js";
74+
} from "./deliver-agent-message.js";
75+
import type { DeliverySettle } from "./queued-delivery.js";
7676
import { toolCallRow } from "./diff.js";
7777
import { toolResultRow } from "./mcp-view.js";
7878
import {

0 commit comments

Comments
 (0)