History

fix opencing in browser

Rhys Sullivan committed 8 months ago

Commit e7159681 parent f93d2873 files · +93 −14Browse files

Unified · Split

3 files
  1. apps/executor/src/cli/interaction-handling.test.ts +37 −0
  2. apps/executor/src/cli/interaction-handling.ts +18 −0
  3. apps/executor/src/cli/main.ts +38 −14
apps/executor/src/cli/interaction-handling.test.ts+37−0
@@ -0,0 +1,37 @@
1import { describe, expect, it } from "@effect/vitest";
2
3import { decideInteractionHandling } from "./interaction-handling";
4
5describe("interaction-handling", () => {
6 it("keeps URL interactions distinct when the terminal is non-interactive", () => {
7 expect(decideInteractionHandling({
8 parsed: {
9 mode: "url",
10 message: "Connect Axiom",
11 url: "https://mcp.axiom.co/authorize",
12 },
13 isInteractiveTerminal: false,
14 })).toBe("url_paused");
15 });
16
17 it("waits on URL interactions in an interactive terminal", () => {
18 expect(decideInteractionHandling({
19 parsed: {
20 mode: "url",
21 message: "Connect Axiom",
22 url: "https://mcp.axiom.co/authorize",
23 },
24 isInteractiveTerminal: true,
25 })).toBe("url_interactive");
26 });
27
28 it("falls back to form pause handling for non-interactive prompts", () => {
29 expect(decideInteractionHandling({
30 parsed: {
31 mode: "form",
32 message: "Approve tool call",
33 },
34 isInteractiveTerminal: false,
35 })).toBe("form_paused");
36 });
37});
apps/executor/src/cli/interaction-handling.ts+18−0
@@ -0,0 +1,18 @@
1import type { ParsedInteractionPayload } from "./pending-interaction-output";
2
3export type InteractionHandling =
4 | "url_interactive"
5 | "url_paused"
6 | "form_interactive"
7 | "form_paused";
8
9export const decideInteractionHandling = (input: {
10 parsed: ParsedInteractionPayload | null;
11 isInteractiveTerminal: boolean;
12}): InteractionHandling => {
13 if (input.parsed?.mode === "url") {
14 return input.isInteractiveTerminal ? "url_interactive" : "url_paused";
15 }
16
17 return input.isInteractiveTerminal ? "form_interactive" : "form_paused";
18};
apps/executor/src/cli/main.ts+38−14
@@ -52,6 +52,7 @@ import { · 51 unmodified lines
52 buildPausedExecutionOutput,52 buildPausedExecutionOutput,
53 parseInteractionPayload,53 parseInteractionPayload,
54} from "./pending-interaction-output";54} from "./pending-interaction-output";
55import { decideInteractionHandling } from "./interaction-handling";
55 56
56const toError = (cause: unknown): Error =>57const toError = (cause: unknown): Error =>
57 cause instanceof Error ? cause : new Error(String(cause));58 cause instanceof Error ? cause : new Error(String(cause));
@@ -1020,8 +1021,32 @@ const driveExecution = (input: { · 962 unmodified lines
1020 }1021 }
1021 1022
1022 const parsed = parseInteractionPayload(pending);1023 const parsed = parseInteractionPayload(pending);
1023 const isInteractiveTerminal = process.stdin.isTTY && process.stdout.isTTY;1024 const handling = decideInteractionHandling({
1024 if (!isInteractiveTerminal) {1025 parsed,
1026 isInteractiveTerminal: process.stdin.isTTY && process.stdout.isTTY,
1027 });
1028
1029 if (handling === "url_interactive" && parsed?.mode === "url") {
1030 yield* printUrlInteraction({
1031 message: parsed.message,
1032 url: parsed.url ?? null,
1033 shouldOpen: input.shouldOpenUrls,
1034 });
1035
1036 current = yield* waitForExecutionProgress({
1037 client: input.client,
1038 workspaceId: input.workspaceId,
1039 executionId: current.execution.id,
1040 pendingInteractionId: pending.id,
1041 });
1042 continue;
1043 }
1044
1045 if (handling === "url_paused") {
1046 if (input.shouldOpenUrls && parsed?.mode === "url" && parsed.url) {
1047 yield* openUrlInBrowser(parsed.url);
1048 }
1049
1025 const paused = buildPausedExecutionOutput({1050 const paused = buildPausedExecutionOutput({
1026 executionId: current.execution.id,1051 executionId: current.execution.id,
1027 interaction: pending,1052 interaction: pending,
@@ -1036,20 +1061,19 @@ const driveExecution = (input: { · 8 unmodified lines
1036 return current;1061 return current;
1037 }1062 }
1038 1063
1039 if (parsed?.mode === "url") {1064 if (handling === "form_paused") {
1040 yield* printUrlInteraction({1065 const paused = buildPausedExecutionOutput({
1041 message: parsed.message,
1042 url: parsed.url ?? null,
1043 shouldOpen: input.shouldOpenUrls,
1044 });
1045
1046 current = yield* waitForExecutionProgress({
1047 client: input.client,
1048 workspaceId: input.workspaceId,
1049 executionId: current.execution.id,1066 executionId: current.execution.id,
1050 pendingInteractionId: pending.id,1067 interaction: pending,
1068 baseUrl: input.baseUrl,
1069 shouldOpenUrls: input.shouldOpenUrls,
1070 cliName: CLI_NAME,
1051 });1071 });
1052 continue;1072 yield* Effect.sync(() => {
1073 console.log(JSON.stringify(paused));
1074 process.exitCode = 20;
1075 });
1076 return current;
1053 }1077 }
1054 1078
1055 const responseJson = yield* promptInteraction({1079 const responseJson = yield* promptInteraction({